2021-08-23 17:13:58 -07:00
|
|
|
package rules
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
2022-01-18 20:21:21 +00:00
|
|
|
"sort"
|
2021-08-23 17:13:58 -07:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
)
|
|
|
|
|
|
2022-06-22 16:14:15 -07:00
|
|
|
func TestDev1235(t *testing.T) {
|
|
|
|
|
// Small boards should no longer error and only get 1 food when num snakes > 4
|
|
|
|
|
state, err := CreateDefaultBoardState(MaxRand, BoardSizeSmall, BoardSizeSmall, []string{
|
|
|
|
|
"1", "2", "3", "4", "5", "6", "7", "8",
|
|
|
|
|
})
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Len(t, state.Food, 1)
|
|
|
|
|
state, err = CreateDefaultBoardState(MaxRand, BoardSizeSmall, BoardSizeSmall, []string{
|
|
|
|
|
"1", "2", "3", "4", "5",
|
|
|
|
|
})
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Len(t, state.Food, 1)
|
|
|
|
|
|
|
|
|
|
// Small boards with <= 4 snakes should still get more than just center food
|
|
|
|
|
state, err = CreateDefaultBoardState(MaxRand, BoardSizeSmall, BoardSizeSmall, []string{
|
|
|
|
|
"1", "2", "3", "4",
|
|
|
|
|
})
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Len(t, state.Food, 5)
|
|
|
|
|
|
|
|
|
|
// Medium boards should still get 9 food
|
|
|
|
|
state, err = CreateDefaultBoardState(MaxRand, BoardSizeMedium, BoardSizeMedium, []string{
|
|
|
|
|
"1", "2", "3", "4", "5", "6", "7", "8",
|
|
|
|
|
})
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Len(t, state.Food, 9)
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-18 20:51:01 +00:00
|
|
|
func sortPoints(p []Point) {
|
|
|
|
|
sort.Slice(p, func(i, j int) bool {
|
|
|
|
|
if p[i].X != p[j].X {
|
|
|
|
|
return p[i].X < p[j].X
|
|
|
|
|
}
|
|
|
|
|
return p[i].Y < p[j].Y
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-23 17:13:58 -07:00
|
|
|
func TestCreateDefaultBoardState(t *testing.T) {
|
|
|
|
|
tests := []struct {
|
2022-05-25 11:17:41 -07:00
|
|
|
Height int
|
|
|
|
|
Width int
|
2021-08-23 17:13:58 -07:00
|
|
|
IDs []string
|
|
|
|
|
ExpectedNumFood int
|
|
|
|
|
Err error
|
|
|
|
|
}{
|
2022-07-07 11:14:30 -07:00
|
|
|
{1, 1, []string{"one"}, 0, ErrorNoRoomForSnake},
|
|
|
|
|
{1, 2, []string{"one"}, 0, ErrorNoRoomForSnake},
|
2021-08-23 17:13:58 -07:00
|
|
|
{1, 4, []string{"one"}, 1, nil},
|
|
|
|
|
{2, 2, []string{"one"}, 1, nil},
|
|
|
|
|
{9, 8, []string{"one"}, 1, nil},
|
2022-07-07 11:14:30 -07:00
|
|
|
{2, 2, []string{"one", "two"}, 0, ErrorNoRoomForSnake},
|
2021-08-23 17:13:58 -07:00
|
|
|
{1, 1, []string{"one", "two"}, 2, ErrorNoRoomForSnake},
|
|
|
|
|
{1, 2, []string{"one", "two"}, 2, ErrorNoRoomForSnake},
|
|
|
|
|
{BoardSizeSmall, BoardSizeSmall, []string{"one", "two"}, 3, nil},
|
2022-07-07 11:14:30 -07:00
|
|
|
{
|
|
|
|
|
BoardSizeSmall,
|
|
|
|
|
BoardSizeSmall,
|
|
|
|
|
[]string{"1", "2", "3", "4"},
|
|
|
|
|
5, // <= 4 snakes on a small board we get more than just center food
|
|
|
|
|
nil,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
BoardSizeSmall,
|
|
|
|
|
BoardSizeSmall,
|
|
|
|
|
[]string{"1", "2", "3", "4", "5"},
|
|
|
|
|
1, // for this size and this many snakes, food is only placed in the center
|
|
|
|
|
nil,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
BoardSizeSmall,
|
|
|
|
|
BoardSizeSmall,
|
|
|
|
|
[]string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16"},
|
|
|
|
|
1, // for this size and this many snakes, food is only placed in the center
|
|
|
|
|
nil,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
BoardSizeMedium,
|
|
|
|
|
BoardSizeMedium,
|
|
|
|
|
[]string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16"},
|
|
|
|
|
17, // > small boards and we get non-center food
|
|
|
|
|
nil,
|
|
|
|
|
},
|
2021-08-23 17:13:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for testNum, test := range tests {
|
2022-07-07 11:14:30 -07:00
|
|
|
t.Logf("test case %d", testNum)
|
2022-05-11 08:26:28 -07:00
|
|
|
state, err := CreateDefaultBoardState(MaxRand, test.Width, test.Height, test.IDs)
|
2021-08-23 17:13:58 -07:00
|
|
|
require.Equal(t, test.Err, err)
|
|
|
|
|
if err != nil {
|
|
|
|
|
require.Nil(t, state)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
require.NotNil(t, state)
|
|
|
|
|
require.Equal(t, test.Width, state.Width)
|
|
|
|
|
require.Equal(t, test.Height, state.Height)
|
|
|
|
|
require.Equal(t, len(test.IDs), len(state.Snakes))
|
|
|
|
|
for i, id := range test.IDs {
|
|
|
|
|
require.Equal(t, id, state.Snakes[i].ID)
|
|
|
|
|
}
|
|
|
|
|
require.Len(t, state.Food, test.ExpectedNumFood, testNum)
|
|
|
|
|
require.Len(t, state.Hazards, 0, testNum)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPlaceSnakesDefault(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
|
2022-07-07 11:14:30 -07:00
|
|
|
// Update: because we exclude the center point now, we can accommodate 1 less snake now (width*height/2 - 1)
|
2021-08-23 17:13:58 -07:00
|
|
|
tests := []struct {
|
|
|
|
|
BoardState *BoardState
|
|
|
|
|
SnakeIDs []string
|
|
|
|
|
Err error
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: 1,
|
|
|
|
|
Height: 1,
|
|
|
|
|
},
|
|
|
|
|
make([]string, 1),
|
2022-07-07 11:14:30 -07:00
|
|
|
ErrorNoRoomForSnake, // we avoid placing snakes in the center, so a board size of 1 will error
|
2021-08-23 17:13:58 -07:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: 1,
|
|
|
|
|
Height: 1,
|
|
|
|
|
},
|
|
|
|
|
make([]string, 2),
|
|
|
|
|
ErrorNoRoomForSnake,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: 2,
|
|
|
|
|
Height: 1,
|
|
|
|
|
},
|
|
|
|
|
make([]string, 2),
|
|
|
|
|
ErrorNoRoomForSnake,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: 1,
|
|
|
|
|
Height: 2,
|
|
|
|
|
},
|
|
|
|
|
make([]string, 2),
|
|
|
|
|
ErrorNoRoomForSnake,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: 10,
|
|
|
|
|
Height: 5,
|
|
|
|
|
},
|
|
|
|
|
make([]string, 24),
|
|
|
|
|
nil,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: 5,
|
|
|
|
|
Height: 10,
|
|
|
|
|
},
|
2022-07-07 11:14:30 -07:00
|
|
|
make([]string, 24),
|
2021-08-23 17:13:58 -07:00
|
|
|
nil,
|
|
|
|
|
},
|
2022-07-07 11:14:30 -07:00
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: 5,
|
|
|
|
|
Height: 10,
|
|
|
|
|
},
|
|
|
|
|
make([]string, 25),
|
|
|
|
|
ErrorNoRoomForSnake,
|
|
|
|
|
},
|
2021-08-23 17:13:58 -07:00
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: 10,
|
|
|
|
|
Height: 5,
|
|
|
|
|
},
|
|
|
|
|
make([]string, 49),
|
|
|
|
|
ErrorNoRoomForSnake,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: 5,
|
|
|
|
|
Height: 10,
|
|
|
|
|
},
|
|
|
|
|
make([]string, 50),
|
|
|
|
|
ErrorNoRoomForSnake,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: 25,
|
|
|
|
|
Height: 2,
|
|
|
|
|
},
|
|
|
|
|
make([]string, 51),
|
|
|
|
|
ErrorNoRoomForSnake,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: BoardSizeSmall,
|
|
|
|
|
Height: BoardSizeSmall,
|
|
|
|
|
},
|
|
|
|
|
make([]string, 1),
|
|
|
|
|
nil,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: BoardSizeSmall,
|
|
|
|
|
Height: BoardSizeSmall,
|
|
|
|
|
},
|
|
|
|
|
make([]string, 8),
|
|
|
|
|
nil,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: BoardSizeMedium,
|
|
|
|
|
Height: BoardSizeMedium,
|
|
|
|
|
},
|
|
|
|
|
make([]string, 8),
|
|
|
|
|
nil,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: BoardSizeMedium,
|
|
|
|
|
Height: BoardSizeMedium,
|
|
|
|
|
},
|
2022-07-07 11:14:30 -07:00
|
|
|
make([]string, 17),
|
2021-08-23 17:13:58 -07:00
|
|
|
ErrorTooManySnakes,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: BoardSizeLarge,
|
|
|
|
|
Height: BoardSizeLarge,
|
|
|
|
|
},
|
|
|
|
|
make([]string, 8),
|
|
|
|
|
nil,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: BoardSizeLarge,
|
|
|
|
|
Height: BoardSizeLarge,
|
|
|
|
|
},
|
2022-07-07 11:14:30 -07:00
|
|
|
make([]string, 17),
|
2021-08-23 17:13:58 -07:00
|
|
|
ErrorTooManySnakes,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
|
t.Run(fmt.Sprint(test.BoardState.Width, test.BoardState.Height, len(test.SnakeIDs)), func(t *testing.T) {
|
2022-08-19 10:09:04 -07:00
|
|
|
require.Equal(t, test.BoardState.Width*test.BoardState.Height, len(GetUnoccupiedPoints(test.BoardState, true, false)))
|
2022-05-11 08:26:28 -07:00
|
|
|
err := PlaceSnakesAutomatically(MaxRand, test.BoardState, test.SnakeIDs)
|
2021-08-23 17:13:58 -07:00
|
|
|
require.Equal(t, test.Err, err, "Snakes: %d", len(test.BoardState.Snakes))
|
|
|
|
|
if err == nil {
|
|
|
|
|
for i := 0; i < len(test.BoardState.Snakes); i++ {
|
|
|
|
|
require.Len(t, test.BoardState.Snakes[i].Body, 3)
|
|
|
|
|
for _, point := range test.BoardState.Snakes[i].Body {
|
2022-05-25 11:17:41 -07:00
|
|
|
require.GreaterOrEqual(t, point.X, 0)
|
|
|
|
|
require.GreaterOrEqual(t, point.Y, 0)
|
2021-08-23 17:13:58 -07:00
|
|
|
require.Less(t, point.X, test.BoardState.Width)
|
|
|
|
|
require.Less(t, point.Y, test.BoardState.Height)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for j := 0; j < len(test.BoardState.Snakes); j++ {
|
|
|
|
|
if j == i {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
require.NotEqual(t, test.BoardState.Snakes[j].Body[0], test.BoardState.Snakes[i].Body[0], "Snakes placed at same square")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-17 15:45:56 -07:00
|
|
|
func TestPlaceSnakesFixed(t *testing.T) {
|
|
|
|
|
snakeIDs := make([]string, 8)
|
|
|
|
|
|
|
|
|
|
for _, test := range []struct {
|
|
|
|
|
label string
|
|
|
|
|
rand Rand
|
|
|
|
|
expectedSnakeHeads []Point
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
label: "corners before cardinal directions",
|
|
|
|
|
rand: MinRand,
|
|
|
|
|
expectedSnakeHeads: []Point{
|
|
|
|
|
{X: 1, Y: 1},
|
|
|
|
|
{X: 1, Y: 9},
|
|
|
|
|
{X: 9, Y: 1},
|
|
|
|
|
{X: 9, Y: 9},
|
|
|
|
|
|
|
|
|
|
{X: 1, Y: 5},
|
|
|
|
|
{X: 5, Y: 1},
|
|
|
|
|
{X: 5, Y: 9},
|
|
|
|
|
{X: 9, Y: 5},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: "cardinal directions before corners",
|
|
|
|
|
rand: MaxRand,
|
|
|
|
|
expectedSnakeHeads: []Point{
|
|
|
|
|
{X: 5, Y: 1},
|
|
|
|
|
{X: 5, Y: 9},
|
|
|
|
|
{X: 9, Y: 5},
|
|
|
|
|
{X: 1, Y: 5},
|
|
|
|
|
|
|
|
|
|
{X: 1, Y: 9},
|
|
|
|
|
{X: 9, Y: 1},
|
|
|
|
|
{X: 9, Y: 9},
|
|
|
|
|
{X: 1, Y: 1},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
} {
|
|
|
|
|
t.Run(test.label, func(t *testing.T) {
|
|
|
|
|
boardState := &BoardState{
|
|
|
|
|
Width: BoardSizeMedium,
|
|
|
|
|
Height: BoardSizeMedium,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := PlaceSnakesAutomatically(test.rand, boardState, snakeIDs)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
var snakeHeads []Point
|
|
|
|
|
for _, snake := range boardState.Snakes {
|
|
|
|
|
require.Len(t, snake.Body, 3)
|
|
|
|
|
snakeHeads = append(snakeHeads, snake.Body[0])
|
|
|
|
|
}
|
|
|
|
|
require.Equalf(t, test.expectedSnakeHeads, snakeHeads, "%#v", snakeHeads)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-23 17:13:58 -07:00
|
|
|
func TestPlaceSnake(t *testing.T) {
|
|
|
|
|
// TODO: Should PlaceSnake check for boundaries?
|
|
|
|
|
boardState := NewBoardState(BoardSizeSmall, BoardSizeSmall)
|
|
|
|
|
require.Empty(t, boardState.Snakes)
|
|
|
|
|
|
|
|
|
|
_ = PlaceSnake(boardState, "a", []Point{{0, 0}, {1, 0}, {1, 1}})
|
|
|
|
|
|
|
|
|
|
require.Len(t, boardState.Snakes, 1)
|
|
|
|
|
require.Equal(t, Snake{
|
|
|
|
|
ID: "a",
|
|
|
|
|
Body: []Point{{0, 0}, {1, 0}, {1, 1}},
|
|
|
|
|
Health: SnakeMaxHealth,
|
|
|
|
|
EliminatedCause: NotEliminated,
|
|
|
|
|
EliminatedBy: "",
|
|
|
|
|
}, boardState.Snakes[0])
|
|
|
|
|
|
|
|
|
|
_ = PlaceSnake(boardState, "b", []Point{{0, 2}, {1, 2}, {3, 2}})
|
|
|
|
|
|
|
|
|
|
require.Len(t, boardState.Snakes, 2)
|
|
|
|
|
require.Equal(t, Snake{
|
|
|
|
|
ID: "b",
|
|
|
|
|
Body: []Point{{0, 2}, {1, 2}, {3, 2}},
|
|
|
|
|
Health: SnakeMaxHealth,
|
|
|
|
|
EliminatedCause: NotEliminated,
|
|
|
|
|
EliminatedBy: "",
|
|
|
|
|
}, boardState.Snakes[1])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPlaceFood(t *testing.T) {
|
|
|
|
|
tests := []struct {
|
|
|
|
|
BoardState *BoardState
|
|
|
|
|
ExpectedFood int
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: 1,
|
|
|
|
|
Height: 1,
|
|
|
|
|
Snakes: make([]Snake, 1),
|
|
|
|
|
},
|
|
|
|
|
1,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: 1,
|
|
|
|
|
Height: 2,
|
|
|
|
|
Snakes: make([]Snake, 2),
|
|
|
|
|
},
|
|
|
|
|
2,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: 101,
|
|
|
|
|
Height: 202,
|
|
|
|
|
Snakes: make([]Snake, 17),
|
|
|
|
|
},
|
|
|
|
|
17,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: 10,
|
|
|
|
|
Height: 20,
|
|
|
|
|
Snakes: make([]Snake, 305),
|
|
|
|
|
},
|
|
|
|
|
200,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: BoardSizeSmall,
|
|
|
|
|
Height: BoardSizeSmall,
|
|
|
|
|
Snakes: []Snake{
|
|
|
|
|
{Body: []Point{{5, 1}}},
|
|
|
|
|
{Body: []Point{{5, 3}}},
|
|
|
|
|
{Body: []Point{{5, 5}}},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
4, // +1 because of fixed spawn locations
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: BoardSizeMedium,
|
|
|
|
|
Height: BoardSizeMedium,
|
|
|
|
|
Snakes: []Snake{
|
|
|
|
|
{Body: []Point{{1, 1}}},
|
|
|
|
|
{Body: []Point{{1, 5}}},
|
|
|
|
|
{Body: []Point{{1, 9}}},
|
|
|
|
|
{Body: []Point{{5, 1}}},
|
|
|
|
|
{Body: []Point{{5, 9}}},
|
|
|
|
|
{Body: []Point{{9, 1}}},
|
|
|
|
|
{Body: []Point{{9, 5}}},
|
|
|
|
|
{Body: []Point{{9, 9}}},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
9, // +1 because of fixed spawn locations
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: BoardSizeLarge,
|
|
|
|
|
Height: BoardSizeLarge,
|
|
|
|
|
Snakes: []Snake{
|
|
|
|
|
{Body: []Point{{1, 1}}},
|
|
|
|
|
{Body: []Point{{1, 9}}},
|
|
|
|
|
{Body: []Point{{1, 17}}},
|
|
|
|
|
{Body: []Point{{17, 1}}},
|
|
|
|
|
{Body: []Point{{17, 9}}},
|
|
|
|
|
{Body: []Point{{17, 17}}},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
7, // +1 because of fixed spawn locations
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-07 11:14:30 -07:00
|
|
|
for i, test := range tests {
|
|
|
|
|
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
|
|
|
|
|
|
|
|
|
|
require.Len(t, test.BoardState.Food, 0)
|
|
|
|
|
err := PlaceFoodAutomatically(MaxRand, test.BoardState)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, test.ExpectedFood, len(test.BoardState.Food))
|
|
|
|
|
for _, point := range test.BoardState.Food {
|
|
|
|
|
require.GreaterOrEqual(t, point.X, 0)
|
|
|
|
|
require.GreaterOrEqual(t, point.Y, 0)
|
|
|
|
|
require.Less(t, point.X, test.BoardState.Width)
|
|
|
|
|
require.Less(t, point.Y, test.BoardState.Height)
|
|
|
|
|
}
|
|
|
|
|
})
|
2021-08-23 17:13:58 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPlaceFoodFixed(t *testing.T) {
|
|
|
|
|
tests := []struct {
|
|
|
|
|
BoardState *BoardState
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: BoardSizeSmall,
|
|
|
|
|
Height: BoardSizeSmall,
|
|
|
|
|
Snakes: []Snake{
|
|
|
|
|
{Body: []Point{{1, 3}}},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: BoardSizeMedium,
|
|
|
|
|
Height: BoardSizeMedium,
|
|
|
|
|
Snakes: []Snake{
|
|
|
|
|
{Body: []Point{{1, 1}}},
|
|
|
|
|
{Body: []Point{{1, 5}}},
|
|
|
|
|
{Body: []Point{{9, 5}}},
|
|
|
|
|
{Body: []Point{{9, 9}}},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Width: BoardSizeLarge,
|
|
|
|
|
Height: BoardSizeLarge,
|
|
|
|
|
Snakes: []Snake{
|
|
|
|
|
{Body: []Point{{1, 1}}},
|
|
|
|
|
{Body: []Point{{1, 9}}},
|
|
|
|
|
{Body: []Point{{1, 17}}},
|
|
|
|
|
{Body: []Point{{9, 1}}},
|
|
|
|
|
{Body: []Point{{9, 17}}},
|
|
|
|
|
{Body: []Point{{17, 1}}},
|
|
|
|
|
{Body: []Point{{17, 9}}},
|
|
|
|
|
{Body: []Point{{17, 17}}},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
|
require.Len(t, test.BoardState.Food, 0)
|
|
|
|
|
|
2022-05-11 08:26:28 -07:00
|
|
|
err := PlaceFoodFixed(MaxRand, test.BoardState)
|
2021-08-23 17:13:58 -07:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, len(test.BoardState.Snakes)+1, len(test.BoardState.Food))
|
|
|
|
|
|
2022-01-18 20:21:21 +00:00
|
|
|
midPoint := Point{(test.BoardState.Width - 1) / 2, (test.BoardState.Height - 1) / 2}
|
|
|
|
|
|
2021-08-23 17:13:58 -07:00
|
|
|
// Make sure every snake has food within 2 moves of it
|
|
|
|
|
for _, snake := range test.BoardState.Snakes {
|
|
|
|
|
head := snake.Body[0]
|
|
|
|
|
|
|
|
|
|
bottomLeft := Point{head.X - 1, head.Y - 1}
|
|
|
|
|
topLeft := Point{head.X - 1, head.Y + 1}
|
|
|
|
|
bottomRight := Point{head.X + 1, head.Y - 1}
|
|
|
|
|
topRight := Point{head.X + 1, head.Y + 1}
|
|
|
|
|
|
|
|
|
|
foundFoodInTwoMoves := false
|
|
|
|
|
for _, food := range test.BoardState.Food {
|
|
|
|
|
if food == bottomLeft || food == topLeft || food == bottomRight || food == topRight {
|
|
|
|
|
foundFoodInTwoMoves = true
|
2022-01-18 20:21:21 +00:00
|
|
|
// Ensure it's not closer to the center than snake
|
|
|
|
|
require.True(t, getDistanceBetweenPoints(head, midPoint) <= getDistanceBetweenPoints(food, midPoint))
|
2021-08-23 17:13:58 -07:00
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
require.True(t, foundFoodInTwoMoves)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Make sure one food exists in center of board
|
|
|
|
|
foundFoodInCenter := false
|
|
|
|
|
for _, food := range test.BoardState.Food {
|
|
|
|
|
if food == midPoint {
|
|
|
|
|
foundFoodInCenter = true
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
require.True(t, foundFoodInCenter)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPlaceFoodFixedNoRoom(t *testing.T) {
|
|
|
|
|
boardState := &BoardState{
|
|
|
|
|
Width: 3,
|
|
|
|
|
Height: 3,
|
|
|
|
|
Snakes: []Snake{
|
|
|
|
|
{Body: []Point{{1, 1}}},
|
|
|
|
|
},
|
|
|
|
|
Food: []Point{},
|
|
|
|
|
}
|
2022-05-11 08:26:28 -07:00
|
|
|
err := PlaceFoodFixed(MaxRand, boardState)
|
2021-08-23 17:13:58 -07:00
|
|
|
require.Error(t, err)
|
2022-01-18 20:51:01 +00:00
|
|
|
}
|
2021-08-23 17:13:58 -07:00
|
|
|
|
2022-01-18 20:51:01 +00:00
|
|
|
func TestPlaceFoodFixedNoRoom_Corners(t *testing.T) {
|
|
|
|
|
boardState := &BoardState{
|
2021-08-23 17:13:58 -07:00
|
|
|
Width: 7,
|
|
|
|
|
Height: 7,
|
|
|
|
|
Snakes: []Snake{
|
|
|
|
|
{Body: []Point{{1, 1}}},
|
2022-01-18 20:51:01 +00:00
|
|
|
{Body: []Point{{1, 5}}},
|
|
|
|
|
{Body: []Point{{5, 1}}},
|
|
|
|
|
{Body: []Point{{5, 5}}},
|
2021-08-23 17:13:58 -07:00
|
|
|
},
|
|
|
|
|
Food: []Point{},
|
|
|
|
|
}
|
2022-01-18 20:21:21 +00:00
|
|
|
|
2022-04-07 07:59:21 -07:00
|
|
|
// There are only two possible food spawn locations for each snake,
|
|
|
|
|
// so repeat calls to place food should fail after 2 successes
|
2022-05-11 08:26:28 -07:00
|
|
|
err := PlaceFoodFixed(MaxRand, boardState)
|
2022-01-18 20:51:01 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
boardState.Food = boardState.Food[:len(boardState.Food)-1] // Center food
|
|
|
|
|
require.Equal(t, 4, len(boardState.Food))
|
|
|
|
|
|
2022-05-11 08:26:28 -07:00
|
|
|
err = PlaceFoodFixed(MaxRand, boardState)
|
2021-08-23 17:13:58 -07:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
boardState.Food = boardState.Food[:len(boardState.Food)-1] // Center food
|
2022-01-18 20:51:01 +00:00
|
|
|
require.Equal(t, 8, len(boardState.Food))
|
2021-08-23 17:13:58 -07:00
|
|
|
|
2022-01-18 20:51:01 +00:00
|
|
|
// And now there should be no more room.
|
2022-05-11 08:26:28 -07:00
|
|
|
err = PlaceFoodFixed(MaxRand, boardState)
|
2022-01-18 20:51:01 +00:00
|
|
|
require.Error(t, err)
|
|
|
|
|
|
|
|
|
|
expectedFood := []Point{
|
2022-04-07 07:59:21 -07:00
|
|
|
{0, 2}, {2, 0}, // Snake @ {1, 1}
|
|
|
|
|
{0, 4}, {2, 6}, // Snake @ {1, 5}
|
|
|
|
|
{4, 0}, {6, 2}, // Snake @ {5, 1}
|
|
|
|
|
{4, 6}, {6, 4}, // Snake @ {5, 5}
|
2022-01-18 20:51:01 +00:00
|
|
|
}
|
|
|
|
|
sortPoints(expectedFood)
|
|
|
|
|
sortPoints(boardState.Food)
|
|
|
|
|
require.Equal(t, expectedFood, boardState.Food)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPlaceFoodFixedNoRoom_Cardinal(t *testing.T) {
|
|
|
|
|
boardState := &BoardState{
|
|
|
|
|
Width: 11,
|
|
|
|
|
Height: 11,
|
|
|
|
|
Snakes: []Snake{
|
|
|
|
|
{Body: []Point{{1, 5}}},
|
|
|
|
|
{Body: []Point{{5, 1}}},
|
|
|
|
|
{Body: []Point{{5, 9}}},
|
|
|
|
|
{Body: []Point{{9, 5}}},
|
|
|
|
|
},
|
|
|
|
|
Food: []Point{},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// There are only two possible spawn locations for each snake,
|
|
|
|
|
// so repeat calls to place food should fail after 2 successes
|
2022-05-11 08:26:28 -07:00
|
|
|
err := PlaceFoodFixed(MaxRand, boardState)
|
2021-08-23 17:13:58 -07:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
boardState.Food = boardState.Food[:len(boardState.Food)-1] // Center food
|
2022-01-18 20:51:01 +00:00
|
|
|
require.Equal(t, 4, len(boardState.Food))
|
|
|
|
|
|
2022-05-11 08:26:28 -07:00
|
|
|
err = PlaceFoodFixed(MaxRand, boardState)
|
2022-01-18 20:51:01 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
boardState.Food = boardState.Food[:len(boardState.Food)-1] // Center food
|
|
|
|
|
require.Equal(t, 8, len(boardState.Food))
|
2021-08-23 17:13:58 -07:00
|
|
|
|
|
|
|
|
// And now there should be no more room.
|
2022-05-11 08:26:28 -07:00
|
|
|
err = PlaceFoodFixed(MaxRand, boardState)
|
2021-08-23 17:13:58 -07:00
|
|
|
require.Error(t, err)
|
2022-01-18 20:21:21 +00:00
|
|
|
|
2022-01-18 20:51:01 +00:00
|
|
|
expectedFood := []Point{
|
|
|
|
|
{0, 4}, {0, 6}, // Snake @ {1, 5}
|
|
|
|
|
{4, 0}, {6, 0}, // Snake @ {5, 1}
|
|
|
|
|
{4, 10}, {6, 10}, // Snake @ {5, 9}
|
|
|
|
|
{10, 4}, {10, 6}, // Snake @ {9, 5}
|
|
|
|
|
}
|
|
|
|
|
sortPoints(expectedFood)
|
|
|
|
|
sortPoints(boardState.Food)
|
2022-01-18 20:21:21 +00:00
|
|
|
require.Equal(t, expectedFood, boardState.Food)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestGetDistanceBetweenPoints(t *testing.T) {
|
|
|
|
|
tests := []struct {
|
|
|
|
|
A Point
|
|
|
|
|
B Point
|
2022-05-25 11:17:41 -07:00
|
|
|
Expected int
|
2022-01-18 20:21:21 +00:00
|
|
|
}{
|
|
|
|
|
{Point{0, 0}, Point{0, 0}, 0},
|
|
|
|
|
{Point{0, 0}, Point{1, 0}, 1},
|
|
|
|
|
{Point{0, 0}, Point{0, 1}, 1},
|
|
|
|
|
{Point{0, 0}, Point{1, 1}, 2},
|
|
|
|
|
{Point{0, 0}, Point{4, 4}, 8},
|
|
|
|
|
{Point{0, 0}, Point{4, 6}, 10},
|
|
|
|
|
{Point{8, 0}, Point{8, 0}, 0},
|
|
|
|
|
{Point{8, 0}, Point{8, 8}, 8},
|
|
|
|
|
{Point{8, 0}, Point{0, 8}, 16},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
|
require.Equal(t, getDistanceBetweenPoints(test.A, test.B), test.Expected)
|
|
|
|
|
require.Equal(t, getDistanceBetweenPoints(test.B, test.A), test.Expected)
|
|
|
|
|
}
|
2021-08-23 17:13:58 -07:00
|
|
|
}
|
|
|
|
|
|
2022-07-07 11:14:30 -07:00
|
|
|
func TestIsSquareBoard(t *testing.T) {
|
2021-08-23 17:13:58 -07:00
|
|
|
tests := []struct {
|
2022-05-25 11:17:41 -07:00
|
|
|
Width int
|
|
|
|
|
Height int
|
2021-08-23 17:13:58 -07:00
|
|
|
Expected bool
|
|
|
|
|
}{
|
2022-07-07 11:14:30 -07:00
|
|
|
{1, 1, true},
|
|
|
|
|
{0, 0, true},
|
2021-08-23 17:13:58 -07:00
|
|
|
{0, 45, false},
|
|
|
|
|
{45, 1, false},
|
|
|
|
|
{7, 7, true},
|
|
|
|
|
{11, 11, true},
|
|
|
|
|
{19, 19, true},
|
|
|
|
|
{7, 11, false},
|
|
|
|
|
{11, 19, false},
|
|
|
|
|
{19, 7, false},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, test := range tests {
|
2022-07-07 11:14:30 -07:00
|
|
|
result := isSquareBoard(&BoardState{Width: test.Width, Height: test.Height})
|
2021-08-23 17:13:58 -07:00
|
|
|
require.Equal(t, test.Expected, result)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestGetUnoccupiedPoints(t *testing.T) {
|
|
|
|
|
tests := []struct {
|
|
|
|
|
Board *BoardState
|
|
|
|
|
Expected []Point
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Height: 1,
|
|
|
|
|
Width: 1,
|
|
|
|
|
},
|
|
|
|
|
[]Point{{0, 0}},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Height: 1,
|
|
|
|
|
Width: 2,
|
|
|
|
|
},
|
|
|
|
|
[]Point{{0, 0}, {1, 0}},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&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{{0, 1}, {1, 1}},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Height: 2,
|
|
|
|
|
Width: 2,
|
|
|
|
|
Food: []Point{{0, 0}, {0, 1}, {1, 0}, {1, 1}},
|
|
|
|
|
},
|
|
|
|
|
[]Point{},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Height: 4,
|
|
|
|
|
Width: 1,
|
|
|
|
|
Snakes: []Snake{
|
|
|
|
|
{Body: []Point{{0, 0}}},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
[]Point{{0, 1}, {0, 2}, {0, 3}},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Height: 2,
|
|
|
|
|
Width: 3,
|
|
|
|
|
Snakes: []Snake{
|
|
|
|
|
{Body: []Point{{0, 0}, {1, 0}, {1, 1}}},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
[]Point{{0, 1}, {2, 0}, {2, 1}},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Height: 2,
|
|
|
|
|
Width: 3,
|
|
|
|
|
Food: []Point{{0, 0}, {1, 0}, {1, 1}, {2, 0}},
|
|
|
|
|
Snakes: []Snake{
|
|
|
|
|
{Body: []Point{{0, 0}, {1, 0}, {1, 1}}},
|
|
|
|
|
{Body: []Point{{0, 1}}},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
[]Point{{2, 1}},
|
|
|
|
|
},
|
2022-08-19 10:09:04 -07:00
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Height: 1,
|
|
|
|
|
Width: 1,
|
|
|
|
|
Hazards: []Point{{0, 0}},
|
|
|
|
|
},
|
|
|
|
|
[]Point{},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Height: 2,
|
|
|
|
|
Width: 2,
|
|
|
|
|
Hazards: []Point{{1, 1}},
|
|
|
|
|
},
|
|
|
|
|
[]Point{{0, 0}, {0, 1}, {1, 0}},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
&BoardState{
|
|
|
|
|
Height: 2,
|
|
|
|
|
Width: 3,
|
|
|
|
|
Food: []Point{{1, 1}, {2, 0}},
|
|
|
|
|
Snakes: []Snake{
|
|
|
|
|
{Body: []Point{{0, 0}, {1, 0}, {1, 1}}},
|
|
|
|
|
{Body: []Point{{0, 1}}},
|
|
|
|
|
},
|
|
|
|
|
Hazards: []Point{{0, 0}, {1, 0}},
|
|
|
|
|
},
|
|
|
|
|
[]Point{{2, 1}},
|
|
|
|
|
},
|
2021-08-23 17:13:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, test := range tests {
|
2022-08-19 10:09:04 -07:00
|
|
|
unoccupiedPoints := GetUnoccupiedPoints(test.Board, true, true)
|
2021-08-23 17:13:58 -07:00
|
|
|
require.Equal(t, len(test.Expected), len(unoccupiedPoints))
|
|
|
|
|
for i, e := range test.Expected {
|
|
|
|
|
require.Equal(t, e, unoccupiedPoints[i])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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}},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-07 11:14:30 -07:00
|
|
|
for i, test := range tests {
|
|
|
|
|
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
|
|
|
|
|
evenUnoccupiedPoints := GetEvenUnoccupiedPoints(test.Board)
|
|
|
|
|
require.Equal(t, len(test.Expected), len(evenUnoccupiedPoints))
|
|
|
|
|
for i, e := range test.Expected {
|
|
|
|
|
require.Equal(t, e, evenUnoccupiedPoints[i])
|
|
|
|
|
}
|
|
|
|
|
})
|
2021-08-23 17:13:58 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestPlaceFoodRandomly(t *testing.T) {
|
|
|
|
|
b := &BoardState{
|
|
|
|
|
Height: 1,
|
|
|
|
|
Width: 3,
|
|
|
|
|
Snakes: []Snake{
|
|
|
|
|
{Body: []Point{{1, 0}}},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
// Food should never spawn, no room
|
2022-05-11 08:26:28 -07:00
|
|
|
err := PlaceFoodRandomly(MaxRand, b, 99)
|
2021-08-23 17:13:58 -07:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, len(b.Food), 0)
|
|
|
|
|
}
|
2022-07-21 14:26:56 -07:00
|
|
|
|
|
|
|
|
func TestEliminateSnake(t *testing.T) {
|
|
|
|
|
s := &Snake{}
|
|
|
|
|
EliminateSnake(s, "test-cause", "", 2)
|
|
|
|
|
require.Equal(t, "test-cause", s.EliminatedCause)
|
|
|
|
|
require.Equal(t, "", s.EliminatedBy)
|
|
|
|
|
require.Equal(t, 2, s.EliminatedOnTurn)
|
|
|
|
|
}
|