Refactor RoyaleRuleset and move hazard damage into StandardRuleset (#50)
* move hazard damage into StandardRuleset * OutOfBounds -> Hazards * remove "out of bounds" in comment * add cases for eating food to hazard damage test
This commit is contained in:
parent
dabbe7dfb5
commit
e416384007
8 changed files with 341 additions and 288 deletions
218
royale_test.go
218
royale_test.go
|
|
@ -13,14 +13,20 @@ func TestRoyaleRulesetInterface(t *testing.T) {
|
|||
|
||||
func TestRoyaleDefaultSanity(t *testing.T) {
|
||||
boardState := &BoardState{}
|
||||
r := RoyaleRuleset{}
|
||||
r := RoyaleRuleset{StandardRuleset: StandardRuleset{HazardDamagePerTurn: 1}, ShrinkEveryNTurns: 0}
|
||||
_, err := r.CreateNextBoardState(boardState, []SnakeMove{})
|
||||
require.Error(t, err)
|
||||
require.Equal(t, errors.New("royale game must shrink at least every turn"), err)
|
||||
require.Equal(t, errors.New("royale game can't shrink more frequently than every turn"), err)
|
||||
|
||||
r = RoyaleRuleset{ShrinkEveryNTurns: 1, DamagePerTurn: 1}
|
||||
r = RoyaleRuleset{ShrinkEveryNTurns: 1}
|
||||
_, err = r.CreateNextBoardState(boardState, []SnakeMove{})
|
||||
require.Error(t, err)
|
||||
require.Equal(t, errors.New("royale damage per turn must be greater than zero"), err)
|
||||
|
||||
r = RoyaleRuleset{StandardRuleset: StandardRuleset{HazardDamagePerTurn: 1}, ShrinkEveryNTurns: 1}
|
||||
boardState, err = r.CreateNextBoardState(boardState, []SnakeMove{})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, boardState.Hazards, 0)
|
||||
}
|
||||
|
||||
func TestRoyaleName(t *testing.T) {
|
||||
|
|
@ -28,56 +34,56 @@ func TestRoyaleName(t *testing.T) {
|
|||
require.Equal(t, "royale", r.Name())
|
||||
}
|
||||
|
||||
func TestRoyaleOutOfBounds(t *testing.T) {
|
||||
func TestRoyaleHazards(t *testing.T) {
|
||||
seed := int64(25543234525)
|
||||
tests := []struct {
|
||||
Width int32
|
||||
Height int32
|
||||
Turn int32
|
||||
ShrinkEveryNTurns int32
|
||||
Error error
|
||||
ExpectedOutOfBounds []Point
|
||||
Width int32
|
||||
Height int32
|
||||
Turn int32
|
||||
ShrinkEveryNTurns int32
|
||||
Error error
|
||||
ExpectedHazards []Point
|
||||
}{
|
||||
{Error: errors.New("royale game must shrink at least every turn")},
|
||||
{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{}},
|
||||
{Error: errors.New("royale game can't shrink more frequently than every turn")},
|
||||
{ShrinkEveryNTurns: 1, ExpectedHazards: []Point{}},
|
||||
{Turn: 1, ShrinkEveryNTurns: 1, ExpectedHazards: []Point{}},
|
||||
{Width: 3, Height: 3, Turn: 1, ShrinkEveryNTurns: 10, ExpectedHazards: []Point{}},
|
||||
{Width: 3, Height: 3, Turn: 9, ShrinkEveryNTurns: 10, ExpectedHazards: []Point{}},
|
||||
{
|
||||
Width: 3, Height: 3, Turn: 10, ShrinkEveryNTurns: 10,
|
||||
ExpectedOutOfBounds: []Point{{0, 0}, {0, 1}, {0, 2}},
|
||||
ExpectedHazards: []Point{{0, 0}, {0, 1}, {0, 2}},
|
||||
},
|
||||
{
|
||||
Width: 3, Height: 3, Turn: 11, ShrinkEveryNTurns: 10,
|
||||
ExpectedOutOfBounds: []Point{{0, 0}, {0, 1}, {0, 2}},
|
||||
ExpectedHazards: []Point{{0, 0}, {0, 1}, {0, 2}},
|
||||
},
|
||||
{
|
||||
Width: 3, Height: 3, Turn: 19, ShrinkEveryNTurns: 10,
|
||||
ExpectedOutOfBounds: []Point{{0, 0}, {0, 1}, {0, 2}},
|
||||
ExpectedHazards: []Point{{0, 0}, {0, 1}, {0, 2}},
|
||||
},
|
||||
{
|
||||
Width: 3, Height: 3, Turn: 20, ShrinkEveryNTurns: 10,
|
||||
ExpectedOutOfBounds: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 2}, {2, 2}},
|
||||
ExpectedHazards: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 2}, {2, 2}},
|
||||
},
|
||||
{
|
||||
Width: 3, Height: 3, Turn: 31, ShrinkEveryNTurns: 10,
|
||||
ExpectedOutOfBounds: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 1}, {1, 2}, {2, 1}, {2, 2}},
|
||||
ExpectedHazards: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 1}, {1, 2}, {2, 1}, {2, 2}},
|
||||
},
|
||||
{
|
||||
Width: 3, Height: 3, Turn: 42, ShrinkEveryNTurns: 10,
|
||||
ExpectedOutOfBounds: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2}},
|
||||
ExpectedHazards: []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}},
|
||||
ExpectedHazards: []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}},
|
||||
ExpectedHazards: []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,
|
||||
ExpectedOutOfBounds: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2}},
|
||||
ExpectedHazards: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2}},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -87,19 +93,22 @@ func TestRoyaleOutOfBounds(t *testing.T) {
|
|||
Height: test.Height,
|
||||
}
|
||||
r := RoyaleRuleset{
|
||||
StandardRuleset: StandardRuleset{
|
||||
HazardDamagePerTurn: 1,
|
||||
},
|
||||
Seed: seed,
|
||||
Turn: test.Turn,
|
||||
ShrinkEveryNTurns: test.ShrinkEveryNTurns,
|
||||
}
|
||||
|
||||
err := r.populateOutOfBounds(b, test.Turn)
|
||||
err := r.populateHazards(b, test.Turn)
|
||||
require.Equal(t, test.Error, err)
|
||||
if err == nil {
|
||||
// Obstacles should match
|
||||
require.Equal(t, test.ExpectedOutOfBounds, r.OutOfBounds)
|
||||
for _, expectedP := range test.ExpectedOutOfBounds {
|
||||
require.Equal(t, test.ExpectedHazards, b.Hazards)
|
||||
for _, expectedP := range test.ExpectedHazards {
|
||||
wasFound := false
|
||||
for _, actualP := range r.OutOfBounds {
|
||||
for _, actualP := range b.Hazards {
|
||||
if expectedP == actualP {
|
||||
wasFound = true
|
||||
break
|
||||
|
|
@ -111,134 +120,57 @@ func TestRoyaleOutOfBounds(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestRoyaleDamageOutOfBounds(t *testing.T) {
|
||||
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},
|
||||
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},
|
||||
ExpectedEliminatedByIDs: []string{"", ""},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
b := &BoardState{Snakes: test.Snakes}
|
||||
r := RoyaleRuleset{OutOfBounds: test.OutOfBounds, DamagePerTurn: 100}
|
||||
err := r.damageOutOfBounds(b)
|
||||
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) {
|
||||
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}
|
||||
base := &BoardState{Width: 10, Height: 10, Snakes: []Snake{{ID: "one", Health: 100, Body: []Point{{9, 1}, {9, 1}, {9, 1}}}}}
|
||||
r := RoyaleRuleset{StandardRuleset: StandardRuleset{HazardDamagePerTurn: 30}, Seed: seed, ShrinkEveryNTurns: 10}
|
||||
m := []SnakeMove{{ID: "one", Move: "down"}}
|
||||
|
||||
r.Turn = 10
|
||||
n, err := r.CreateNextBoardState(b, m)
|
||||
err := r.populateHazards(base, r.Turn-1)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, NotEliminated, n.Snakes[0].EliminatedCause)
|
||||
require.Equal(t, int32(99), n.Snakes[0].Health)
|
||||
require.Equal(t, Point{9, 0}, n.Snakes[0].Body[0])
|
||||
require.Equal(t, 10, len(r.OutOfBounds)) // X = 0
|
||||
next, err := r.CreateNextBoardState(base, m)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, NotEliminated, next.Snakes[0].EliminatedCause)
|
||||
require.Equal(t, int32(99), next.Snakes[0].Health)
|
||||
require.Equal(t, Point{9, 0}, next.Snakes[0].Body[0])
|
||||
require.Equal(t, 10, len(next.Hazards)) // X = 0
|
||||
|
||||
r.Turn = 20
|
||||
n, err = r.CreateNextBoardState(b, m)
|
||||
err = r.populateHazards(base, r.Turn-1)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, NotEliminated, n.Snakes[0].EliminatedCause)
|
||||
require.Equal(t, int32(99), n.Snakes[0].Health)
|
||||
require.Equal(t, Point{9, 0}, n.Snakes[0].Body[0])
|
||||
require.Equal(t, 20, len(r.OutOfBounds)) // X = 9
|
||||
next, err = r.CreateNextBoardState(base, m)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, NotEliminated, next.Snakes[0].EliminatedCause)
|
||||
require.Equal(t, int32(99), next.Snakes[0].Health)
|
||||
require.Equal(t, Point{9, 0}, next.Snakes[0].Body[0])
|
||||
require.Equal(t, 20, len(next.Hazards)) // X = 9
|
||||
|
||||
r.Turn = 21
|
||||
n, err = r.CreateNextBoardState(b, m)
|
||||
err = r.populateHazards(base, r.Turn-1)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, NotEliminated, n.Snakes[0].EliminatedCause)
|
||||
require.Equal(t, int32(69), n.Snakes[0].Health)
|
||||
require.Equal(t, Point{9, 0}, n.Snakes[0].Body[0])
|
||||
require.Equal(t, 20, len(r.OutOfBounds))
|
||||
next, err = r.CreateNextBoardState(base, m)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, NotEliminated, next.Snakes[0].EliminatedCause)
|
||||
require.Equal(t, int32(69), next.Snakes[0].Health)
|
||||
require.Equal(t, Point{9, 0}, next.Snakes[0].Body[0])
|
||||
require.Equal(t, 20, len(next.Hazards))
|
||||
|
||||
b.Snakes[0].Health = 15
|
||||
n, err = r.CreateNextBoardState(b, m)
|
||||
base.Snakes[0].Health = 15
|
||||
next, err = r.CreateNextBoardState(base, m)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, EliminatedByOutOfHealth, n.Snakes[0].EliminatedCause)
|
||||
require.Equal(t, int32(0), n.Snakes[0].Health)
|
||||
require.Equal(t, Point{9, 0}, n.Snakes[0].Body[0])
|
||||
require.Equal(t, 20, len(r.OutOfBounds))
|
||||
require.Equal(t, EliminatedByOutOfHealth, next.Snakes[0].EliminatedCause)
|
||||
require.Equal(t, int32(0), next.Snakes[0].Health)
|
||||
require.Equal(t, Point{9, 0}, next.Snakes[0].Body[0])
|
||||
require.Equal(t, 20, len(next.Hazards))
|
||||
|
||||
base.Food = append(base.Food, Point{9, 0})
|
||||
next, err = r.CreateNextBoardState(base, m)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, Point{9, 0}, next.Snakes[0].Body[0])
|
||||
require.Equal(t, NotEliminated, next.Snakes[0].EliminatedCause)
|
||||
require.Equal(t, int32(100), next.Snakes[0].Health)
|
||||
require.Equal(t, Point{9, 0}, next.Snakes[0].Body[0])
|
||||
require.Equal(t, 20, len(next.Hazards))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue