aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2025-07-04 09:24:48 -0400
committerFlorian Fischer <florian.fischer@muhq.space>2025-08-20 15:57:23 +0200
commit9dcbe08bc2fddb736891849aabc3d748f1426e01 (patch)
tree59cd4597d364884d0117ab5956206461d40af827
parente4ec9266c205120a51dc8d5c4ac956f2b8792f1b (diff)
downloadmuhqs-game-9dcbe08bc2fddb736891849aabc3d748f1426e01.tar.gz
muhqs-game-9dcbe08bc2fddb736891849aabc3d748f1426e01.zip
add initial support for marshaling actions to plain text
-rw-r--r--go/game/action.go61
-rw-r--r--go/game/action_test.go64
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())
+ }
+}