A bunch more work towards achieving torus

This commit is contained in:
Dan Buch 2012-12-16 12:17:44 -05:00
parent 7567f1c991
commit 8056d86cbf
6 changed files with 137 additions and 378 deletions

View File

@ -31,122 +31,68 @@ func init() {
s.Set(15, 15, 1) s.Set(15, 15, 1)
} }
func newTestGameState() (*GameState, error) { func newTestGameState() *GameState {
state := NewGameState(16, 16) state := NewGameState(16, 16)
state.Import(TEST_SIMPLE_INITIAL_STATE)
err := state.Import(TEST_SIMPLE_INITIAL_STATE) return state
if err != nil {
return nil, err
}
return state, nil
} }
func newTestGameOfLife() (*GameOfLife, error) { func newTestGameOfLife() *GameOfLife {
game := NewGameOfLife(16, 16) game := NewGameOfLife(16, 16)
game.State.Import(TEST_SIMPLE_INITIAL_STATE)
err := game.State.Import(TEST_SIMPLE_INITIAL_STATE) return game
if err != nil {
return nil, err
}
return game, nil
} }
func TestLiveCellWithFewerThanTwoLiveNeighborsDies(t *testing.T) { func TestLiveCellWithFewerThanTwoLiveNeighborsDies(t *testing.T) {
game, err := newTestGameOfLife() game := newTestGameOfLife()
if err != nil {
t.Error(err)
return
}
game.EvaluateGeneration() game.EvaluateGeneration()
value, err := game.State.Get(3, 2) cell := game.State.Get(3, 2)
if err != nil { if cell.Value != 0 {
t.Error(err) t.Errorf("%v != 0", cell.Value)
return
}
if value != 0 {
t.Errorf("%v != 0", value)
return return
} }
} }
func TestLiveCellWithTwoOrThreeLiveNeighborsLivesOn(t *testing.T) { func TestLiveCellWithTwoOrThreeLiveNeighborsLivesOn(t *testing.T) {
game, err := newTestGameOfLife() game := newTestGameOfLife()
if err != nil {
t.Error(err)
return
}
game.EvaluateGeneration() game.EvaluateGeneration()
value, err := game.State.Get(0, 0) cell := game.State.Get(0, 0)
if err != nil { if cell.Value != 1 {
t.Error(err) t.Errorf("%v != 1", cell.Value)
return
}
if value != 1 {
t.Errorf("%v != 1", value)
return return
} }
} }
func TestLiveCellWithMoreThanThreeLiveNeighborsDies(t *testing.T) { func TestLiveCellWithMoreThanThreeLiveNeighborsDies(t *testing.T) {
game, err := newTestGameOfLife() game := newTestGameOfLife()
if err != nil {
t.Error(err)
return
}
game.EvaluateGeneration() game.EvaluateGeneration()
value, err := game.State.Get(0, 1) cell := game.State.Get(0, 1)
if err != nil { if cell.Value != 0 {
t.Error(err) t.Errorf("%v != 0", cell.Value)
return
}
if value != 0 {
t.Errorf("%v != 0", value)
return return
} }
} }
func TestDeadCellWithExactlyThreeLiveNeighborsBecomesAlive(t *testing.T) { func TestDeadCellWithExactlyThreeLiveNeighborsBecomesAlive(t *testing.T) {
game, err := newTestGameOfLife() game := newTestGameOfLife()
if err != nil {
t.Error(err)
return
}
game.EvaluateGeneration() game.EvaluateGeneration()
value, err := game.State.Get(3, 1) cell := game.State.Get(3, 1)
if err != nil { if cell.Value != 1 {
t.Error(err) t.Errorf("%v != 1", cell.Value)
return
}
if value != 1 {
t.Errorf("%v != 1", value)
return return
} }
} }
func TestGameOfLifeCanDisplayItself(t *testing.T) { func TestGameOfLifeCanDisplayItself(t *testing.T) {
game, err := newTestGameOfLife() game := newTestGameOfLife()
if err != nil {
t.Error(err)
return
}
grid := fmt.Sprintf("%s\n", game) grid := fmt.Sprintf("%s\n", game)
@ -158,11 +104,7 @@ func TestGameOfLifeCanDisplayItself(t *testing.T) {
} }
func TestNewGameOfLifeHasCorrectDimensions(t *testing.T) { func TestNewGameOfLifeHasCorrectDimensions(t *testing.T) {
game, err := newTestGameOfLife() game := newTestGameOfLife()
if err != nil {
t.Error(err)
return
}
if game.State.Height() != 16 || game.State.Width() != 16 { if game.State.Height() != 16 || game.State.Width() != 16 {
t.Fail() t.Fail()
@ -170,12 +112,7 @@ func TestNewGameOfLifeHasCorrectDimensions(t *testing.T) {
} }
func TestNewGameOfLifeHasGameStateOfSameDimensions(t *testing.T) { func TestNewGameOfLifeHasGameStateOfSameDimensions(t *testing.T) {
game, err := newTestGameOfLife() game := newTestGameOfLife()
if err != nil {
t.Error(err)
return
}
if len(game.State.Rows) < 16 { if len(game.State.Rows) < 16 {
t.Fail() t.Fail()
@ -187,41 +124,33 @@ func TestNewGameOfLifeHasGameStateOfSameDimensions(t *testing.T) {
} }
func TestGameStateCanImportState(t *testing.T) { func TestGameStateCanImportState(t *testing.T) {
game, err := newTestGameOfLife() game := newTestGameOfLife()
if err != nil { if game.State.Get(0, 0).Value != 1 {
t.Fail() t.Fail()
} }
if value, err := game.State.Get(0, 0); err != nil || value != 1 { if game.State.Get(1, 0).Value != 1 {
t.Fail() t.Fail()
} }
if value, err := game.State.Get(1, 0); err != nil || value != 1 { if game.State.Get(0, 1).Value != 1 {
t.Fail() t.Fail()
} }
if value, err := game.State.Get(0, 1); err != nil || value != 1 { if game.State.Get(1, 1).Value != 1 {
t.Fail() t.Fail()
} }
if value, err := game.State.Get(1, 1); err != nil || value != 1 { if game.State.Get(2, 2).Value != 1 {
t.Fail()
}
if value, err := game.State.Get(2, 2); err != nil || value != 1 {
t.Fail() t.Fail()
} }
} }
func TestGameOfLifeCanImportRandomState(t *testing.T) { func TestGameOfLifeCanImportRandomState(t *testing.T) {
game, err := newTestGameOfLife() game := newTestGameOfLife()
if err != nil {
t.Error(err)
return
}
err = game.ImportRandomState() err := game.ImportRandomState()
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return return
@ -231,13 +160,8 @@ func TestGameOfLifeCanImportRandomState(t *testing.T) {
for y := 0; y < 16; y++ { for y := 0; y < 16; y++ {
for x := 0; x < 16; x++ { for x := 0; x < 16; x++ {
value, err := game.State.Get(x, y) cell := game.State.Get(x, y)
if err != nil { if cell.Value == 0 {
t.Error(err)
return
}
if value == 0 {
zeroCount++ zeroCount++
} }
} }
@ -249,11 +173,7 @@ func TestGameOfLifeCanImportRandomState(t *testing.T) {
} }
func TestGameStateCanDisplayItself(t *testing.T) { func TestGameStateCanDisplayItself(t *testing.T) {
state, err := newTestGameState() state := newTestGameState()
if err != nil {
t.Error(err)
return
}
grid := fmt.Sprintf("%s\n", state) grid := fmt.Sprintf("%s\n", state)
lenGrid := len(grid) lenGrid := len(grid)
@ -274,7 +194,7 @@ func TestNewGameStatesAreAllDead(t *testing.T) {
state := NewGameState(4, 4) state := NewGameState(4, 4)
for x := 0; x < 3; x++ { for x := 0; x < 3; x++ {
for y := 0; y < 3; y++ { for y := 0; y < 3; y++ {
if value, err := state.Get(x, y); err != nil || value != 0 { if state.Get(x, y).Value != 0 {
t.Fail() t.Fail()
} }
} }
@ -283,29 +203,25 @@ func TestNewGameStatesAreAllDead(t *testing.T) {
func TestGameStateCanGetCellValueByCoords(t *testing.T) { func TestGameStateCanGetCellValueByCoords(t *testing.T) {
state := NewGameState(8, 8) state := NewGameState(8, 8)
if value, err := state.Get(2, 2); err != nil || value != 0 { if state.Get(2, 2).Value != 0 {
t.Fail() t.Fail()
} }
} }
func TestGameStateCanSetCellValueByCoords(t *testing.T) { func TestGameStateCanSetCellValueByCoords(t *testing.T) {
state := NewGameState(8, 8) state := NewGameState(8, 8)
if err := state.Set(2, 5, 1); err != nil { state.Set(2, 5, 1)
t.Fail()
}
if value, err := state.Get(2, 5); err != nil || value != 1 { if state.Get(2, 5).Value != 1 {
t.Fail() t.Fail()
} }
} }
func TestGameStateCanEnlivenCellsByCoords(t *testing.T) { func TestGameStateCanEnlivenCellsByCoords(t *testing.T) {
state := NewGameState(8, 8) state := NewGameState(8, 8)
if err := state.Enliven(0, 1); err != nil { state.Enliven(0, 1)
t.Fail()
}
if value, err := state.Get(0, 1); err != nil || value != 1 { if state.Get(0, 1).Value != 1 {
t.Fail() t.Fail()
} }
} }
@ -313,19 +229,15 @@ func TestGameStateCanEnlivenCellsByCoords(t *testing.T) {
func TestGameStateCanDeadenCellsByCoords(t *testing.T) { func TestGameStateCanDeadenCellsByCoords(t *testing.T) {
state := NewGameState(8, 8) state := NewGameState(8, 8)
if err := state.Enliven(0, 1); err != nil { state.Enliven(0, 1)
if state.Get(0, 1).Value != 1 {
t.Fail() t.Fail()
} }
if value, err := state.Get(0, 1); err != nil || value != 1 { state.Deaden(0, 1)
t.Fail()
}
if err := state.Deaden(0, 1); err != nil { if state.Get(0, 1).Value != 0 {
t.Fail()
}
if value, err := state.Get(0, 1); err != nil || value != 0 {
t.Fail() t.Fail()
} }
} }
@ -335,7 +247,7 @@ func TestNewGenerationScoreCardIsAllZeros(t *testing.T) {
for y := 0; y < gen.Height(); y++ { for y := 0; y < gen.Height(); y++ {
for x := 0; x < gen.Width(); x++ { for x := 0; x < gen.Width(); x++ {
if value, err := gen.Get(x, y); err != nil || value != 0 { if gen.Get(x, y).Value != 0 {
t.Fail() t.Fail()
} }
} }
@ -345,38 +257,25 @@ func TestNewGenerationScoreCardIsAllZeros(t *testing.T) {
func TestGenerationScoreCardCalculateResultsInCorrectNeighborCounts(t *testing.T) { func TestGenerationScoreCardCalculateResultsInCorrectNeighborCounts(t *testing.T) {
genScore := NewGenerationScoreCard(16, 16) genScore := NewGenerationScoreCard(16, 16)
state, err := newTestGameState() state := newTestGameState()
if err != nil {
t.Error(err)
return
}
genScore.Calculate(state) genScore.Calculate(state)
value, err := genScore.Get(0, 0)
if err != nil { cell := genScore.Get(0, 0)
t.Error(err) if cell.Value != 3 {
return t.Errorf("[0, 0] value %v != 3", cell.Value)
} else if value != 3 {
t.Errorf("[0, 0] value %v != 3", value)
return return
} }
value, err = genScore.Get(3, 2) cell = genScore.Get(3, 2)
if err != nil { if cell.Value != 1 {
t.Error(err) t.Errorf("[3, 2] value %d != 1", cell.Value)
return
} else if value != 1 {
t.Errorf("[3, 2] value %d != 1", value)
return return
} }
} }
func TestStateCanMutate(t *testing.T) { func TestStateCanMutate(t *testing.T) {
state, err := newTestGameState() state := newTestGameState()
if err != nil {
t.Error(err)
return
}
curCksum, err := state.Checksum() curCksum, err := state.Checksum()
if err != nil { if err != nil {
@ -384,11 +283,7 @@ func TestStateCanMutate(t *testing.T) {
return return
} }
err = state.Mutate() state.Mutate()
if err != nil {
t.Error(err)
return
}
newCksum, err := state.Checksum() newCksum, err := state.Checksum()
if err != nil { if err != nil {
@ -402,11 +297,7 @@ func TestStateCanMutate(t *testing.T) {
} }
func TestStateProvidesCellIteratorChannel(t *testing.T) { func TestStateProvidesCellIteratorChannel(t *testing.T) {
state, err := newTestGameState() state := newTestGameState()
if err != nil {
t.Error(err)
return
}
cells, err := state.Cells() cells, err := state.Cells()
if err != nil { if err != nil {
@ -425,11 +316,7 @@ func TestStateProvidesCellIteratorChannel(t *testing.T) {
} }
func TestGameStateCellsCanHaveTheirValueSet(t *testing.T) { func TestGameStateCellsCanHaveTheirValueSet(t *testing.T) {
state, err := newTestGameState() state := newTestGameState()
if err != nil {
t.Error(err)
return
}
cells, err := state.Cells() cells, err := state.Cells()
if err != nil { if err != nil {
@ -438,7 +325,7 @@ func TestGameStateCellsCanHaveTheirValueSet(t *testing.T) {
} }
for cell := range cells { for cell := range cells {
cell.SetValue(1) cell.Value = 1
} }
cells, err = state.Cells() cells, err = state.Cells()
@ -454,12 +341,16 @@ func TestGameStateCellsCanHaveTheirValueSet(t *testing.T) {
} }
} }
func TestGameOfLifeEmitsGenerationTicksUntilStasis(t *testing.T) { func TestGameStateCellsCanBeFetchedByXAndYCoords(t *testing.T) {
game, err := newTestGameOfLife() state := newTestGameState()
if err != nil {
t.Error(err) if state.Get(3, 4) == nil {
return t.Fail()
} }
}
func TestGameOfLifeEmitsGenerationTicksUntilStasis(t *testing.T) {
game := newTestGameOfLife()
genTicks, err := game.Generations() genTicks, err := game.Generations()
if err != nil { if err != nil {
@ -482,85 +373,21 @@ func TestGameOfLifeEmitsGenerationTicksUntilStasis(t *testing.T) {
} }
} }
func TestGameStateRowsCanBeGottenByYCoord(t *testing.T) { func TestGameStateCoordsAreNeverOutOfBounds(t *testing.T) {
state, err := newTestGameState() state := newTestGameState()
if err != nil {
t.Error(err)
return
}
row := state.GetRow(1) oobX, oobY := state.Width()+rand.Intn(99), state.Height()+rand.Intn(99)
if len(row.Cells) < 1 { newVal := rand.Intn(9999)
state.Set(oobX, oobY, newVal)
cell := state.Get(oobX, oobY)
if cell == nil {
t.Fail() 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 { if cell.Value != newVal {
t.Errorf("(0, 4) != %d: %d", newVal, cell.Value) t.Errorf("(%d, %d) != %d: %d", oobX, oobY, 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)
} }
} }

View File

@ -51,8 +51,8 @@ func RunConsoleGame(height, width, sleepMs int, mutate bool) (int, error) {
return 0, nil return 0, nil
} }
func (game *GameOfLife) Mutate() error { func (game *GameOfLife) Mutate() {
return game.State.Mutate() game.State.Mutate()
} }
func (game *GameOfLife) Checksum() (string, error) { func (game *GameOfLife) Checksum() (string, error) {
@ -79,18 +79,11 @@ func (game *GameOfLife) EvaluateGeneration() error {
for cell := range cells { for cell := range cells {
score := cell.Value score := cell.Value
curState, err := game.State.Get(cell.X, cell.Y) cell := game.State.Get(cell.X, cell.Y)
if err != nil {
return err
}
if curState == 1 {
if cell.Value == 1 {
if score < 2 { if score < 2 {
err = game.State.Deaden(cell.X, cell.Y) game.State.Deaden(cell.X, cell.Y)
if err != nil {
return err
}
continue continue
} }
@ -99,19 +92,13 @@ func (game *GameOfLife) EvaluateGeneration() error {
} }
if score > 3 { if score > 3 {
err = game.State.Deaden(cell.X, cell.Y) game.State.Deaden(cell.X, cell.Y)
if err != nil {
return err
}
continue continue
} }
} else if curState == 0 { } else if cell.Value == 0 {
if score == 3 { if score == 3 {
err = game.State.Enliven(cell.X, cell.Y) game.State.Enliven(cell.X, cell.Y)
if err != nil {
return err
}
continue continue
} else { } else {
continue continue
@ -122,8 +109,8 @@ func (game *GameOfLife) EvaluateGeneration() error {
return nil return nil
} }
func (game *GameOfLife) ImportState(state *GameState) error { func (game *GameOfLife) ImportState(state *GameState) {
return game.State.Import(state) game.State.Import(state)
} }
func (game *GameOfLife) ImportRandomState() error { func (game *GameOfLife) ImportRandomState() error {
@ -144,10 +131,11 @@ func (game *GameOfLife) ImportRandomState() error {
} }
for cell := range cells { for cell := range cells {
cell.SetValue(rand.Intn(2)) cell.Value = rand.Intn(2)
} }
return game.ImportState(randState) game.ImportState(randState)
return nil
} }
func (game *GameOfLife) String() string { func (game *GameOfLife) String() string {

View File

@ -14,6 +14,17 @@ const (
LIVE_CELL = " " LIVE_CELL = " "
) )
type GameStateCell struct {
Value int
X int
Y int
}
type GameStateRow struct {
Y int
Cells []*GameStateCell
}
type GameState struct { type GameState struct {
Rows []*GameStateRow Rows []*GameStateRow
} }
@ -23,7 +34,11 @@ func NewGameState(height, width int) *GameState {
for i := 0; i < height; i++ { for i := 0; i < height; i++ {
row := &GameStateRow{Y: i} row := &GameStateRow{Y: i}
for j := 0; j < width; j++ { for j := 0; j < width; j++ {
row.Cells = append(row.Cells, 0) row.Cells = append(row.Cells, &GameStateCell{
Value: 0,
X: j,
Y: i,
})
} }
state.Rows = append(state.Rows, row) state.Rows = append(state.Rows, row)
} }
@ -51,50 +66,36 @@ func (state *GameState) GetRow(y int) *GameStateRow {
return state.Rows[y] return state.Rows[y]
} }
func (state *GameState) Set(x, y, value int) error { func (state *GameState) Set(x, y, value int) {
if x < 0 || y < 0 { cell := state.Get(x, y)
errMsg := fmt.Sprintf("coordinates (%v, %v) are out of bounds!", x, y) cell.Value = value
return errors.New(errMsg) }
}
func (state *GameState) Get(x, y int) *GameStateCell {
row := state.GetRow(y) row := state.GetRow(y)
lenCells := len(row.Cells)
if x+1 > len(row.Cells) { if x+1 > lenCells {
errMsg := fmt.Sprintf("x coordinate %v is out of bounds!", x) return state.Get(x%lenCells, row.Y)
return errors.New(errMsg)
} }
row.Cells[x] = value return row.Cells[x]
return nil
} }
func (state *GameState) Get(x, y int) (int, error) { func (state *GameState) Enliven(x, y int) {
row := state.GetRow(y) state.Set(x, y, 1)
if len(row.Cells) < x+1 {
return -1, errors.New("x coordinate is out of bounds!")
}
return row.Cells[x], nil
} }
func (state *GameState) Enliven(x, y int) error { func (state *GameState) Deaden(x, y int) {
return state.Set(x, y, 1) state.Set(x, y, 0)
} }
func (state *GameState) Deaden(x, y int) error { func (state *GameState) Import(other *GameState) {
return state.Set(x, y, 0)
}
func (state *GameState) Import(other *GameState) (err error) {
for y, row := range other.Rows { for y, row := range other.Rows {
for x, cell := range row.Cells { for x, cell := range row.Cells {
if err = state.Set(x, y, cell); err != nil { state.Set(x, y, cell.Value)
return err
} }
} }
}
return nil
} }
func (state *GameState) Cells() (<-chan *GameStateCell, error) { func (state *GameState) Cells() (<-chan *GameStateCell, error) {
@ -113,19 +114,8 @@ func (state *GameState) Cells() (<-chan *GameStateCell, error) {
width := state.Width() width := state.Width()
for y := 0; y < height; y++ { for y := 0; y < height; y++ {
row := state.GetRow(y)
for x := 0; x < width; x++ { for x := 0; x < width; x++ {
value, err := state.Get(x, y) c <- state.Get(x, y)
if err != nil {
panic(err)
}
c <- &GameStateCell{
Value: value,
X: x,
Y: y,
cellmates: row.Cells,
}
} }
} }
}(state, cells) }(state, cells)
@ -133,18 +123,12 @@ func (state *GameState) Cells() (<-chan *GameStateCell, error) {
return (<-chan *GameStateCell)(cells), nil return (<-chan *GameStateCell)(cells), nil
} }
func (state *GameState) Mutate() error { func (state *GameState) Mutate() {
randX := rand.Intn(state.Width()) randX := rand.Intn(state.Width())
randY := rand.Intn(state.Height()) randY := rand.Intn(state.Height())
curVal, err := state.Get(randX, randY) cell := state.Get(randX, randY)
if err != nil { state.Set(randX, randY, int(math.Abs(float64(cell.Value-1))))
return err
}
err = state.Set(randX, randY, int(math.Abs(float64(curVal-1))))
return nil
} }
func (state *GameState) Checksum() (string, error) { func (state *GameState) Checksum() (string, error) {
@ -171,12 +155,8 @@ func (state *GameState) String() string {
for x := 0; x < width; x++ { for x := 0; x < width; x++ {
stringVal := DEAD_CELL stringVal := DEAD_CELL
value, err := state.Get(x, y) cell := state.Get(x, y)
if err != nil { if cell.Value == 1 {
return ""
}
if value == 1 {
stringVal = LIVE_CELL stringVal = LIVE_CELL
} }
cells = append(cells, stringVal) cells = append(cells, stringVal)

View File

@ -1,12 +0,0 @@
package conway
type GameStateCell struct {
Value int
X int
Y int
cellmates []int
}
func (cell *GameStateCell) SetValue(value int) {
cell.cellmates[cell.X] = value
}

View File

@ -1,21 +0,0 @@
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,
}
}

View File

@ -27,7 +27,11 @@ func NewGenerationScoreCard(height, width int) *GenerationScoreCard {
for i := 0; i < height; i++ { for i := 0; i < height; i++ {
row := &GameStateRow{Y: i} row := &GameStateRow{Y: i}
for j := 0; j < width; j++ { for j := 0; j < width; j++ {
row.Cells = append(row.Cells, 0) row.Cells = append(row.Cells, &GameStateCell{
Value: 0,
X: j,
Y: i,
})
} }
genScore.Rows = append(genScore.Rows, row) genScore.Rows = append(genScore.Rows, row)
} }
@ -58,15 +62,8 @@ func (genScore *GenerationScoreCard) Calculate(state *GameState) error {
continue continue
} }
curScore, err := genScore.Get(xTarget, yTarget) cell := genScore.Get(xTarget, yTarget)
if err != nil { genScore.Set(xTarget, yTarget, cell.Value+1)
continue
}
err = genScore.Set(xTarget, yTarget, curScore+1)
if err != nil {
return err
}
} }
} }