package draft import "errors" // Errors that can happen during draft var ( ErrNotInPack = errors.New("card picked not in pack") ErrNoPacksLeft = errors.New("no packs left to open") ) // PodDirection is the direction packs are passed between players type PodDirection string // All rotations var ( PRClockwise PodDirection = "left" PRAnticlockwise PodDirection = "right" ) // Pod is a group of players drafting packs/cubes type Pod struct { Players []*Player Direction PodDirection } // Player is a single player partecipating in a pod type Player struct { // Packs and picks CurrentPack Pack Packs []Pack Picks []Card // Nearby players left *Player right *Player // Pod the player is in pod *Pod } // MakePod creates a pod with a specified number of players and a given set of packs func MakePod(playerCount int, provider PackProvider) *Pod { // Make player list players := make([]*Player, playerCount) // Make pod pod := &Pod{ Players: players, Direction: PRAnticlockwise, } // Fill players for i := range players { players[i] = &Player{ Packs: provider(), Picks: []Card{}, pod: pod, } } // Second loop to fill nearby players for i := range players { if i > 0 { players[i].left = players[i-1] } else { players[i].left = players[playerCount-1] } players[i].right = players[(i+1)%playerCount] } return pod } // OpenPacks opens the next pack of each player func (p *Pod) OpenPacks() error { for _, p := range p.Players { err := p.OpenPack() if err != nil { return err } } p.flipDirection() return nil } func (p *Pod) flipDirection() { if p.Direction == PRClockwise { p.Direction = PRAnticlockwise } else { p.Direction = PRClockwise } } // OpenPack opens the next pack the player has func (p *Player) OpenPack() error { if len(p.Packs) < 1 { return ErrNoPacksLeft } p.CurrentPack, p.Packs = p.Packs[0], p.Packs[1:] return nil } // Pick specified what card a player has picked and gives the pack to the next player func (p *Player) Pick(pick Card) error { // Check that pack contains specified card id := -1 for i, card := range p.CurrentPack { if pick.ID == card.ID { id = i break } } if id < 0 { return ErrNotInPack } // Take card from pack and put it into the picks p.Picks = append(p.Picks, p.CurrentPack[id]) // Remove pick from pack using slice tricks p.CurrentPack[id] = p.CurrentPack[len(p.CurrentPack)-1] p.CurrentPack = p.CurrentPack[:len(p.CurrentPack)-1] return nil }