diff --git a/conway/conway_test.go b/conway/conway_test.go index 7ca2094..d2ce709 100644 --- a/conway/conway_test.go +++ b/conway/conway_test.go @@ -2,6 +2,7 @@ package conway_test import ( "fmt" + "math/rand" "strings" "testing" ) @@ -180,7 +181,7 @@ func TestNewGameOfLifeHasGameStateOfSameDimensions(t *testing.T) { t.Fail() } - if len(game.State.Rows[0].Cols) < 16 { + if len(game.State.Rows[0].Cells) < 16 { t.Fail() } } @@ -480,3 +481,86 @@ func TestGameOfLifeEmitsGenerationTicksUntilStasis(t *testing.T) { t.Errorf("%v is too few generations!", nGens) } } + +func TestGameStateRowsCanBeGottenByYCoord(t *testing.T) { + state, err := newTestGameState() + if err != nil { + t.Error(err) + return + } + + row := state.GetRow(1) + + if len(row.Cells) < 1 { + t.Fail() + } +} + +func TestGameStateRowsCanBeGottenByYCoordsBeyondBounds(t *testing.T) { + state, err := newTestGameState() + if err != nil { + t.Error(err) + return + } + + newVal := rand.Intn(9999) + + err = state.Set(0, 2, newVal) + if err != nil { + t.Error(err) + return + } + + row := state.GetRow(state.Height() + 2) + + if row.Cells[0] != newVal { + t.Errorf("(0, 2) != %d: %d", newVal, row.Cells[0]) + return + } +} + +func TestGameStateRowCellsCanBeGottenByXCoord(t *testing.T) { + state, err := newTestGameState() + if err != nil { + t.Error(err) + return + } + + newVal := rand.Intn(9999) + + err = state.Set(4, 0, newVal) + if err != nil { + t.Error(err) + return + } + + row := state.GetRow(0) + cell := row.GetCell(4) + + if cell.Value != newVal { + t.Errorf("(0, 4) != %d: %d", newVal, cell.Value) + } +} + +func TestGameStateRowCellsCanBeGottenByXCoordBeyondBounds(t *testing.T) { + state, err := newTestGameState() + if err != nil { + t.Error(err) + return + } + + newVal := rand.Intn(9999) + + err = state.Set(9, 2, newVal) + if err != nil { + t.Error(err) + return + } + + row := state.GetRow(2) + cell := row.GetCell(state.Width() + 9) + + if cell.Value != newVal { + t.Errorf("(9, 2) != %d: %d", newVal, cell.Value) + } +} diff --git a/conway/game_state.go b/conway/game_state.go index b59540b..38327a2 100644 --- a/conway/game_state.go +++ b/conway/game_state.go @@ -14,20 +14,16 @@ const ( LIVE_CELL = " " ) -type gameGridRow struct { - Cols []int -} - type GameState struct { - Rows []*gameGridRow + Rows []*GameStateRow } func NewGameState(height, width int) *GameState { state := &GameState{} for i := 0; i < height; i++ { - row := &gameGridRow{} + row := &GameStateRow{Y: i} for j := 0; j < width; j++ { - row.Cols = append(row.Cols, 0) + row.Cells = append(row.Cells, 0) } state.Rows = append(state.Rows, row) } @@ -42,15 +38,17 @@ func (state *GameState) Width() int { if len(state.Rows) < 1 { return -1 } - return len(state.Rows[0].Cols) + return len(state.Rows[0].Cells) } -func (state *GameState) GetRow(y int) (*gameGridRow, error) { - if y+1 > len(state.Rows) { - return nil, errors.New("y coordinate is out of bounds!") +func (state *GameState) GetRow(y int) *GameStateRow { + lenRows := len(state.Rows) + + if y+1 > lenRows { + return state.GetRow(y % lenRows) } - return state.Rows[y], nil + return state.Rows[y] } func (state *GameState) Set(x, y, value int) error { @@ -59,31 +57,25 @@ func (state *GameState) Set(x, y, value int) error { return errors.New(errMsg) } - row, err := state.GetRow(y) - if err != nil { - return err - } + row := state.GetRow(y) - if x+1 > len(row.Cols) { + if x+1 > len(row.Cells) { errMsg := fmt.Sprintf("x coordinate %v is out of bounds!", x) return errors.New(errMsg) } - row.Cols[x] = value + row.Cells[x] = value return nil } func (state *GameState) Get(x, y int) (int, error) { - row, err := state.GetRow(y) - if err != nil { - return -1, err - } + row := state.GetRow(y) - if len(row.Cols) < x+1 { + if len(row.Cells) < x+1 { return -1, errors.New("x coordinate is out of bounds!") } - return row.Cols[x], nil + return row.Cells[x], nil } func (state *GameState) Enliven(x, y int) error { @@ -96,7 +88,7 @@ func (state *GameState) Deaden(x, y int) error { func (state *GameState) Import(other *GameState) (err error) { for y, row := range other.Rows { - for x, cell := range row.Cols { + for x, cell := range row.Cells { if err = state.Set(x, y, cell); err != nil { return err } @@ -121,10 +113,7 @@ func (state *GameState) Cells() (<-chan *GameStateCell, error) { width := state.Width() for y := 0; y < height; y++ { - row, err := state.GetRow(y) - if err != nil { - panic(err) - } + row := state.GetRow(y) for x := 0; x < width; x++ { value, err := state.Get(x, y) @@ -132,10 +121,10 @@ func (state *GameState) Cells() (<-chan *GameStateCell, error) { panic(err) } c <- &GameStateCell{ - Value: value, - X: x, - Y: y, - cols: row.Cols, + Value: value, + X: x, + Y: y, + cellmates: row.Cells, } } } diff --git a/conway/game_state_cell.go b/conway/game_state_cell.go index 963f20f..1458c22 100644 --- a/conway/game_state_cell.go +++ b/conway/game_state_cell.go @@ -1,12 +1,12 @@ package conway type GameStateCell struct { - Value int - X int - Y int - cols []int + Value int + X int + Y int + cellmates []int } func (cell *GameStateCell) SetValue(value int) { - cell.cols[cell.X] = value + cell.cellmates[cell.X] = value } diff --git a/conway/game_state_row.go b/conway/game_state_row.go new file mode 100644 index 0000000..358b23f --- /dev/null +++ b/conway/game_state_row.go @@ -0,0 +1,21 @@ +package conway + +type GameStateRow struct { + Y int + Cells []int +} + +func (row *GameStateRow) GetCell(x int) *GameStateCell { + lenCells := len(row.Cells) + + if x+1 > lenCells { + return row.GetCell(x % lenCells) + } + + return &GameStateCell{ + Value: row.Cells[x], + X: x, + Y: row.Y, + cellmates: row.Cells, + } +} diff --git a/conway/generation_score_card.go b/conway/generation_score_card.go index aaa506e..347c2e9 100644 --- a/conway/generation_score_card.go +++ b/conway/generation_score_card.go @@ -25,9 +25,9 @@ type neighbor struct { func NewGenerationScoreCard(height, width int) *GenerationScoreCard { genScore := &GenerationScoreCard{} for i := 0; i < height; i++ { - row := &gameGridRow{} + row := &GameStateRow{Y: i} for j := 0; j < width; j++ { - row.Cols = append(row.Cols, 0) + row.Cells = append(row.Cells, 0) } genScore.Rows = append(genScore.Rows, row) }