diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2025-07-04 09:24:48 -0400 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2025-08-20 15:57:23 +0200 |
| commit | 9dcbe08bc2fddb736891849aabc3d748f1426e01 (patch) | |
| tree | 59cd4597d364884d0117ab5956206461d40af827 | |
| parent | e4ec9266c205120a51dc8d5c4ac956f2b8792f1b (diff) | |
| download | muhqs-game-9dcbe08bc2fddb736891849aabc3d748f1426e01.tar.gz muhqs-game-9dcbe08bc2fddb736891849aabc3d748f1426e01.zip | |
add initial support for marshaling actions to plain text
| -rw-r--r-- | go/game/action.go | 61 | ||||
| -rw-r--r-- | go/game/action_test.go | 64 |
2 files changed, 125 insertions, 0 deletions
diff --git a/go/game/action.go b/go/game/action.go index 373c814f..1d34a843 100644 --- a/go/game/action.go +++ b/go/game/action.go @@ -1,8 +1,11 @@ package game import ( + "errors" "fmt" "log" + "regexp" + "strings" ) type ActionSpeed int @@ -713,3 +716,61 @@ func UseAttackAction(a Action) { a.costFunc = genAttackActionCost(a.Source().(*Unit)) } } + +// Marshal an action to plain text. +// The format of the action is `SOURCE ACTION CONTEXT`. +// PassPriority: PLAYER pass +// DraftPick: PLAYER pick CARD:PACK +func MarshalAction(_a Action) []byte { + out := []byte{} + switch a := _a.(type) { + case *PassPriority: + out = fmt.Appendf(out, "%s\u00A0pass", a.player.Name) + case *DraftPick: + out = fmt.Appendf(out, "%s\u00A0pick\u00A0%s:%s", a.player.Name, a.pick.Path(), a.pack) + default: + log.Fatalf("MarshalAction(%s) not implemented\n", a) + } + return out +} + +var ( + InvalidActionFormat = errors.New("Invalid Action Format") +) + +var ActionRegex = regexp.MustCompile(`^([^\xA0]*)\xA0([^\xA0]*)\xA0?(.*)?$`) + +func UnmarshalAction(s State, in []byte) (a Action, err error) { + m := ActionRegex.FindSubmatch(in) + if len(m) < 2 || len(m) > 4 { + log.Println(m) + return nil, InvalidActionFormat + } + _action := string(m[2]) + if _action == "pick" { + p := s.PlayerByName(string(m[1])) + if p == nil { + err = errors.New("Unknown player") + return + } + _p := strings.Split(string(m[3]), ":") + pick, err := NewCardSafe(_p[0]) + if err != nil { + return nil, err + } + pack := NewPileOfCards() + err = pack.FromString(_p[1]) + if err != nil { + return nil, err + } + a = NewDraftPick(p, pack, pick) + } else if _action == "pass" { + p := s.PlayerByName(string(m[1])) + if p == nil { + err = errors.New("Unknown player") + return + } + a = NewPassPriority(p) + } + return +} diff --git a/go/game/action_test.go b/go/game/action_test.go new file mode 100644 index 00000000..b1642bd1 --- /dev/null +++ b/go/game/action_test.go @@ -0,0 +1,64 @@ +package game + +import ( + "testing" +) + +const PASS_STRING = "muhq\u00A0pass" + +var s *LocalState = NewLocalState() +var p *Player = s.AddNewPlayer("muhq", NewDeck(), nil) + +func TestMarshalPass(t *testing.T) { + exp := PASS_STRING + a := NewPassPriority(p) + is := string(MarshalAction(a)) + if is != exp { + t.Fatalf("expected string %s does not match %s\n", exp, is) + } +} + +func TestUnmarshalPass(t *testing.T) { + in := PASS_STRING + a, err := UnmarshalAction(s, []byte(in)) + if err != nil { + t.Fatal(err) + } + if _, ok := a.(*PassPriority); !ok { + t.Fatalf("expexted PassPriority not %s", a) + } +} + +const PICK_ACTION_STRING = "muhq\u00A0pick\u00A0base/archer:[base/archer, magic/more!]" + +func TestMarshalPickAction(t *testing.T) { + exp := PICK_ACTION_STRING + poc := NewPileOfCards() + c := NewCard("base/archer") + poc.AddCard(c) + poc.AddCard(NewCard("magic/more!")) + a := NewDraftPick(p, poc, c) + is := string(MarshalAction(a)) + if is != exp { + t.Fatalf("expected string %s does not match %s\n", exp, is) + } +} + +func TestUnmarshalPickAction(t *testing.T) { + in := PICK_ACTION_STRING + a, err := UnmarshalAction(s, []byte(in)) + if err != nil { + t.Fatal(err) + } + var p *DraftPick + var ok bool + if p, ok = a.(*DraftPick); !ok { + t.Fatalf("expexted DraftPick not %v", a) + } + if len(p.pack.Cards()) != 2 { + t.Fatalf("expexted two cards in pack not %d", len(p.pack.Cards())) + } + if p.pick.Name != "Archer" { + t.Fatalf("expexted archer beeing picked not %s", p.pick.Path()) + } +} |
