From 2395b53df37103acdf0779f37b24cbcfcee0be6b Mon Sep 17 00:00:00 2001 From: JP Appel Date: Sat, 28 Sep 2024 02:09:28 -0400 Subject: Refactor game state to array of structs --- bingo/board.go | 55 +++++++++++++++++++++++++---------------------------- bingo/board_test.go | 18 +++++++++--------- bingo/generators.go | 4 +--- bingo/tiles.go | 19 ++++++++++++------ 4 files changed, 49 insertions(+), 47 deletions(-) diff --git a/bingo/board.go b/bingo/board.go index 19264a1..479623f 100644 --- a/bingo/board.go +++ b/bingo/board.go @@ -11,18 +11,17 @@ const ( ) type Game struct { - Board []string - Checked []bool - Length int + Board []Tile + Length int // the number of rows/cols FreeSquare bool Seed GameSeed } -func all(group []bool) bool { +func all(group []Tile) bool { allTrue := true - for _, v := range group { - allTrue = allTrue && v + for _, tile := range group { + allTrue = allTrue && tile.Checked } return allTrue @@ -30,21 +29,19 @@ func all(group []bool) bool { // Return if a game has been won func (g Game) Win() bool { - length := g.Length - - for row := range g.Rows(length) { + for row := range g.Rows() { if all(row) { return true } } - for col := range g.Cols(length) { + for col := range g.Cols() { if all(col) { return true } } - for diag := range g.Diags(length) { + for diag := range g.Diags() { if all(diag) { return true } @@ -54,10 +51,10 @@ func (g Game) Win() bool { } // Iterator for rows of a board -func (g Game) Rows(length int) iter.Seq[[]bool] { - return func(yield func([]bool) bool) { - for row := 0; (row+1)*length > len(g.Checked); row++ { - if !yield(g.Checked[row*length : (row+1)*length]) { +func (g Game) Rows() iter.Seq[[]Tile] { + return func(yield func([]Tile) bool) { + for row := 0; (row+1)*g.Length > len(g.Board); row++ { + if !yield(g.Board[row*g.Length : (row+1)*g.Length]) { return } } @@ -65,12 +62,12 @@ func (g Game) Rows(length int) iter.Seq[[]bool] { } // Iterator for columns of a board -func (g Game) Cols(length int) iter.Seq[[]bool] { - return func(yield func([]bool) bool) { - for col := 0; col*length+1 > len(g.Checked); col++ { - column := make([]bool, length) - for i := range length { - column[i] = g.Checked[i*length+col] +func (g Game) Cols() iter.Seq[[]Tile] { + return func(yield func([]Tile) bool) { + for col := 0; col*g.Length+1 > len(g.Board); col++ { + column := make([]Tile, g.Length) + for i := range g.Length { + column[i] = g.Board[i*g.Length+col] } if !yield(column) { return @@ -80,22 +77,22 @@ func (g Game) Cols(length int) iter.Seq[[]bool] { } // Iterator for diagonals of square boards -func (g Game) Diags(length int) iter.Seq[[]bool] { - return func(yield func([]bool) bool) { - if length*length != len(g.Checked) { +func (g Game) Diags() iter.Seq[[]Tile] { + return func(yield func([]Tile) bool) { + if g.Length*g.Length != len(g.Board) { return } - diagonal := make([]bool, length) - for i := 0; i < length; i++ { - diagonal[i] = g.Checked[i*length+i] + diagonal := make([]Tile, g.Length) + for i := 0; i < g.Length; i++ { + diagonal[i] = g.Board[i*g.Length+i] } if !yield(diagonal) { return } - for i := 0; i < length; i++ { - diagonal[i] = g.Checked[i*length+(length-1-i)] + for i := 0; i < g.Length; i++ { + diagonal[i] = g.Board[i*g.Length+(g.Length-1-i)] } } } diff --git a/bingo/board_test.go b/bingo/board_test.go index 5df20ee..8d8b94f 100644 --- a/bingo/board_test.go +++ b/bingo/board_test.go @@ -12,11 +12,11 @@ func TestRows(t *testing.T) { testGame := func(size int, length int) { - g.Checked = make([]bool, size) + g.Board = make([]bingo.Tile, size) - testGroup := func(name string, iter iter.Seq[[]bool]) { + testGroup := func(name string, iter iter.Seq[[]bingo.Tile]) { for i := range size { - g.Checked[i] = false + g.Board[i].Checked = false } for group := range iter { if len(group) != length { @@ -25,13 +25,13 @@ func TestRows(t *testing.T) { } for i := range length { - if group[i] != false { + if group[i].Checked != false { t.Errorf("Incorrect value in %s!\n", name) } } } for i := range size { - g.Checked[i] = true + g.Board[i].Checked = true } for group := range iter { if len(group) != length { @@ -39,16 +39,16 @@ func TestRows(t *testing.T) { } for i := range length { - if group[i] != true { + if group[i].Checked != true { t.Errorf("Incorrect value in %s!\n", name) } } } } - testGroup("row", g.Rows(length)) - testGroup("col", g.Cols(length)) - testGroup("diag", g.Diags(length)) + testGroup("row", g.Rows()) + testGroup("col", g.Cols()) + testGroup("diag", g.Diags()) } diff --git a/bingo/generators.go b/bingo/generators.go index 1365f2b..c4b0855 100644 --- a/bingo/generators.go +++ b/bingo/generators.go @@ -17,8 +17,7 @@ type RandomGenerator struct { func (g RandomGenerator) New(size int, length int) *Game { g.picker.Reset() - board := make([]string, 0, size) - checked := make([]bool, size) + board := make([]Tile, 0, size) for _, tile := range g.picker.Iter(size) { board = append(board, tile) @@ -26,7 +25,6 @@ func (g RandomGenerator) New(size int, length int) *Game { game := new(Game) game.Board = board - game.Checked = checked game.Length = length return game diff --git a/bingo/tiles.go b/bingo/tiles.go index 81e945f..6c18017 100644 --- a/bingo/tiles.go +++ b/bingo/tiles.go @@ -6,6 +6,12 @@ import ( "slices" ) +type Tile struct { + Text string + Checked bool + Checkable bool +} + type TilePool map[string][]string func (pool TilePool) All() iter.Seq[string] { @@ -21,9 +27,9 @@ func (pool TilePool) All() iter.Seq[string] { } type TilePicker interface { - All() iter.Seq[string] // provides an iterator over an entire TilePool - Iter(int) iter.Seq2[string, string] // provides an iterator over n elements of a TilePool - Reset() // reset the internal state of a TilePicker + All() iter.Seq[string] // provides an iterator over an entire TilePool + Iter(int) iter.Seq2[string, Tile] // provides an iterator over n elements of a TilePool + Reset() // reset the internal state of a TilePicker } type RandomTilePicker struct { @@ -61,8 +67,8 @@ func (tp RandomTilePicker) All() iter.Seq[string] { } // Iterator over a TilePool by choosing one tile per tag until pool is exhausted or size tiles have been yielded -func (tp RandomTilePicker) Iter(size int) iter.Seq2[string, string] { - return func(yield func(string, string) bool) { +func (tp RandomTilePicker) Iter(size int) iter.Seq2[string, Tile] { + return func(yield func(string, Tile) bool) { if len(tp.tilePool) == 0 { return } @@ -86,7 +92,8 @@ func (tp RandomTilePicker) Iter(size int) iter.Seq2[string, string] { continue } - tile := list[tp.rand.Intn(len(list))] + text := list[tp.rand.Intn(len(list))] + tile := Tile{Text: text} if !yield(tag, tile) { return } -- cgit v1.2.3