"Feast" -> "Maze". Fix backfill bug. (#26)

This commit is contained in:
Brad Van Vugt 2020-12-08 13:20:13 -08:00 committed by GitHub
parent d7ee7b97fb
commit e01a1bf505
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 13 deletions

View file

@ -2,11 +2,11 @@ package rules
import () import ()
type FeastRuleset struct { type MazeRuleset struct {
StandardRuleset 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) initialBoardState, err := r.StandardRuleset.CreateInitialBoardState(width, height, snakeIDs)
if err != nil { if err != nil {
return nil, err return nil, err
@ -20,7 +20,7 @@ func (r *FeastRuleset) CreateInitialBoardState(width int32, height int32, snakeI
return initialBoardState, nil 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) nextState, err := r.StandardRuleset.CreateNextBoardState(prevState, moves)
if err != nil { if err != nil {
return nil, err return nil, err
@ -34,7 +34,7 @@ func (r *FeastRuleset) CreateNextBoardState(prevState *BoardState, moves []Snake
return nextState, nil return nextState, nil
} }
func (r *FeastRuleset) fillBoardWithFood(b *BoardState) error { func (r *MazeRuleset) fillBoardWithFood(b *BoardState) error {
unoccupiedPoints := r.getUnoccupiedPoints(b, true) unoccupiedPoints := r.getUnoccupiedPoints(b, true)
b.Food = append(b.Food, unoccupiedPoints...) b.Food = append(b.Food, unoccupiedPoints...)
return nil return nil

View file

@ -6,11 +6,11 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestFeastRulesetInterface(t *testing.T) { func TestMazeRulesetInterface(t *testing.T) {
var _ Ruleset = (*FeastRuleset)(nil) var _ Ruleset = (*MazeRuleset)(nil)
} }
func TestFeastCreateInitialBoardState(t *testing.T) { func TestMazeCreateInitialBoardState(t *testing.T) {
tests := []struct { tests := []struct {
Height int32 Height int32
Width int32 Width int32
@ -27,7 +27,7 @@ func TestFeastCreateInitialBoardState(t *testing.T) {
{11, 11, []string{"one", "two", "three", "four", "five"}, 116, nil}, {11, 11, []string{"one", "two", "three", "four", "five"}, 116, nil},
} }
r := FeastRuleset{} r := MazeRuleset{}
for testNum, test := range tests { for testNum, test := range tests {
state, err := r.CreateInitialBoardState(test.Width, test.Height, test.IDs) state, err := r.CreateInitialBoardState(test.Width, test.Height, test.IDs)
require.Equal(t, test.Err, err) 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 { tests := []struct {
prevState *BoardState prevState *BoardState
moves []SnakeMove moves []SnakeMove
expectedError error
expectedState *BoardState expectedState *BoardState
}{ }{
{ {
@ -75,7 +74,6 @@ func TestFeastCreateNextBoardState(t *testing.T) {
{ID: "one", Move: MoveDown}, {ID: "one", Move: MoveDown},
{ID: "two", Move: MoveUp}, {ID: "two", Move: MoveUp},
}, },
nil,
&BoardState{ &BoardState{
Width: 3, Width: 3,
Height: 3, Height: 3,
@ -94,12 +92,84 @@ func TestFeastCreateNextBoardState(t *testing.T) {
Food: []Point{{0, 2}, {1, 1}, {2, 0}}, 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 { for _, test := range tests {
nextState, err := r.CreateNextBoardState(test.prevState, test.moves) nextState, err := r.CreateNextBoardState(test.prevState, test.moves)
require.Equal(t, test.expectedError, err) require.NoError(t, err)
require.Equal(t, test.expectedState, nextState) require.Equal(t, test.expectedState, nextState)
} }
} }

View file

@ -548,6 +548,9 @@ func (r *StandardRuleset) getUnoccupiedPoints(b *BoardState, includePossibleMove
pointIsOccupied[p.X][p.Y] = true pointIsOccupied[p.X][p.Y] = true
} }
for _, snake := range b.Snakes { for _, snake := range b.Snakes {
if snake.EliminatedCause != NotEliminated {
continue
}
for i, p := range snake.Body { for i, p := range snake.Body {
if _, xExists := pointIsOccupied[p.X]; !xExists { if _, xExists := pointIsOccupied[p.X]; !xExists {
pointIsOccupied[p.X] = map[int32]bool{} pointIsOccupied[p.X] = map[int32]bool{}