Made snakes spawn on odd or even diagonal points (#14). Fixes #12.

Randomly placed snakes will now always spawn on "even" squares.
This commit is contained in:
sjbcastro 2020-05-26 23:07:43 +01:00 committed by GitHub
parent 68043109a5
commit 2d62a58c9b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 143 additions and 5 deletions

View file

@ -99,10 +99,8 @@ func (r *StandardRuleset) placeSnakesFixed(b *BoardState) error {
func (r *StandardRuleset) placeSnakesRandomly(b *BoardState) error {
// TODO: Always place on all black or all white squares
for i := 0; i < len(b.Snakes); i++ {
unoccupiedPoints := r.getUnoccupiedPoints(b)
unoccupiedPoints := r.getEvenUnoccupiedPoints(b)
if len(unoccupiedPoints) <= 0 {
return errors.New("not enough space to place snake")
}
@ -440,6 +438,21 @@ func (r *StandardRuleset) getUnoccupiedPoints(b *BoardState) []Point {
return unoccupiedPoints
}
func (r *StandardRuleset) getEvenUnoccupiedPoints(b *BoardState) []Point {
// Start by getting unoccupied points
unoccupiedPoints := r.getUnoccupiedPoints(b)
// Create a new array to hold points that are even
evenUnoccupiedPoints := []Point{}
for _, point := range unoccupiedPoints {
if ((point.X + point.Y) % 2) == 0 {
evenUnoccupiedPoints = append(evenUnoccupiedPoints, point)
}
}
return evenUnoccupiedPoints
}
func (r *StandardRuleset) IsGameOver(b *BoardState) (bool, error) {
numSnakesRemaining := 0
for i := 0; i < len(b.Snakes); i++ {

View file

@ -49,6 +49,7 @@ func TestCreateInitialBoardState(t *testing.T) {
{2, 2, []string{"one", "two"}, 2, nil},
{2, 2, []string{"one", "two"}, 2, nil},
{1, 1, []string{"one", "two"}, 2, errors.New("not enough space to place snake")},
{1, 2, []string{"one", "two"}, 2, errors.New("not enough space to place snake")},
}
r := StandardRuleset{}
@ -73,6 +74,7 @@ func TestCreateInitialBoardState(t *testing.T) {
func TestPlaceSnakes(t *testing.T) {
// Because placement is random, we only test to ensure
// that snake bodies are populated correctly
// Note: because snakes are randomly spawned on even diagonal points, the board can accomodate number of snakes equal to: width*height/2
tests := []struct {
BoardState *BoardState
Err error
@ -93,11 +95,27 @@ func TestPlaceSnakes(t *testing.T) {
},
errors.New("not enough space to place snake"),
},
{
&BoardState{
Width: 2,
Height: 1,
Snakes: make([]Snake, 2),
},
errors.New("not enough space to place snake"),
},
{
&BoardState{
Width: 1,
Height: 2,
Snakes: make([]Snake, 2),
},
errors.New("not enough space to place snake"),
},
{
&BoardState{
Width: 10,
Height: 5,
Snakes: make([]Snake, 49),
Snakes: make([]Snake, 24),
},
nil,
},
@ -105,10 +123,26 @@ func TestPlaceSnakes(t *testing.T) {
&BoardState{
Width: 5,
Height: 10,
Snakes: make([]Snake, 50),
Snakes: make([]Snake, 25),
},
nil,
},
{
&BoardState{
Width: 10,
Height: 5,
Snakes: make([]Snake, 49),
},
errors.New("not enough space to place snake"),
},
{
&BoardState{
Width: 5,
Height: 10,
Snakes: make([]Snake, 50),
},
errors.New("not enough space to place snake"),
},
{
&BoardState{
Width: 25,
@ -189,6 +223,10 @@ func TestPlaceSnakes(t *testing.T) {
require.Less(t, point.X, test.BoardState.Width)
require.Less(t, point.Y, test.BoardState.Height)
}
// All snakes are expected to be placed on an even square - this is true even of fixed positions for known board sizes
var snakePlacedOnEvenSquare bool = ((test.BoardState.Snakes[i].Body[0].X + test.BoardState.Snakes[i].Body[0].Y) % 2) == 0
require.Equal(t, true, snakePlacedOnEvenSquare)
}
}
}
@ -1123,6 +1161,93 @@ func TestGetUnoccupiedPoints(t *testing.T) {
}
}
func TestGetEvenUnoccupiedPoints(t *testing.T) {
tests := []struct {
Board *BoardState
Expected []Point
}{
{
&BoardState{
Height: 1,
Width: 1,
},
[]Point{{0, 0}},
},
{
&BoardState{
Height: 2,
Width: 2,
},
[]Point{{0, 0}, {1, 1}},
},
{
&BoardState{
Height: 1,
Width: 1,
Food: []Point{{0, 0}, {101, 202}, {-4, -5}},
},
[]Point{},
},
{
&BoardState{
Height: 2,
Width: 2,
Food: []Point{{0, 0}, {1, 0}},
},
[]Point{{1, 1}},
},
{
&BoardState{
Height: 4,
Width: 4,
Food: []Point{{0, 0}, {0, 2}, {1, 1}, {1, 3}, {2, 0}, {2, 2}, {3, 1}, {3, 3}},
},
[]Point{},
},
{
&BoardState{
Height: 4,
Width: 1,
Snakes: []Snake{
{Body: []Point{{0, 0}}},
},
},
[]Point{{0, 2}},
},
{
&BoardState{
Height: 2,
Width: 3,
Snakes: []Snake{
{Body: []Point{{0, 0}, {1, 0}, {1, 1}}},
},
},
[]Point{{2, 0}},
},
{
&BoardState{
Height: 2,
Width: 3,
Food: []Point{{0, 0}, {1, 0}, {1, 1}, {2, 1}},
Snakes: []Snake{
{Body: []Point{{0, 0}, {1, 0}, {1, 1}}},
{Body: []Point{{0, 1}}},
},
},
[]Point{{2, 0}},
},
}
r := StandardRuleset{}
for _, test := range tests {
evenUnoccupiedPoints := r.getEvenUnoccupiedPoints(test.Board)
require.Equal(t, len(test.Expected), len(evenUnoccupiedPoints))
for i, e := range test.Expected {
require.Equal(t, e, evenUnoccupiedPoints[i])
}
}
}
func TestMaybeSpawnFood(t *testing.T) {
tests := []struct {
Seed int64