From e01a1bf50518b152810ac38068619f50856bf7ef Mon Sep 17 00:00:00 2001 From: Brad Van Vugt <1531419+bvanvugt@users.noreply.github.com> Date: Tue, 8 Dec 2020 13:20:13 -0800 Subject: [PATCH] "Feast" -> "Maze". Fix backfill bug. (#26) --- feast.go => maze.go | 8 ++-- feast_test.go => maze_test.go | 88 +++++++++++++++++++++++++++++++---- standard.go | 3 ++ 3 files changed, 86 insertions(+), 13 deletions(-) rename feast.go => maze.go (66%) rename feast_test.go => maze_test.go (54%) diff --git a/feast.go b/maze.go similarity index 66% rename from feast.go rename to maze.go index 0f916f3..33e0363 100644 --- a/feast.go +++ b/maze.go @@ -2,11 +2,11 @@ package rules import () -type FeastRuleset struct { +type MazeRuleset struct { StandardRuleset } -func (r *FeastRuleset) CreateInitialBoardState(width int32, height int32, snakeIDs []string) (*BoardState, error) { +func (r *MazeRuleset) CreateInitialBoardState(width int32, height int32, snakeIDs []string) (*BoardState, error) { initialBoardState, err := r.StandardRuleset.CreateInitialBoardState(width, height, snakeIDs) if err != nil { return nil, err @@ -20,7 +20,7 @@ func (r *FeastRuleset) CreateInitialBoardState(width int32, height int32, snakeI return initialBoardState, nil } -func (r *FeastRuleset) CreateNextBoardState(prevState *BoardState, moves []SnakeMove) (*BoardState, error) { +func (r *MazeRuleset) CreateNextBoardState(prevState *BoardState, moves []SnakeMove) (*BoardState, error) { nextState, err := r.StandardRuleset.CreateNextBoardState(prevState, moves) if err != nil { return nil, err @@ -34,7 +34,7 @@ func (r *FeastRuleset) CreateNextBoardState(prevState *BoardState, moves []Snake return nextState, nil } -func (r *FeastRuleset) fillBoardWithFood(b *BoardState) error { +func (r *MazeRuleset) fillBoardWithFood(b *BoardState) error { unoccupiedPoints := r.getUnoccupiedPoints(b, true) b.Food = append(b.Food, unoccupiedPoints...) return nil diff --git a/feast_test.go b/maze_test.go similarity index 54% rename from feast_test.go rename to maze_test.go index c3eb74f..8304bf0 100644 --- a/feast_test.go +++ b/maze_test.go @@ -6,11 +6,11 @@ import ( "github.com/stretchr/testify/require" ) -func TestFeastRulesetInterface(t *testing.T) { - var _ Ruleset = (*FeastRuleset)(nil) +func TestMazeRulesetInterface(t *testing.T) { + var _ Ruleset = (*MazeRuleset)(nil) } -func TestFeastCreateInitialBoardState(t *testing.T) { +func TestMazeCreateInitialBoardState(t *testing.T) { tests := []struct { Height int32 Width int32 @@ -27,7 +27,7 @@ func TestFeastCreateInitialBoardState(t *testing.T) { {11, 11, []string{"one", "two", "three", "four", "five"}, 116, nil}, } - r := FeastRuleset{} + r := MazeRuleset{} for testNum, test := range tests { state, err := r.CreateInitialBoardState(test.Width, test.Height, test.IDs) require.Equal(t, test.Err, err) @@ -46,11 +46,10 @@ func TestFeastCreateInitialBoardState(t *testing.T) { } } -func TestFeastCreateNextBoardState(t *testing.T) { +func TestMazeCreateNextBoardState(t *testing.T) { tests := []struct { prevState *BoardState moves []SnakeMove - expectedError error expectedState *BoardState }{ { @@ -75,7 +74,6 @@ func TestFeastCreateNextBoardState(t *testing.T) { {ID: "one", Move: MoveDown}, {ID: "two", Move: MoveUp}, }, - nil, &BoardState{ Width: 3, Height: 3, @@ -94,12 +92,84 @@ func TestFeastCreateNextBoardState(t *testing.T) { Food: []Point{{0, 2}, {1, 1}, {2, 0}}, }, }, + // Ensure food is spawning in front of snakes + { + &BoardState{ + Width: 3, + Height: 3, + Snakes: []Snake{ + { + ID: "one", + Body: []Point{{1, 0}, {1, 0}, {1, 0}}, + Health: 75, + }, + }, + Food: []Point{}, + }, + []SnakeMove{ + {ID: "one", Move: MoveDown}, + }, + &BoardState{ + Width: 3, + Height: 3, + Snakes: []Snake{ + { + ID: "one", + Body: []Point{{1, 1}, {1, 0}, {1, 0}}, + Health: 74, + }, + }, + Food: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 2}, {2, 0}, {2, 1}, {2, 2}}, + }, + }, + // Ensure eliminated snakes are immediately replace with food + { + &BoardState{ + Width: 3, + Height: 3, + Snakes: []Snake{ + { + ID: "one", + Body: []Point{{1, 0}, {2, 0}, {2, 0}}, + Health: 100, + }, + { + ID: "two", + Body: []Point{{2, 2}, {1, 2}, {0, 2}}, + Health: 100, + }, + }, + Food: []Point{}, + }, + []SnakeMove{ + {ID: "one", Move: MoveLeft}, + {ID: "two", Move: MoveDown}, + }, + &BoardState{ + Width: 3, + Height: 3, + Snakes: []Snake{ + { + ID: "one", + Body: []Point{{0, 0}, {1, 0}, {2, 0}}, + Health: 99, + }, + { + ID: "two", + Body: []Point{{2, 3}, {2, 2}, {1, 2}}, + Health: 99, + EliminatedCause: EliminatedByOutOfBounds, + }, + }, + Food: []Point{{0, 1}, {0, 2}, {1, 1}, {1, 2}, {2, 1}, {2, 2}}, + }, + }, } - r := FeastRuleset{} + r := MazeRuleset{} for _, test := range tests { nextState, err := r.CreateNextBoardState(test.prevState, test.moves) - require.Equal(t, test.expectedError, err) + require.NoError(t, err) require.Equal(t, test.expectedState, nextState) } } diff --git a/standard.go b/standard.go index 4fd444e..2d78af7 100644 --- a/standard.go +++ b/standard.go @@ -548,6 +548,9 @@ func (r *StandardRuleset) getUnoccupiedPoints(b *BoardState, includePossibleMove pointIsOccupied[p.X][p.Y] = true } for _, snake := range b.Snakes { + if snake.EliminatedCause != NotEliminated { + continue + } for i, p := range snake.Body { if _, xExists := pointIsOccupied[p.X]; !xExists { pointIsOccupied[p.X] = map[int32]bool{}