Merge branch 'master' of github.com:BattlesnakeOfficial/rules
This commit is contained in:
commit
a241c526b2
2 changed files with 18 additions and 348 deletions
16
standard.go
16
standard.go
|
|
@ -11,9 +11,11 @@ const (
|
|||
BoardSizeSmall = 7
|
||||
BoardSizeMedium = 11
|
||||
BoardSizeLarge = 19
|
||||
FoodSpawnChance = 0.1
|
||||
SnakeMaxHealth = 100
|
||||
SnakeStartSize = 3
|
||||
|
||||
FoodSpawnChance = 0.15
|
||||
|
||||
SnakeMaxHealth = 100
|
||||
SnakeStartSize = 3
|
||||
|
||||
// bvanvugt - TODO: Just return formatted strings instead of codes?
|
||||
NotEliminated = ""
|
||||
|
|
@ -175,7 +177,7 @@ func (r *StandardRuleset) ResolveMoves(prevState *BoardState, moves []SnakeMove)
|
|||
}
|
||||
|
||||
// TODO: LOG?
|
||||
err = r.maybeSpawnFood(nextState, 1)
|
||||
err = r.maybeSpawnFood(nextState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -362,9 +364,9 @@ func (r *StandardRuleset) feedSnakes(b *BoardState) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (r *StandardRuleset) maybeSpawnFood(b *BoardState, n int) error {
|
||||
if rand.Float32() <= FoodSpawnChance {
|
||||
return r.spawnFood(b, n)
|
||||
func (r *StandardRuleset) maybeSpawnFood(b *BoardState) error {
|
||||
if len(b.Food) == 0 || rand.Float32() <= FoodSpawnChance {
|
||||
return r.spawnFood(b, 1)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
350
standard_test.go
350
standard_test.go
|
|
@ -1091,15 +1091,16 @@ func TestGetUnoccupiedPoints(t *testing.T) {
|
|||
func TestMaybeSpawnFood(t *testing.T) {
|
||||
tests := []struct {
|
||||
Seed int64
|
||||
Food []Point
|
||||
ExpectedFood []Point
|
||||
}{
|
||||
// Use pre-tested seeds and results
|
||||
{123, []Point{}},
|
||||
{456, []Point{}},
|
||||
{789, []Point{}},
|
||||
{1024, []Point{{2, 1}}},
|
||||
{511, []Point{{2, 0}}},
|
||||
{165, []Point{{3, 1}}},
|
||||
{123, []Point{}, []Point{{2, 2}}},
|
||||
{456, []Point{{4, 4}}, []Point{{4, 4}}},
|
||||
{789, []Point{{4, 4}}, []Point{{4, 4}}},
|
||||
{1024, []Point{}, []Point{{4, 1}}},
|
||||
{511, []Point{{4, 4}}, []Point{{4, 4}, {2, 0}}},
|
||||
{165, []Point{{4, 4}}, []Point{{4, 4}, {3, 1}}},
|
||||
}
|
||||
|
||||
r := StandardRuleset{}
|
||||
|
|
@ -1111,10 +1112,11 @@ func TestMaybeSpawnFood(t *testing.T) {
|
|||
{Body: []Point{{1, 0}, {1, 1}}},
|
||||
{Body: []Point{{0, 1}, {0, 2}, {0, 3}}},
|
||||
},
|
||||
Food: test.Food,
|
||||
}
|
||||
|
||||
rand.Seed(test.Seed)
|
||||
err := r.maybeSpawnFood(b, 1)
|
||||
err := r.maybeSpawnFood(b)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(test.ExpectedFood), len(b.Food), "Seed %d", test.Seed)
|
||||
for i, e := range test.ExpectedFood {
|
||||
|
|
@ -1122,337 +1124,3 @@ func TestMaybeSpawnFood(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// func TestCheckForSnakesEating(t *testing.T) {
|
||||
// snake := &pb.Snake{
|
||||
// Body: []*pb.Point{
|
||||
// {X: 2, Y: 1},
|
||||
// {X: 1, Y: 1},
|
||||
// {X: 1, Y: 2},
|
||||
// {X: 2, Y: 2},
|
||||
// },
|
||||
// }
|
||||
// checkForSnakesEating(&pb.GameFrame{
|
||||
// Food: []*pb.Point{
|
||||
// {X: 2, Y: 1},
|
||||
// },
|
||||
// Snakes: []*pb.Snake{snake},
|
||||
// })
|
||||
// require.Len(t, snake.Body, 4)
|
||||
// require.Equal(t, snake.Body[2], snake.Body[3])
|
||||
// }
|
||||
|
||||
// func TestCheckForSnakesNotEating(t *testing.T) {
|
||||
// snake := &pb.Snake{
|
||||
// Body: []*pb.Point{
|
||||
// {X: 2, Y: 1},
|
||||
// {X: 1, Y: 1},
|
||||
// {X: 1, Y: 2},
|
||||
// {X: 2, Y: 2},
|
||||
// },
|
||||
// }
|
||||
// checkForSnakesEating(&pb.GameFrame{
|
||||
// Food: []*pb.Point{},
|
||||
// Snakes: []*pb.Snake{snake},
|
||||
// })
|
||||
// require.Len(t, snake.Body, 3)
|
||||
// require.NotEqual(t, snake.Body[2], snake.Body[1])
|
||||
// }
|
||||
// func TestGameFrameSnakeEats(t *testing.T) {
|
||||
// snake := &pb.Snake{
|
||||
// Health: 67,
|
||||
// Body: []*pb.Point{
|
||||
// {X: 1, Y: 1},
|
||||
// {X: 1, Y: 2},
|
||||
// {X: 1, Y: 3},
|
||||
// },
|
||||
// }
|
||||
|
||||
// lastFrame.Snakes = []*pb.Snake{snake}
|
||||
|
||||
// gt, err := GameTick(commonGame, lastFrame)
|
||||
// require.NoError(t, err)
|
||||
// require.Len(t, gt.Snakes, 1)
|
||||
// snake = gt.Snakes[0]
|
||||
// require.Equal(t, int32(100), snake.Health)
|
||||
// require.Len(t, snake.Body, 4)
|
||||
// }
|
||||
|
||||
// func TestUpdateFood(t *testing.T) {
|
||||
// updated, err := updateFood(&pb.Game{Width: 20, Height: 20}, &pb.GameFrame{
|
||||
// Food: []*pb.Point{
|
||||
// {X: 1, Y: 1},
|
||||
// {X: 1, Y: 2},
|
||||
// },
|
||||
// Snakes: []*pb.Snake{
|
||||
// {
|
||||
// Body: []*pb.Point{
|
||||
// {X: 1, Y: 2},
|
||||
// {X: 2, Y: 2},
|
||||
// {X: 3, Y: 2},
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// }, []*pb.Point{
|
||||
// {X: 1, Y: 2},
|
||||
// })
|
||||
// require.NoError(t, err)
|
||||
// require.Len(t, updated, 2)
|
||||
// require.True(t, updated[0].Equal(&pb.Point{X: 1, Y: 1}))
|
||||
// require.False(t, updated[1].Equal(&pb.Point{X: 1, Y: 2}))
|
||||
// require.False(t, updated[1].Equal(&pb.Point{X: 2, Y: 2}))
|
||||
// require.False(t, updated[1].Equal(&pb.Point{X: 3, Y: 2}))
|
||||
// require.False(t, updated[1].Equal(&pb.Point{X: 1, Y: 1}))
|
||||
// }
|
||||
|
||||
// func TestUpdateFoodWithFullBoard(t *testing.T) {
|
||||
// updated, err := updateFood(&pb.Game{Width: 2, Height: 2}, &pb.GameFrame{
|
||||
// Food: []*pb.Point{
|
||||
// {X: 0, Y: 0},
|
||||
// },
|
||||
// Snakes: []*pb.Snake{
|
||||
// {
|
||||
// Body: []*pb.Point{
|
||||
// {X: 0, Y: 0},
|
||||
// {X: 0, Y: 1},
|
||||
// {X: 1, Y: 1},
|
||||
// {X: 1, Y: 0},
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// }, []*pb.Point{
|
||||
// {X: 0, Y: 0},
|
||||
// })
|
||||
// require.NoError(t, err)
|
||||
// require.Len(t, updated, 0)
|
||||
// }
|
||||
|
||||
// func TestGetUnoccupiedPointEven(t *testing.T) {
|
||||
|
||||
// unoccupiedPoint := getUnoccupiedPointEven(2, 2,
|
||||
// []*pb.Point{},
|
||||
// []*pb.Snake{})
|
||||
// require.True(t, (unoccupiedPoint.X+unoccupiedPoint.Y)%2 == 0, "Point coordinates should sum to an even number %o ", unoccupiedPoint)
|
||||
// }
|
||||
|
||||
// func TestGetUnoccupiedPointOdd(t *testing.T) {
|
||||
// unoccupiedPoint := getUnoccupiedPointOdd(2, 2,
|
||||
// []*pb.Point{{X: 0, Y: 1}},
|
||||
// []*pb.Snake{})
|
||||
// require.True(t, (unoccupiedPoint.X+unoccupiedPoint.Y)%2 == 1, "Point coordinates should sum to an odd number %o ", unoccupiedPoint)
|
||||
// }
|
||||
|
||||
// func TestGetUnoccupiedPointWithFullBoard(t *testing.T) {
|
||||
// unoccupiedPoint := getUnoccupiedPoint(2, 2,
|
||||
// []*pb.Point{{X: 0, Y: 0}},
|
||||
// []*pb.Snake{
|
||||
// {
|
||||
// Body: []*pb.Point{
|
||||
// {X: 0, Y: 1},
|
||||
// {X: 1, Y: 1},
|
||||
// {X: 1, Y: 0},
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
// require.True(t, unoccupiedPoint.Equal(nil))
|
||||
// }
|
||||
|
||||
// func TestGetUnoccupiedPointsWithEmptySpots(t *testing.T) {
|
||||
// unoccupiedPoints := getUnoccupiedPoints(2, 2,
|
||||
// []*pb.Point{{X: 0, Y: 0}},
|
||||
// []*pb.Snake{
|
||||
// {
|
||||
// Body: []*pb.Point{
|
||||
// {X: 0, Y: 1},
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
// require.Len(t, unoccupiedPoints, 2)
|
||||
// require.True(t, unoccupiedPoints[0].Equal(&pb.Point{X: 1, Y: 0}))
|
||||
// require.True(t, unoccupiedPoints[1].Equal(&pb.Point{X: 1, Y: 1}))
|
||||
// }
|
||||
|
||||
// func TestGetUniqOccupiedPoints(t *testing.T) {
|
||||
// unoccupiedPoints := getUniqOccupiedPoints(
|
||||
// []*pb.Point{
|
||||
// {X: 0, Y: 0},
|
||||
// },
|
||||
// []*pb.Snake{
|
||||
// {
|
||||
// Body: []*pb.Point{
|
||||
// {X: 0, Y: 1},
|
||||
// {X: 1, Y: 1},
|
||||
// {X: 1, Y: 1},
|
||||
// {X: 1, Y: 0},
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
// require.Len(t, unoccupiedPoints, 4)
|
||||
// }
|
||||
|
||||
// func TestGameTickUpdatesTurnCounter(t *testing.T) {
|
||||
// gt, err := GameTick(commonGame, &pb.GameFrame{Turn: 5})
|
||||
// require.NoError(t, err)
|
||||
// require.Equal(t, int32(6), gt.Turn)
|
||||
// }
|
||||
|
||||
// func TestGameTickUpdatesSnake(t *testing.T) {
|
||||
// snake := &pb.Snake{
|
||||
// Health: 67,
|
||||
// Body: []*pb.Point{
|
||||
// {X: 1, Y: 1},
|
||||
// {X: 1, Y: 2},
|
||||
// {X: 1, Y: 3},
|
||||
// },
|
||||
// }
|
||||
// game := &pb.Game{
|
||||
// Width: 20,
|
||||
// Height: 20,
|
||||
// }
|
||||
// gt, err := GameTick(game, &pb.GameFrame{
|
||||
// Turn: 5,
|
||||
// Snakes: []*pb.Snake{
|
||||
// snake,
|
||||
// },
|
||||
// })
|
||||
// require.NoError(t, err)
|
||||
// require.Len(t, gt.Snakes, 1)
|
||||
// snake = gt.Snakes[0]
|
||||
// require.Equal(t, int32(66), snake.Health)
|
||||
// require.Len(t, snake.Body, 3)
|
||||
// require.Equal(t, &pb.Point{X: 1, Y: 0}, snake.Body[0])
|
||||
// require.Equal(t, &pb.Point{X: 1, Y: 1}, snake.Body[1])
|
||||
// require.Equal(t, &pb.Point{X: 1, Y: 2}, snake.Body[2])
|
||||
// }
|
||||
|
||||
// var commonGame = &pb.Game{
|
||||
// Width: 20,
|
||||
// Height: 20,
|
||||
// }
|
||||
// var lastFrame = &pb.GameFrame{
|
||||
// Turn: 5,
|
||||
// Snakes: []*pb.Snake{},
|
||||
// Food: []*pb.Point{
|
||||
// {X: 1, Y: 0},
|
||||
// },
|
||||
// }
|
||||
|
||||
// func TestGameTickDeadSnakeDoNotUpdate(t *testing.T) {
|
||||
// snake := &pb.Snake{
|
||||
// Health: 87,
|
||||
// Body: []*pb.Point{
|
||||
// {X: 1, Y: 1},
|
||||
// {X: 1, Y: 2},
|
||||
// {X: 1, Y: 3},
|
||||
// },
|
||||
// Death: &pb.Death{
|
||||
// Turn: 4,
|
||||
// Cause: DeathCauseSnakeCollision,
|
||||
// },
|
||||
// }
|
||||
|
||||
// lastFrame.Snakes = []*pb.Snake{snake}
|
||||
|
||||
// gt, err := GameTick(commonGame, lastFrame)
|
||||
// require.NoError(t, err)
|
||||
// require.Len(t, gt.Snakes, 1)
|
||||
// snake = gt.Snakes[0]
|
||||
// require.Equal(t, int32(87), snake.Health)
|
||||
// require.Len(t, snake.Body, 3)
|
||||
// require.Equal(t, &pb.Point{X: 1, Y: 1}, snake.Body[0])
|
||||
// require.Equal(t, &pb.Point{X: 1, Y: 2}, snake.Body[1])
|
||||
// require.Equal(t, &pb.Point{X: 1, Y: 3}, snake.Body[2])
|
||||
// }
|
||||
|
||||
// func TestGameTickUpdatesDeath(t *testing.T) {
|
||||
// snake := &pb.Snake{
|
||||
// Health: 0,
|
||||
// Body: []*pb.Point{
|
||||
// {X: 3, Y: 1},
|
||||
// {X: 3, Y: 2},
|
||||
// {X: 3, Y: 3},
|
||||
// },
|
||||
// }
|
||||
|
||||
// lastFrame.Snakes = []*pb.Snake{snake}
|
||||
|
||||
// gt, err := GameTick(commonGame, lastFrame)
|
||||
// require.NoError(t, err)
|
||||
// require.NotNil(t, gt.Snakes[0].Death)
|
||||
// }
|
||||
|
||||
// func TestUpdateSnakes(t *testing.T) {
|
||||
// snake := &pb.Snake{
|
||||
// Body: []*pb.Point{
|
||||
// {X: 1, Y: 1},
|
||||
// },
|
||||
// }
|
||||
// moves := []*SnakeUpdate{
|
||||
// {
|
||||
// Snake: snake,
|
||||
// Err: errors.New("some error"),
|
||||
// },
|
||||
// }
|
||||
// updateSnakes(&pb.Game{}, &pb.GameFrame{
|
||||
// Snakes: []*pb.Snake{snake},
|
||||
// }, moves)
|
||||
// require.Equal(t, &pb.Point{X: 1, Y: 0}, snake.Head(), "snake did not move up")
|
||||
|
||||
// moves = []*SnakeUpdate{
|
||||
// {
|
||||
// Snake: snake,
|
||||
// Move: "left",
|
||||
// },
|
||||
// }
|
||||
// updateSnakes(&pb.Game{}, &pb.GameFrame{
|
||||
// Snakes: []*pb.Snake{snake},
|
||||
// }, moves)
|
||||
// require.Equal(t, &pb.Point{X: 0, Y: 0}, snake.Head(), "snake did not move left")
|
||||
// }
|
||||
|
||||
// func TestCanFollowTail(t *testing.T) {
|
||||
// url := setupSnakeServer(t, MoveResponse{
|
||||
// Move: "down",
|
||||
// }, StartResponse{})
|
||||
// snake := &pb.Snake{
|
||||
// Body: []*pb.Point{
|
||||
// {X: 2, Y: 1},
|
||||
// {X: 1, Y: 1},
|
||||
// {X: 1, Y: 2},
|
||||
// {X: 2, Y: 2},
|
||||
// },
|
||||
// URL: url,
|
||||
// Health: 100,
|
||||
// }
|
||||
// next, err := GameTick(&pb.Game{
|
||||
// Width: 20,
|
||||
// Height: 20,
|
||||
// }, &pb.GameFrame{
|
||||
// Snakes: []*pb.Snake{snake},
|
||||
// })
|
||||
// require.NoError(t, err)
|
||||
// require.NotNil(t, next)
|
||||
// require.Nil(t, next.Snakes[0].Death)
|
||||
// }
|
||||
|
||||
// func TestNextFoodSpawn(t *testing.T) {
|
||||
// rand.Seed(1) // random order is 65, 85, 29
|
||||
// snakes := []*pb.Snake{
|
||||
// {URL: setupSnakeServer(t, MoveResponse{}, StartResponse{})},
|
||||
// {URL: setupSnakeServer(t, MoveResponse{}, StartResponse{})},
|
||||
// {URL: setupSnakeServer(t, MoveResponse{}, StartResponse{})},
|
||||
// {URL: setupSnakeServer(t, MoveResponse{}, StartResponse{})},
|
||||
// }
|
||||
// next, err := GameTick(&pb.Game{
|
||||
// Width: 20,
|
||||
// Height: 20,
|
||||
// TurnsSinceLastFoodSpawn: 5,
|
||||
// MaxTurnsToNextFoodSpawn: 5,
|
||||
// }, &pb.GameFrame{
|
||||
// Snakes: snakes,
|
||||
// })
|
||||
// require.NoError(t, err)
|
||||
// require.Len(t, next.Food, 2)
|
||||
// }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue