Byte-snake-engine/royale_test.go

240 lines
7.7 KiB
Go
Raw Normal View History

2020-07-25 17:37:41 -07:00
package rules
import (
"errors"
"testing"
"github.com/stretchr/testify/require"
)
func TestRoyaleRulesetInterface(t *testing.T) {
var _ Ruleset = (*RoyaleRuleset)(nil)
}
func TestRoyaleDefaultSanity(t *testing.T) {
boardState := &BoardState{}
r := RoyaleRuleset{}
_, err := r.CreateNextBoardState(boardState, []SnakeMove{})
require.Error(t, err)
require.Equal(t, errors.New("royale game must shrink at least every turn"), err)
2020-07-25 17:37:41 -07:00
r = RoyaleRuleset{ShrinkEveryNTurns: 1, DamagePerTurn: 1}
2020-07-25 17:37:41 -07:00
_, err = r.CreateNextBoardState(boardState, []SnakeMove{})
require.NoError(t, err)
}
func TestRoyaleOutOfBounds(t *testing.T) {
2020-07-29 13:14:42 -07:00
seed := int64(25543234525)
2020-07-25 17:37:41 -07:00
tests := []struct {
Width int32
Height int32
Turn int32
ShrinkEveryNTurns int32
Error error
ExpectedOutOfBounds []Point
}{
{Error: errors.New("royale game must shrink at least every turn")},
2020-07-25 17:37:41 -07:00
{ShrinkEveryNTurns: 1, ExpectedOutOfBounds: []Point{}},
{Turn: 1, ShrinkEveryNTurns: 1, ExpectedOutOfBounds: []Point{}},
{Width: 3, Height: 3, Turn: 1, ShrinkEveryNTurns: 10, ExpectedOutOfBounds: []Point{}},
{Width: 3, Height: 3, Turn: 9, ShrinkEveryNTurns: 10, ExpectedOutOfBounds: []Point{}},
{
Width: 3, Height: 3, Turn: 10, ShrinkEveryNTurns: 10,
ExpectedOutOfBounds: []Point{{0, 0}, {0, 1}, {0, 2}},
2020-07-25 17:37:41 -07:00
},
{
Width: 3, Height: 3, Turn: 11, ShrinkEveryNTurns: 10,
ExpectedOutOfBounds: []Point{{0, 0}, {0, 1}, {0, 2}},
2020-07-25 17:37:41 -07:00
},
{
Width: 3, Height: 3, Turn: 19, ShrinkEveryNTurns: 10,
ExpectedOutOfBounds: []Point{{0, 0}, {0, 1}, {0, 2}},
2020-07-25 17:37:41 -07:00
},
{
Width: 3, Height: 3, Turn: 20, ShrinkEveryNTurns: 10,
ExpectedOutOfBounds: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 2}, {2, 2}},
},
{
Width: 3, Height: 3, Turn: 31, ShrinkEveryNTurns: 10,
2020-07-29 13:14:42 -07:00
ExpectedOutOfBounds: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 1}, {1, 2}, {2, 1}, {2, 2}},
},
{
Width: 3, Height: 3, Turn: 42, ShrinkEveryNTurns: 10,
2020-07-29 13:14:42 -07:00
ExpectedOutOfBounds: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2}},
},
{
Width: 3, Height: 3, Turn: 53, ShrinkEveryNTurns: 10,
ExpectedOutOfBounds: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2}},
},
{
Width: 3, Height: 3, Turn: 64, ShrinkEveryNTurns: 10,
ExpectedOutOfBounds: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2}},
},
{
Width: 3, Height: 3, Turn: 6987, ShrinkEveryNTurns: 10,
2020-07-25 17:37:41 -07:00
ExpectedOutOfBounds: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2}},
},
}
for _, test := range tests {
b := &BoardState{
Width: test.Width,
Height: test.Height,
}
2020-07-25 17:37:41 -07:00
r := RoyaleRuleset{
2020-07-29 13:14:42 -07:00
Seed: seed,
2020-07-25 17:37:41 -07:00
Turn: test.Turn,
ShrinkEveryNTurns: test.ShrinkEveryNTurns,
}
err := r.populateOutOfBounds(b, test.Turn)
2020-07-25 17:37:41 -07:00
require.Equal(t, test.Error, err)
if err == nil {
// Obstacles should match
require.Equal(t, test.ExpectedOutOfBounds, r.OutOfBounds)
for _, expectedP := range test.ExpectedOutOfBounds {
wasFound := false
for _, actualP := range r.OutOfBounds {
if expectedP == actualP {
wasFound = true
break
}
}
require.True(t, wasFound)
}
}
}
}
func TestRoyaleDamageOutOfBounds(t *testing.T) {
2020-07-25 17:37:41 -07:00
tests := []struct {
Snakes []Snake
OutOfBounds []Point
ExpectedEliminatedCauses []string
ExpectedEliminatedByIDs []string
}{
{},
{
Snakes: []Snake{{Body: []Point{{0, 0}}}},
OutOfBounds: []Point{},
ExpectedEliminatedCauses: []string{NotEliminated},
ExpectedEliminatedByIDs: []string{""},
},
{
Snakes: []Snake{{Body: []Point{{0, 0}}}},
OutOfBounds: []Point{{0, 0}},
ExpectedEliminatedCauses: []string{EliminatedByOutOfHealth},
2020-07-25 17:37:41 -07:00
ExpectedEliminatedByIDs: []string{""},
},
{
Snakes: []Snake{{Body: []Point{{0, 0}, {1, 0}, {2, 0}}}},
OutOfBounds: []Point{{1, 0}, {2, 0}},
ExpectedEliminatedCauses: []string{NotEliminated},
ExpectedEliminatedByIDs: []string{""},
},
{
Snakes: []Snake{
{Body: []Point{{0, 0}, {1, 0}, {2, 0}}},
{Body: []Point{{3, 3}, {3, 4}, {3, 5}, {3, 6}}},
},
OutOfBounds: []Point{{1, 0}, {2, 0}, {3, 4}, {3, 5}, {3, 6}},
ExpectedEliminatedCauses: []string{NotEliminated, NotEliminated},
ExpectedEliminatedByIDs: []string{"", ""},
},
{
Snakes: []Snake{
{Body: []Point{{0, 0}, {1, 0}, {2, 0}}},
{Body: []Point{{3, 3}, {3, 4}, {3, 5}, {3, 6}}},
},
OutOfBounds: []Point{{3, 3}},
ExpectedEliminatedCauses: []string{NotEliminated, EliminatedByOutOfHealth},
2020-07-25 17:37:41 -07:00
ExpectedEliminatedByIDs: []string{"", ""},
},
}
for _, test := range tests {
b := &BoardState{Snakes: test.Snakes}
r := RoyaleRuleset{OutOfBounds: test.OutOfBounds, DamagePerTurn: 100}
err := r.damageOutOfBounds(b)
2020-07-25 17:37:41 -07:00
require.NoError(t, err)
for i, snake := range b.Snakes {
require.Equal(t, test.ExpectedEliminatedCauses[i], snake.EliminatedCause)
}
}
}
func TestRoyaleDamagePerTurn(t *testing.T) {
tests := []struct {
Health int32
DamagePerTurn int32
ExpectedHealth int32
ExpectedEliminationCause string
Error error
}{
{100, 0, 100, NotEliminated, errors.New("royale damage per turn must be greater than zero")},
{100, -100, 100, NotEliminated, errors.New("royale damage per turn must be greater than zero")},
{100, 1, 99, NotEliminated, nil},
{100, 99, 1, NotEliminated, nil},
{100, 100, 0, EliminatedByOutOfHealth, nil},
{100, 101, 0, EliminatedByOutOfHealth, nil},
{100, 999, 0, EliminatedByOutOfHealth, nil},
{2, 1, 1, NotEliminated, nil},
{1, 1, 0, EliminatedByOutOfHealth, nil},
{1, 999, 0, EliminatedByOutOfHealth, nil},
{0, 1, 0, EliminatedByOutOfHealth, nil},
{0, 999, 0, EliminatedByOutOfHealth, nil},
}
for _, test := range tests {
b := &BoardState{Snakes: []Snake{{Health: test.Health, Body: []Point{{0, 0}}}}}
r := RoyaleRuleset{OutOfBounds: []Point{{0, 0}}, DamagePerTurn: test.DamagePerTurn}
err := r.damageOutOfBounds(b)
require.Equal(t, test.Error, err)
require.Equal(t, test.ExpectedHealth, b.Snakes[0].Health)
require.Equal(t, test.ExpectedEliminationCause, b.Snakes[0].EliminatedCause)
}
}
func TestRoyalDamageNextTurn(t *testing.T) {
2020-07-29 13:14:42 -07:00
seed := int64(45897034512311)
b := &BoardState{Width: 10, Height: 10, Snakes: []Snake{{ID: "one", Health: 100, Body: []Point{{9, 1}}}}}
r := RoyaleRuleset{Seed: seed, ShrinkEveryNTurns: 10, DamagePerTurn: 30}
m := []SnakeMove{{ID: "one", Move: "up"}}
r.Turn = 10
n, err := r.CreateNextBoardState(b, m)
require.NoError(t, err)
require.Equal(t, NotEliminated, n.Snakes[0].EliminatedCause)
require.Equal(t, int32(99), n.Snakes[0].Health)
2020-07-29 13:14:42 -07:00
require.Equal(t, Point{9, 0}, n.Snakes[0].Body[0])
require.Equal(t, 10, len(r.OutOfBounds)) // X = 0
r.Turn = 20
n, err = r.CreateNextBoardState(b, m)
require.NoError(t, err)
require.Equal(t, NotEliminated, n.Snakes[0].EliminatedCause)
require.Equal(t, int32(99), n.Snakes[0].Health)
2020-07-29 13:14:42 -07:00
require.Equal(t, Point{9, 0}, n.Snakes[0].Body[0])
require.Equal(t, 20, len(r.OutOfBounds)) // X = 9
r.Turn = 21
n, err = r.CreateNextBoardState(b, m)
require.NoError(t, err)
require.Equal(t, NotEliminated, n.Snakes[0].EliminatedCause)
require.Equal(t, int32(69), n.Snakes[0].Health)
2020-07-29 13:14:42 -07:00
require.Equal(t, Point{9, 0}, n.Snakes[0].Body[0])
require.Equal(t, 20, len(r.OutOfBounds))
b.Snakes[0].Health = 15
n, err = r.CreateNextBoardState(b, m)
require.NoError(t, err)
require.Equal(t, EliminatedByOutOfHealth, n.Snakes[0].EliminatedCause)
require.Equal(t, int32(0), n.Snakes[0].Health)
2020-07-29 13:14:42 -07:00
require.Equal(t, Point{9, 0}, n.Snakes[0].Body[0])
require.Equal(t, 20, len(r.OutOfBounds))
}