package game import "fmt" // Suit is the trade-in symbol printed on pet cards. Three pets of the same // suit can be traded for a pick of the next tier's deck. type Suit string const ( SuitSun Suit = "sun" SuitMoon Suit = "moon" SuitStar Suit = "star" SuitLeaf Suit = "leaf" ) var suits = []Suit{SuitSun, SuitMoon, SuitStar, SuitLeaf} // CardKind distinguishes pets from foods. type CardKind string const ( KindPet CardKind = "pet" KindFood CardKind = "food" ) // Food identifiers. Only apples exist for now; more foods come later. const FoodApple = "apple" // Card is a single physical card instance. IDs are unique per game. type Card struct { ID string `json:"id"` Kind CardKind `json:"kind"` Name string `json:"name"` Tier int `json:"tier"` Power int `json:"power,omitempty"` Suit Suit `json:"suit,omitempty"` // Effect is display text for the pet's ability. Effects are not yet // implemented mechanically; the field keeps card data forward-compatible. Effect string `json:"effect,omitempty"` Food string `json:"food,omitempty"` } func (c Card) IsPet() bool { return c.Kind == KindPet } func (c Card) IsFood() bool { return c.Kind == KindFood } // petTemplate is the printed definition of a pet; each template appears as // multiple card copies in its tier's shop deck. type petTemplate struct { Name string Power int } const copiesPerPet = 2 // petTiers defines the shop decks. Index 0 is tier 1 (round 1) through // index 5 for tier 6 (round 6). Suits are assigned round-robin per tier so // every tier contains every suit. var petTiers = [MaxRounds][]petTemplate{ { // Tier 1 {"Ant", 1}, {"Cricket", 1}, {"Fish", 2}, {"Horse", 1}, {"Beaver", 2}, {"Otter", 1}, {"Pig", 3}, {"Mosquito", 2}, }, { // Tier 2 {"Crab", 3}, {"Swan", 2}, {"Hedgehog", 3}, {"Peacock", 4}, {"Flamingo", 3}, {"Rat", 2}, {"Shrimp", 2}, {"Spider", 3}, }, { // Tier 3 {"Dog", 4}, {"Badger", 4}, {"Camel", 3}, {"Giraffe", 3}, {"Kangaroo", 4}, {"Ox", 5}, {"Rabbit", 3}, {"Sheep", 4}, }, { // Tier 4 {"Skunk", 5}, {"Hippo", 6}, {"Bison", 6}, {"Deer", 4}, {"Squirrel", 4}, {"Whale", 5}, {"Worm", 4}, {"Penguin", 5}, }, { // Tier 5 {"Scorpion", 5}, {"Rhino", 7}, {"Monkey", 6}, {"Cow", 6}, {"Seal", 6}, {"Shark", 7}, {"Turkey", 5}, {"Crocodile", 8}, }, { // Tier 6 {"Leopard", 8}, {"Boar", 9}, {"Fly", 7}, {"Gorilla", 9}, {"Mammoth", 10}, {"Snake", 8}, {"Tiger", 9}, {"Dragon", 10}, }, } // newCardID mints a unique card ID within the game. func (g *Game) newCardID() string { g.NextCardID++ return fmt.Sprintf("c%d", g.NextCardID) } // buildShopDecks creates all six tier decks (unshuffled). func (g *Game) buildShopDecks() { g.ShopDecks = make([][]Card, MaxRounds) for tierIdx, templates := range petTiers { deck := make([]Card, 0, len(templates)*copiesPerPet) for i, t := range templates { for range copiesPerPet { deck = append(deck, Card{ ID: g.newCardID(), Kind: KindPet, Name: t.Name, Tier: tierIdx + 1, Power: t.Power, Suit: suits[i%len(suits)], }) } } g.ShopDecks[tierIdx] = deck } } // newApple mints an apple food card (from discarding, etc.). func (g *Game) newApple() Card { return Card{ ID: g.newCardID(), Kind: KindFood, Name: "Apple", Food: FoodApple, } }