From 3463fadfac66e6d449e399b92ac31334f3a71452 Mon Sep 17 00:00:00 2001 From: Hamcha Date: Mon, 17 Jun 2019 21:45:15 +0200 Subject: [PATCH] Add passing logic and pod tests --- pod.go | 61 +++++++++++++++++++++++++++++++++++++++++++++-------- pod_test.go | 47 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 94 insertions(+), 14 deletions(-) diff --git a/pod.go b/pod.go index 25c226f..20720b1 100644 --- a/pod.go +++ b/pod.go @@ -4,8 +4,9 @@ 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") + ErrNotInPack = errors.New("card picked not in pack") + 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 @@ -22,7 +23,8 @@ type Pod struct { Players []*Player Direction PodDirection - NextRound chan bool + ReadyNextPick chan bool + ReadyNextPack chan bool } // Player is a single player partecipating in a pod @@ -50,8 +52,10 @@ func MakePod(playerCount int, provider PackProvider) *Pod { // Make pod pod := &Pod{ - Players: players, - Direction: PRAnticlockwise, + Players: players, + Direction: PRAnticlockwise, + ReadyNextPick: make(chan bool, 1), + ReadyNextPack: make(chan bool, 1), } // Fill players @@ -88,6 +92,17 @@ func (p *Pod) OpenPacks() error { 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() { if p.Direction == PRClockwise { p.Direction = PRAnticlockwise @@ -96,15 +111,28 @@ func (p *Pod) flipDirection() { } } -func (p *Pod) checkRound() { +func (p *Pod) checkPicks() { for _, player := range p.Players { if len(player.newpack) < 1 { - // Someone still hasn't passed a pack + // Someone still hasn't passed a pack but has cards return } } + // 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 @@ -116,6 +144,15 @@ func (p *Player) OpenPack() error { 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 func (p *Player) Pick(pick Card) error { // 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 = 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 if p.pod.Direction == PRClockwise { p.left.newpack <- p.CurrentPack @@ -142,7 +185,7 @@ func (p *Player) Pick(pick Card) error { p.right.newpack <- p.CurrentPack } - p.pod.checkRound() + p.pod.checkPicks() return nil } diff --git a/pod_test.go b/pod_test.go index a4b54b8..17e7205 100644 --- a/pod_test.go +++ b/pod_test.go @@ -41,15 +41,44 @@ func TestPick(t *testing.T) { // Create pod pod := draft.MakePod(PlayersPerPod, testProvider) - pod.OpenPacks() - for _, player := range pod.Players { - // Pick first card for each player - err := player.Pick(player.CurrentPack[0]) + // Simulate a round of drafting + // Each player will always pick their first card + // 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 { - 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) { @@ -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()) } + // 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 for i := 0; i < PacksPerPlayer; i++ { err = pod.OpenPacks()