simplify game state tracking

This commit is contained in:
Branden J Brown 2024-01-29 13:16:34 -06:00
parent 1099e0b618
commit a3bf457fd6
3 changed files with 7 additions and 16 deletions

View File

@ -26,11 +26,9 @@ type Match struct {
// uses shellArray as its backing array. // uses shellArray as its backing array.
shells []bool shells []bool
// round is the round number. Once it reaches 3, the match is over. // round is the round number. Once it reaches 3, the match is over.
round uint round int8
// game is the game number. May be nice for metrics eventually.
game uint
// turn is the turn number. When even, it is the dealer's turn. // turn is the turn number. When even, it is the dealer's turn.
turn uint turn int8
// hp is the starting and max HP of both players in the current round. // hp is the starting and max HP of both players in the current round.
hp int8 hp int8
// damage is the amount of damage a live shell will deal this turn. // damage is the amount of damage a live shell will deal this turn.
@ -65,7 +63,6 @@ func (g *Match) NextRound() {
g.players[0].StartRound(g.hp) g.players[0].StartRound(g.hp)
g.players[1].StartRound(g.hp) g.players[1].StartRound(g.hp)
g.round++ g.round++
g.game = 0
g.NextGame() g.NextGame()
} }
@ -83,7 +80,6 @@ func (g *Match) NextGame() {
} }
g.shells = g.shellArray[:shells] g.shells = g.shellArray[:shells]
ShuffleSlice(&g.rng, g.shells) ShuffleSlice(&g.rng, g.shells)
g.game++
g.turn = 0 g.turn = 0
g.prev = nil g.prev = nil
g.NextTurn() g.NextTurn()
@ -104,12 +100,12 @@ func (g *Match) NextTurn() {
// CurrentPlayer gets the current player. // CurrentPlayer gets the current player.
func (g *Match) CurrentPlayer() *Player { func (g *Match) CurrentPlayer() *Player {
return &g.players[g.turn%2] return &g.players[g.turn&1]
} }
// Opponent returns the player who is not the current player. // Opponent returns the player who is not the current player.
func (g *Match) Opponent() *Player { func (g *Match) Opponent() *Player {
return &g.players[g.turn%2^1] return &g.players[g.turn&1^1]
} }
// Apply uses an item by index for the current player. // Apply uses an item by index for the current player.

View File

@ -25,7 +25,6 @@ func TestNewGame(t *testing.T) {
{len(g.shells) < 2 || len(g.shells) > 8, "bad shells count %d, want 2-8", []any{len(g.shells)}}, {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]}}, {&g.shells[0] != &g.shellArray[0], "shells[0] is %p, want %p", []any{&g.shells[0], &g.shellArray[0]}},
{g.round != 1, "first round is %d, want 1", []any{g.round}}, {g.round != 1, "first round is %d, want 1", []any{g.round}},
{g.game != 1, "first group is %d, want 1", []any{g.game}},
{g.turn != 1, "first turn is %d, want 1", []any{g.turn}}, {g.turn != 1, "first turn is %d, want 1", []any{g.turn}},
{g.hp < 2 || g.hp > 4, "hp is %d, want 2-4", []any{g.hp}}, {g.hp < 2 || g.hp > 4, "hp is %d, want 2-4", []any{g.hp}},
{g.damage != 1, "damage is %d, want 1", []any{g.damage}}, {g.damage != 1, "damage is %d, want 1", []any{g.damage}},
@ -43,7 +42,7 @@ func TestNewGame(t *testing.T) {
func TestGameStartRound(t *testing.T) { func TestGameStartRound(t *testing.T) {
t.Parallel() t.Parallel()
g := New(player.ID{1}, player.ID{2}) g := New(player.ID{1}, player.ID{2})
for i := uint(1); i < 10000; i++ { for i := int8(1); i < 100; i++ {
checks := []struct { checks := []struct {
failed bool failed bool
msg string msg string
@ -54,7 +53,6 @@ func TestGameStartRound(t *testing.T) {
{len(g.shells) < 2 || len(g.shells) > 8, "bad shells count %d, want 2-8", []any{len(g.shells)}}, {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]}}, {&g.shells[0] != &g.shellArray[0], "shells[0] is %p, want %p", []any{&g.shells[0], &g.shellArray[0]}},
{g.round != i, "round is %d, want %d", []any{g.round, i}}, {g.round != i, "round is %d, want %d", []any{g.round, i}},
{g.game != 1, "group is %d, want 1", []any{g.game}},
{g.turn != 1, "turn is %d, want 1", []any{g.turn}}, {g.turn != 1, "turn is %d, want 1", []any{g.turn}},
{g.hp < 2 || g.hp > 4, "hp is %d, want 2-4", []any{g.hp}}, {g.hp < 2 || g.hp > 4, "hp is %d, want 2-4", []any{g.hp}},
{g.damage != 1, "damage is %d, want 1", []any{g.damage}}, {g.damage != 1, "damage is %d, want 1", []any{g.damage}},
@ -70,7 +68,6 @@ func TestGameStartRound(t *testing.T) {
g.players[0].hp = 0 g.players[0].hp = 0
g.popShell() g.popShell()
g.popShell() g.popShell()
g.game = 2
g.turn = 3 g.turn = 3
g.damage = 2 g.damage = 2
// Start the next round and check again. // Start the next round and check again.
@ -94,7 +91,6 @@ func TestGameStartGroup(t *testing.T) {
{&g.shells[0] != &g.shellArray[0], "shells[0] is %p, want %p", []any{&g.shells[0], &g.shellArray[0]}}, {&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}}, {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.round != 1, "round is %d, want 1", []any{g.round}},
{g.game != i, "group is %d, want %d", []any{g.game, i}},
{g.turn != 1, "turn is %d, want 1", []any{g.turn}}, {g.turn != 1, "turn is %d, want 1", []any{g.turn}},
{g.damage != 1, "damage is %d, want 1", []any{g.damage}}, {g.damage != 1, "damage is %d, want 1", []any{g.damage}},
{g.reveal, "revealed at start", nil}, {g.reveal, "revealed at start", nil},
@ -121,14 +117,13 @@ func TestGameStartGroup(t *testing.T) {
func TestGameNextTurn(t *testing.T) { func TestGameNextTurn(t *testing.T) {
t.Parallel() t.Parallel()
g := New(player.ID{1}, player.ID{2}) g := New(player.ID{1}, player.ID{2})
for i := uint(1); i < 10000; i++ { for i := int8(1); i < 100; i++ {
checks := []struct { checks := []struct {
failed bool failed bool
msg string msg string
args []any args []any
}{ }{
{g.round != 1, "round is %d, want 1", []any{g.round}}, {g.round != 1, "round is %d, want 1", []any{g.round}},
{g.game != 1, "group is %d, want 1", []any{g.game}},
{g.turn != i, "turn is %d, want %d", []any{g.turn, i}}, {g.turn != i, "turn is %d, want %d", []any{g.turn, i}},
{g.damage != 1, "damage is %d, want 1", []any{g.damage}}, {g.damage != 1, "damage is %d, want 1", []any{g.damage}},
{g.reveal, "revealed at start", nil}, {g.reveal, "revealed at start", nil},

View File

@ -8,7 +8,7 @@ type Game struct {
// The dealer is always the first player. // The dealer is always the first player.
Players [2]Player `json:"players"` Players [2]Player `json:"players"`
// Round is the current round. // Round is the current round.
Round uint `json:"round"` Round int8 `json:"round"`
// Damage is the damage a live shell will deal this turn. // Damage is the damage a live shell will deal this turn.
Damage int8 `json:"damage"` Damage int8 `json:"damage"`
// Shell gives whether the current shell is live if it is revealed. // Shell gives whether the current shell is live if it is revealed.