aboutsummaryrefslogtreecommitdiff
path: root/go/game/cardParsing.go
diff options
context:
space:
mode:
Diffstat (limited to 'go/game/cardParsing.go')
-rw-r--r--go/game/cardParsing.go140
1 files changed, 140 insertions, 0 deletions
diff --git a/go/game/cardParsing.go b/go/game/cardParsing.go
new file mode 100644
index 00000000..af8e1560
--- /dev/null
+++ b/go/game/cardParsing.go
@@ -0,0 +1,140 @@
+package game
+
+import (
+ "log"
+ "strconv"
+ "strings"
+)
+
+type parsedCardImplementation struct {
+ card *Card
+ spawnTilesFunc func(*State, *Player) []*Tile
+ genFullActionPrototypes func(*Unit) []*FullActionPrototype
+ genFreeActionPrototypes func(Permanent) []*FreeActionPrototype
+}
+
+func (impl *parsedCardImplementation) spawnTiles(s *State, p *Player) []*Tile {
+ if impl.spawnTilesFunc != nil {
+ return impl.spawnTilesFunc(s, p)
+ }
+ return nil
+}
+
+func (impl *parsedCardImplementation) fullActionPrototypes(u *Unit) []*FullActionPrototype {
+ if impl.genFullActionPrototypes != nil {
+ return impl.genFullActionPrototypes(u)
+ }
+ return nil
+}
+
+func (impl *parsedCardImplementation) freeActionPrototypes(p Permanent) []*FreeActionPrototype {
+ if impl.genFreeActionPrototypes != nil {
+ return impl.genFreeActionPrototypes(p)
+ }
+ return nil
+}
+
+func newParsedCardImplementation(c *Card) *parsedCardImplementation {
+ impl := &parsedCardImplementation{card: c}
+ for _, effect := range c.getEffects() {
+ impl.parseEffect(effect)
+ }
+ return impl
+}
+
+func (impl *parsedCardImplementation) parseEffect(effect string) {
+ if strings.Contains(effect, "can be played") {
+ impl.parsePlayModification(effect)
+ }
+}
+
+func parseUnitConstrain(constrain string) func(ctx interface{}, u *Unit) bool {
+ enemy := strings.Contains(constrain, "enemy")
+ if enemy {
+ return func(ctx interface{}, e *Unit) bool {
+ p := ctx.(*Player)
+ return p.IsEnemy(e.Controller())
+ }
+ } else {
+ log.Println("Only enemy unit constrains are implemented yet")
+ }
+
+ return nil
+}
+
+func parseLocation(location string) func(interface{}, *State) []*Tile {
+ r := -1
+ var what string
+ if strings.Contains(location, "on") {
+ r = 0
+ tokens := strings.SplitN(location, "on ", 2)
+ what = tokens[1]
+
+ } else if strings.Contains(location, "next to") {
+ r = 1
+ tokens := strings.SplitN(location, "next to ", 2)
+ what = tokens[1]
+
+ } else if strings.Contains(location, "in range") {
+ tokens := strings.SplitN(location, "in range ", 2)
+ afterRangePattern := tokens[1]
+
+ var rangeStr string
+ tokens = strings.SplitN(afterRangePattern, " ", 2)
+ rangeStr, what = tokens[0], tokens[1]
+
+ var err error
+ r, err = strconv.Atoi(rangeStr)
+ if err != nil {
+ log.Fatalf("Unsupported range pattern \"%s\" in \"%s\"", "range "+rangeStr, location)
+ }
+ }
+
+ if r == -1 || what == "" {
+ return nil
+ }
+
+ if strings.Contains(what, "unit") {
+ constrainFunc := parseUnitConstrain(what)
+ if constrainFunc != nil {
+ return func(ctx interface{}, s *State) []*Tile {
+ origins := s.Map.FilterTiles(func(t *Tile) bool {
+ if t.Permanent != nil &&
+ t.Permanent.Card().Type == CardTypes.Unit &&
+ constrainFunc(ctx, t.Permanent.(*Unit)) {
+ return true
+ }
+ return false
+ })
+
+ if r == 0 {
+ return origins
+ } else {
+ tiles := []*Tile{}
+ for _, origin := range origins {
+ tiles = append(tiles, TilesInRangeFromOrigin(s.Map, origin.Position, r)...)
+ }
+ return tiles
+ }
+ }
+ }
+ }
+ log.Println("Only unit location constrains are implemented yet")
+ return nil
+}
+
+func (impl *parsedCardImplementation) parsePlayModification(effect string) {
+ tokens := strings.SplitN(effect, " can be played ", 2)
+ log.Println(tokens)
+ what, how := tokens[0], tokens[1]
+ if what == strings.ToLower(impl.card.Name) {
+ if locationFunc := parseLocation(how); locationFunc != nil {
+ impl.spawnTilesFunc = func(p *State, s *Player) []*Tile { return locationFunc(s, p) }
+ } else {
+ log.Println("Play modification other than locations are not implemented ")
+ }
+ } else {
+ log.Println(effect)
+ log.Println("Play modification for other cards are not implemented")
+ }
+}