diff options
Diffstat (limited to 'go/game/cardParsing.go')
| -rw-r--r-- | go/game/cardParsing.go | 140 |
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") + } +} |
