From e8a181a4f7dcc6ea6a1b90772b77054137e05b13 Mon Sep 17 00:00:00 2001 From: Branden J Brown Date: Mon, 29 Jan 2024 21:20:17 -0600 Subject: [PATCH] include shell counts in game dto --- game/game.go | 20 ++++------ game/game_test.go | 97 ++++++++++++++++++++++++----------------------- serve/dto.go | 12 +++--- 3 files changed, 62 insertions(+), 67 deletions(-) diff --git a/game/game.go b/game/game.go index ddc6113..d4fe1a0 100644 --- a/game/game.go +++ b/game/game.go @@ -226,6 +226,11 @@ func (g *Match) Concede(id player.ID) error { // DTO returns the current match state as viewed by the given player. func (g *Match) DTO(id player.ID) serve.Game { + var live, blank int + if g.turn == 1 { + live = len(g.shells) / 2 + blank = len(g.shells) - live + } return serve.Game{ Players: [2]serve.Player{ g.players[0].DTO(), @@ -235,22 +240,11 @@ func (g *Match) DTO(id player.ID) serve.Game { Damage: g.damage, Shell: g.Peek(id), Previous: g.prev, + Live: live, + Blank: blank, } } -// ShellCounts returns the number of live and blank shells. -func (g *Match) ShellCounts() serve.ShellCounts { - var counts serve.ShellCounts - for _, s := range g.shells { - if s { - counts.Live++ - } else { - counts.Blank++ - } - } - return counts -} - var ( ErrWrongTurn = errors.New("not your turn") ErrGameEnded = errors.New("the shotgun is empty") diff --git a/game/game_test.go b/game/game_test.go index b84d355..829103f 100644 --- a/game/game_test.go +++ b/game/game_test.go @@ -79,7 +79,6 @@ func TestGameStartGroup(t *testing.T) { t.Parallel() g := New(player.ID{1}, player.ID{2}) for i := uint(1); i < 10000; i++ { - counts := g.ShellCounts() checks := []struct { failed bool msg string @@ -89,7 +88,6 @@ func TestGameStartGroup(t *testing.T) { {g.players[1].items[0] == ItemNone, "challenger has no first item: %v", []any{g.players[1].items}}, {len(g.shells) < 2 || len(g.shells) > 8, "bad shells count %d, want 2-8", []any{len(g.shells)}}, {&g.shells[0] != &g.shellArray[0], "shells[0] is %p, want %p", []any{&g.shells[0], &g.shellArray[0]}}, - {counts.Live != counts.Blank && counts.Live+1 != counts.Blank, "imbalanced live/blank %d/%d", []any{counts.Live, counts.Blank}}, {g.round != 1, "round is %d, want 1", []any{g.round}}, {g.turn != 1, "turn is %d, want 1", []any{g.turn}}, {g.damage != 1, "damage is %d, want 1", []any{g.damage}}, @@ -436,53 +434,56 @@ func TestConcede(t *testing.T) { } } -func TestGameShellCounts(t *testing.T) { - cases := []struct { - name string - shells []bool - want serve.ShellCounts - }{ - { - name: "empty", - shells: nil, - want: serve.ShellCounts{Live: 0, Blank: 0}, - }, - { - name: "one-live", - shells: []bool{true}, - want: serve.ShellCounts{Live: 1, Blank: 0}, - }, - { - name: "one-blank", - shells: []bool{false}, - want: serve.ShellCounts{Live: 0, Blank: 1}, - }, - { - name: "two", - shells: []bool{true, false}, - want: serve.ShellCounts{Live: 1, Blank: 1}, - }, - { - name: "three", - shells: []bool{true, false, true}, - want: serve.ShellCounts{Live: 2, Blank: 1}, - }, - { - name: "four", - shells: []bool{true, false, true, false}, - want: serve.ShellCounts{Live: 2, Blank: 2}, - }, +func TestGameDTO(t *testing.T) { + t.Parallel() + dealer, chall := player.ID{1}, player.ID{2} + g := New(dealer, chall) + { + want := serve.Game{ + Players: [2]serve.Player{ + g.players[0].DTO(), + g.players[1].DTO(), + }, + Round: g.round, + Damage: g.damage, + Shell: nil, + Previous: nil, + Live: len(g.shells) / 2, + Blank: (len(g.shells) + 1) / 2, + } + if got := g.DTO(dealer); want != got { + t.Errorf("dealer sees the wrong thing:\nwant %+v\ngot %+v", want, got) + } + if got := g.DTO(chall); want != got { + t.Errorf("challenger sees the wrong thing:\nwant %+v\ngot %+v", want, got) + } + if got := g.DTO(player.ID{}); want != got { + t.Errorf("observer sees the wrong thing:\nwant %+v\ngot %+v", want, got) + } } - for _, c := range cases { - c := c - t.Run(c.name, func(t *testing.T) { - t.Parallel() - g := New(player.ID{1}, player.ID{2}) - g.shells = c.shells - if got := g.ShellCounts(); got != c.want { - t.Errorf("wrong shell counts: got %#v, wanted %#v", got, c.want) - } - }) + g.Shoot(chall, false) + { + want := serve.Game{ + Players: [2]serve.Player{ + g.players[0].DTO(), + g.players[1].DTO(), + }, + Round: g.round, + Damage: g.damage, + Shell: nil, + Previous: &g.shellArray[0], + Live: 0, + Blank: 0, + } + if got := g.DTO(dealer); want != got { + t.Errorf("dealer sees the wrong thing:\nwant %+v\ngot %+v", want, got) + } + if got := g.DTO(chall); want != got { + t.Errorf("challenger sees the wrong thing:\nwant %+v\ngot %+v", want, got) + } + if got := g.DTO(player.ID{}); want != got { + t.Errorf("observer sees the wrong thing:\nwant %+v\ngot %+v", want, got) + } } } diff --git a/serve/dto.go b/serve/dto.go index 8774253..694e219 100644 --- a/serve/dto.go +++ b/serve/dto.go @@ -17,6 +17,12 @@ type Game struct { Shell *bool `json:"shell,omitempty"` // Previous gives whether the previously discharged shell was live. Previous *bool `json:"previous"` + // Live is the number of live shells this round, if it is the first turn + // of the round. + Live int `json:"live,omitempty"` + // Blank is the number of blank shells this round, if it is the first turn + // of the round. + Blank int `json:"blank,omitempty"` } // Player is the JSON DTO for a player. @@ -37,9 +43,3 @@ type GameStart struct { ID GameID `json:"id"` Dealer bool `json:"dealer"` } - -// ShellCounts is the JSON DTO for shell counts emitted at the start of a shell group. -type ShellCounts struct { - Live int `json:"live"` - Blank int `json:"blank"` -}