Files
super-auto-pets-board-game/internal/game/cards.go
T
2026-07-22 23:07:29 -04:00

121 lines
3.2 KiB
Go

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,
}
}