From d76117cc913c738002c7562189ada75748645ff1 Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Tue, 31 Jan 2023 00:16:53 +0100 Subject: intermediate commit --- go/game/card.go | 157 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 116 insertions(+), 41 deletions(-) (limited to 'go/game/card.go') diff --git a/go/game/card.go b/go/game/card.go index 07ef033b..d4515676 100644 --- a/go/game/card.go +++ b/go/game/card.go @@ -1,6 +1,7 @@ package game import ( + "fmt" "io" "log" "net/http" @@ -15,30 +16,30 @@ import ( type CardType int const ( - UndefinedCardType CardType = iota - UnitType - SpellType - ArtifactType - EquipmentType - PotionType - IntentionType + undefinedCardType CardType = iota + unitType + spellType + artifactType + equipmentType + potionType + intentionType ) func (ct CardType) String() string { switch ct { - case UndefinedCardType: + case undefinedCardType: return "undefined" - case UnitType: + case unitType: return "unit" - case SpellType: + case spellType: return "spell" - case ArtifactType: + case artifactType: return "artifact" - case EquipmentType: + case equipmentType: return "equipment" - case PotionType: + case potionType: return "potion" - case IntentionType: + case intentionType: return "intention" } log.Panicf("Switch not exhausting %d", ct) @@ -53,26 +54,63 @@ var CardTypes = struct { Potion CardType Intention CardType }{ - Unit: UnitType, - Spell: SpellType, - Artifact: ArtifactType, - Equipment: EquipmentType, - Potion: PotionType, - Intention: IntentionType, + Unit: unitType, + Spell: spellType, + Artifact: artifactType, + Equipment: equipmentType, + Potion: potionType, + Intention: intentionType, } var CardTypeNames = map[string]CardType{ - "unit": UnitType, - "spell": SpellType, - "artifact": ArtifactType, - "equipment": EquipmentType, - "potion": PotionType, - "intention": IntentionType, + "unit": unitType, + "spell": spellType, + "artifact": artifactType, + "equipment": equipmentType, + "potion": potionType, + "intention": intentionType, +} + +type cardImplementation interface { + spawnTiles(*State, *Player) []*Tile + fullActionPrototypes(*Unit) []*FullActionPrototype + freeActionPrototypes(Permanent) []*FreeActionPrototype +} + +// Default implementation of the cardImplementation interface. +// +// Card Implementations should embed this struct to "inherit" the +// default behavior. +type cardImplementationBase struct{} + +func (impl *cardImplementationBase) spawnTiles(*State, *Player) []*Tile { + return nil +} + +func (impl *cardImplementationBase) fullActionPrototypes(*Unit) []*FullActionPrototype { + return nil +} + +func (impl *cardImplementationBase) freeActionPrototypes(Permanent) []*FreeActionPrototype { + return nil +} + +// Map of all card implementations +var cardImplementations map[string]cardImplementation + +func getCardImplementation(c *Card) cardImplementation { + if impl, found := cardImplementations[c.Path()]; found { + return impl + } + + impl := newParsedCardImplementation(c) + cardImplementations[c.Path()] = impl + return impl } const ( CARD_DATA_URL string = "data/cards" - NOT_BUYABLE int = -1 + NOT_BUYABLE int = -1 // Maybe this needs to be changed some day to allow more design space ) type Card struct { @@ -81,9 +119,22 @@ type Card struct { Type CardType BuyCost int Values map[string]interface{} + Impl cardImplementation } -var cards = map[string]map[string][]byte{} +var cardDefinitions = map[string]map[string][]byte{} + +func getCardDefinition(set, cardName string) []byte { + cardDefinition, found := cardDefinitions[set][cardName] + if !found { + cardDefinition = retrieveCardDefinition(path.Join(set, cardName)) + if cardDefinitions[set] == nil { + cardDefinitions[set] = map[string][]byte{} + } + cardDefinitions[set][cardName] = cardDefinition + } + return cardDefinition +} func retrieveCardDefinition(cardPath string) []byte { url := PROTOCOL + path.Join(BASE_URL, CARD_DATA_URL, cardPath+".yml") @@ -135,12 +186,16 @@ func (card *Card) parseDefinition(definition []byte) { bc, found := data["buy"] if found { card.BuyCost = bc.(int) + } else { + card.BuyCost = NOT_BUYABLE } delete(data, "buy") for k, v := range data { card.Values[k.(string)] = v } + + card.Impl = getCardImplementation(card) } func (card *Card) getCanonicalValues(key string) []string { @@ -187,9 +242,23 @@ func (card *Card) hasEffect(effect string) bool { return slices.Contains(card.getEffects(), effect) } -func (card *Card) hasMovementEffect(effect string) bool { +func (card *Card) getXEffect(effect string) (int, error) { + for _, e := range card.getEffects() { + if !strings.Contains(e, effect) { + continue + } + + tokens := strings.SplitN(e, " ", 2) + return strconv.Atoi(tokens[1]) + } + return 0, fmt.Errorf("Crad %s has no effect %s", card.Name, effect) +} + +func (card *Card) hasPlacementConstrain(effect string) bool { if slices.Contains(card.getEffects(), effect) { return true + } else if card.Type != CardTypes.Unit { + return false } movementDesc := card.getCanonicalValues("movement")[0] @@ -208,16 +277,15 @@ func NewCard(cardPath string) *Card { cardName := path.Base(cardPath) set := path.Dir(cardPath) - cardDefinition, found := cards[set][cardName] - if !found { - cardDefinition = retrieveCardDefinition(cardPath) - if cards[set] == nil { - cards[set] = map[string][]byte{} - } - cards[set][cardName] = cardDefinition - } + cardDefinition := getCardDefinition(set, cardName) - c := Card{"", SetIdentifierNames[set], UndefinedCardType, -1, map[string]interface{}{}} + c := Card{ + Name: "", + Set: SetIdentifierNames[set], + Type: undefinedCardType, + BuyCost: NOT_BUYABLE, + Values: map[string]interface{}{}, + } c.parseDefinition(cardDefinition) return &c } @@ -228,12 +296,19 @@ func (c *Card) Path() string { } func (c *Card) IsPermanent() bool { - return c.Type != UndefinedCardType && c.Type != SpellType && c.Type != IntentionType + return c.Type == CardTypes.Unit || + c.Type != CardTypes.Artifact || + c.Type != CardTypes.Equipment || + c.Type != CardTypes.Potion +} + +func (c *Card) IsBuyable() bool { + return c.BuyCost != NOT_BUYABLE } -func (c *Card) GetPlayCosts() int { +func (c *Card) PlayCosts() int { switch c.Type { - case UnitType: + case CardTypes.Unit: return c.Values["upkeep"].(int) default: return c.Values["play"].(int) -- cgit v1.2.3