package game import ( "io" "log" "net/http" "path" "gopkg.in/yaml.v3" ) type CardType int const ( UndefinedCardType CardType = iota UnitType SpellType ArtifactType EquipmentType PotionType ItentionType ) func (ct CardType) String() string { switch ct { case UndefinedCardType: return "undefined" case UnitType: return "unit" case SpellType: return "spell" case ArtifactType: return "artifact" case EquipmentType: return "equipment" case PotionType: return "potion" case ItentionType: return "itention" } log.Panicf("Switch not exhausting %d", ct) return "" } var CardTypes = struct { Unit CardType Spell CardType Artifact CardType Equipment CardType Potion CardType Itention CardType }{ Unit: UnitType, Spell: SpellType, Artifact: ArtifactType, Equipment: EquipmentType, Potion: PotionType, Itention: ItentionType, } var CardTypeNames = map[string]CardType{ "unit": UnitType, "spell": SpellType, "artifact": ArtifactType, "equipment": EquipmentType, "potion": PotionType, "itention": ItentionType, } const ( CARD_DATA_URL string = "data/cards" ) type Card struct { Name string Set SetIdentifier Type CardType Values map[string]interface{} } var cards = map[string]map[string][]byte{} func retrieveCardDefinition(cardPath string) []byte { url := PROTOCOL + path.Join(BASE_URL, CARD_DATA_URL, cardPath+".yml") log.Printf("loading %s\n", url) resp, err := http.Get(url) if err != nil { log.Fatal(err) } defer resp.Body.Close() data, err := io.ReadAll(resp.Body) if err != nil { log.Fatal(err) } return data } func (card *Card) parseDefinition(definition []byte) { data := make(map[interface{}]interface{}) err := yaml.Unmarshal(definition, &data) if err != nil { log.Fatalf("parsing %s failed with: %v\n", definition, err) } name, ok := data["name"] if !ok { log.Fatalf("no name in card yaml %s\n", definition) } delete(data, "name") switch nameYml := name.(type) { case string: card.Name = nameYml case map[string]interface{}: cardName := nameYml["en"] card.Name = cardName.(string) default: log.Fatalf("Unexpected type %T of yml card field 'Name'\n", name) } t, ok := data["type"] if !ok { log.Fatalf("no type in card yaml %s\n", definition) } delete(data, "type") card.Type = CardTypeNames[t.(string)] for k, v := range data { card.Values[k.(string)] = v } } func (card *Card) getEffects() []string { effects, found := card.Values["effect"] if !found { return []string{} } if effect, ok := effects.(string); ok { return []string{effect} } if effectsMap, ok := effects.(map[string]interface{}); ok { enEffects := effectsMap["en"] if effect, ok := enEffects.(string); ok { return []string{effect} } return enEffects.([]string) } return effects.([]string) } 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 } c := Card{"", SetIdentifierNames[set], UndefinedCardType, map[string]interface{}{}} c.parseDefinition(cardDefinition) return &c }