Add passing logic and pod tests

This commit is contained in:
Hamcha 2019-06-17 21:45:15 +02:00
parent d5deca8993
commit 3463fadfac
Signed by: hamcha
GPG key ID: A40413D21021EAEE
2 changed files with 94 additions and 14 deletions

61
pod.go
View file

@ -4,8 +4,9 @@ import "errors"
// Errors that can happen during draft // Errors that can happen during draft
var ( var (
ErrNotInPack = errors.New("card picked not in pack") ErrNotInPack = errors.New("card picked not in pack")
ErrNoPacksLeft = errors.New("no packs left to open") ErrNoPacksLeft = errors.New("no packs left to open")
ErrNoPendingPack = errors.New("no packs received from other players")
) )
// PodDirection is the direction packs are passed between players // PodDirection is the direction packs are passed between players
@ -22,7 +23,8 @@ type Pod struct {
Players []*Player Players []*Player
Direction PodDirection Direction PodDirection
NextRound chan bool ReadyNextPick chan bool
ReadyNextPack chan bool
} }
// Player is a single player partecipating in a pod // Player is a single player partecipating in a pod
@ -50,8 +52,10 @@ func MakePod(playerCount int, provider PackProvider) *Pod {
// Make pod // Make pod
pod := &Pod{ pod := &Pod{
Players: players, Players: players,
Direction: PRAnticlockwise, Direction: PRAnticlockwise,
ReadyNextPick: make(chan bool, 1),
ReadyNextPack: make(chan bool, 1),
} }
// Fill players // Fill players
@ -88,6 +92,17 @@ func (p *Pod) OpenPacks() error {
return nil return nil
} }
// NextPacks makes player exchange packs for the next pick
func (p *Pod) NextPacks() error {
for _, p := range p.Players {
err := p.NextPack()
if err != nil {
return err
}
}
return nil
}
func (p *Pod) flipDirection() { func (p *Pod) flipDirection() {
if p.Direction == PRClockwise { if p.Direction == PRClockwise {
p.Direction = PRAnticlockwise p.Direction = PRAnticlockwise
@ -96,15 +111,28 @@ func (p *Pod) flipDirection() {
} }
} }
func (p *Pod) checkRound() { func (p *Pod) checkPicks() {
for _, player := range p.Players { for _, player := range p.Players {
if len(player.newpack) < 1 { if len(player.newpack) < 1 {
// Someone still hasn't passed a pack // Someone still hasn't passed a pack but has cards
return return
} }
} }
// Everyone has new packs to draft // Everyone has new packs to draft
p.NextRound <- true p.ReadyNextPick <- true
}
func (p *Pod) checkEndPack() {
for _, player := range p.Players {
if len(player.CurrentPack) != 0 {
// Someone still has cards to draft
return
}
}
// Everyone needs to open their next pack
p.ReadyNextPack <- true
} }
// OpenPack opens the next pack the player has // OpenPack opens the next pack the player has
@ -116,6 +144,15 @@ func (p *Player) OpenPack() error {
return nil return nil
} }
// NextPack picks the next pack passed from other players
func (p *Player) NextPack() error {
if len(p.newpack) < 1 {
return ErrNoPendingPack
}
p.CurrentPack = <-p.newpack
return nil
}
// Pick specified what card a player has picked and gives the pack to the next player // Pick specified what card a player has picked and gives the pack to the next player
func (p *Player) Pick(pick Card) error { func (p *Player) Pick(pick Card) error {
// Check that pack contains specified card // Check that pack contains specified card
@ -135,6 +172,12 @@ func (p *Player) Pick(pick Card) error {
p.CurrentPack[id] = p.CurrentPack[len(p.CurrentPack)-1] p.CurrentPack[id] = p.CurrentPack[len(p.CurrentPack)-1]
p.CurrentPack = p.CurrentPack[:len(p.CurrentPack)-1] p.CurrentPack = p.CurrentPack[:len(p.CurrentPack)-1]
// Out of cards! Check if everyone else is as well
if len(p.CurrentPack) == 0 {
p.pod.checkEndPack()
return nil
}
// Send pack to next player // Send pack to next player
if p.pod.Direction == PRClockwise { if p.pod.Direction == PRClockwise {
p.left.newpack <- p.CurrentPack p.left.newpack <- p.CurrentPack
@ -142,7 +185,7 @@ func (p *Player) Pick(pick Card) error {
p.right.newpack <- p.CurrentPack p.right.newpack <- p.CurrentPack
} }
p.pod.checkRound() p.pod.checkPicks()
return nil return nil
} }

View file

@ -41,15 +41,44 @@ func TestPick(t *testing.T) {
// Create pod // Create pod
pod := draft.MakePod(PlayersPerPod, testProvider) pod := draft.MakePod(PlayersPerPod, testProvider)
pod.OpenPacks()
for _, player := range pod.Players { // Simulate a round of drafting
// Pick first card for each player // Each player will always pick their first card
err := player.Pick(player.CurrentPack[0]) // Repeat until all packs are gone
// Channels are tested when they should trigger
for packnum := 0; packnum < PacksPerPlayer; packnum++ {
// Open new packs!
err := pod.OpenPacks()
if err != nil { if err != nil {
t.Fatalf("Tried picking first card in pack but couldn't: %s\n", err.Error()) t.Fatalf("Got an error while opening packs #%d: %s\n", packnum, err.Error())
}
for picknum := 0; picknum < PACKSIZE; picknum++ {
for _, player := range pod.Players {
// Pick first card for each player
err := player.Pick(player.CurrentPack[0])
if err != nil {
t.Fatalf("Tried picking first card in pack but couldn't: %s\n", err.Error())
}
}
// Make sure either ReadyNextPick or ReadyNextPack triggers
select {
case <-pod.ReadyNextPick:
// Pass packs around
err := pod.NextPacks()
if err != nil {
t.Fatalf("Got an error while passing packs: %s\n", err.Error())
}
case <-pod.ReadyNextPack:
break
default:
t.Fatal("ReadyNextPick/ReadyNextPack channel should trigger but hasn't\n")
}
} }
} }
} }
func TestPodErrors(t *testing.T) { func TestPodErrors(t *testing.T) {
@ -71,6 +100,14 @@ func TestPodErrors(t *testing.T) {
t.Fatalf("Got error for wrong pick but not the right one: %s\n", err.Error()) t.Fatalf("Got error for wrong pick but not the right one: %s\n", err.Error())
} }
// Try getting packs from nearby players when no one is passing them
err = pod.NextPacks()
if err == nil {
t.Fatal("Tried getting inexistant packs from nearby players but it succeeded\n")
} else if err != draft.ErrNoPendingPack {
t.Fatalf("Got error for non existant pack but not the right one: %s\n", err.Error())
}
// Try opening more packs than each player has // Try opening more packs than each player has
for i := 0; i < PacksPerPlayer; i++ { for i := 0; i < PacksPerPlayer; i++ {
err = pod.OpenPacks() err = pod.OpenPacks()