draft/pack.go

90 lines
2.0 KiB
Go

package draft
import (
"math/rand"
"strings"
)
// Pack is a collection of cards from a booster pack
type Pack []Card
// Card is a single card
type Card struct {
ID string
}
// CardProvider is a function that returns as many cards of a certain types as needed
type CardProvider func(int) []Card
// PackSchema is all that's needed to generate a certain type of pack
type PackSchema struct {
Slots []PackSlot
}
// PackSlot is part of how packs are made, one or more providers provide
// cards for X cards of the whole pack
type PackSlot struct {
Amount int
Provider CardProvider
Alternate []AlternateProvider
}
// AlternateProvider are Card providers that can replace one or more slots
// with special cards (foils, ultra rares)
type AlternateProvider struct {
Probability float32
Provider CardProvider
}
// MakePack makes a booster pack from a given set
// It's a shortcut to `MakePackWithSchema(set.PackSchema())`
func MakePack(set Set) Pack {
schema := set.PackSchema()
return MakePackWithSchema(schema)
}
// MakePackWithSchema makes a booster pack from a given schema
func MakePackWithSchema(schema PackSchema) Pack {
pack := make(Pack, 0)
for _, slot := range schema.Slots {
// Default provider
provider := slot.Provider
// Check for random alternates
if slot.Alternate != nil {
var currentProb float32
var chosenProb = rand.Float32()
for _, alt := range slot.Alternate {
currentProb += alt.Probability
if currentProb > chosenProb {
provider = alt.Provider
break
}
}
}
// Extract cards from provider and add them to the pack
cards := provider(slot.Amount)
pack = append(pack, cards...)
}
return pack
}
// String encodes a pack to a list of space-separated IDs
func (p Pack) String() (str string) {
for _, card := range p {
str += " " + card.ID
}
str = strings.TrimSpace(str)
return
}
// IDs unwraps all the IDs from the cards in the pack
func (p Pack) IDs() []string {
out := make([]string, len(p))
for i, card := range p {
out[i] = card.ID
}
return out
}