package draft import "math/rand" // Set is an interface for all game sets/expansions type Set interface { PackSchema() PackSchema } // GenericSet is an generalized set of a card game // Treat this as an example implementation or a starting type GenericSet struct { Cards []Card PackSize int Alternates []AlternateProvider } // PackSchema returns the pack schema from a booster containing all possible cards func (g *GenericSet) PackSchema() PackSchema { return PackSchema{ Slots: []PackSlot{ {Amount: g.PackSize, Provider: g.RandomProvider(), Alternate: g.Alternates}, }, } } // RandomProvider returns a provider for random cards from the set func (g *GenericSet) RandomProvider() CardProvider { return func(n int) []Card { out := make([]Card, n) for n := range out { idx := rand.Intn(len(g.Cards)) out[n] = g.Cards[idx] } return out } } // GenericCube is a "consumable" set, meaning cards get taken out of the pool as they are put in packs type GenericCube struct { Cards []Card PackSize int } // PackSchema returns the pack schema from a booster containing all possible cards func (c *GenericCube) PackSchema() PackSchema { return PackSchema{ Slots: []PackSlot{ {Amount: c.PackSize, Provider: c.RandomProvider()}, }, } } // RandomProvider returns a provider for random cards from the set func (c *GenericCube) RandomProvider() CardProvider { return func(n int) (out []Card) { c.shuffle() if len(c.Cards) < n { n = len(c.Cards) } out, c.Cards = c.Cards[:n], c.Cards[n:] return } } func (c *GenericCube) shuffle() { rand.Shuffle(len(c.Cards), func(i, j int) { c.Cards[i], c.Cards[j] = c.Cards[j], c.Cards[i] }) }