DEV-1761: New rules API (#118)
* DEV-1761: Clean up Ruleset interface (#115) * remove legacy ruleset types and simplify ruleset interface * remove unnecessary settings argument from Ruleset interface * decouple rules.Settings from client API and store settings as strings * DEV 1761: Add new BoardState and Point fields (#117) * add Point.TTL, Point.Value, GameState and PointState to BoardState * allow maps to access BoardState.GameState,PointState * add PreUpdateBoard and refactor snail_mode with it * fix bug where an extra turn was printed to the console * fix formatting * fix lint errors Co-authored-by: JonathanArns <jonathan.arns@googlemail.com>
This commit is contained in:
parent
639362ef46
commit
82e1999126
50 changed files with 1349 additions and 1610 deletions
|
|
@ -2,14 +2,19 @@ package rules
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestRoyaleRulesetInterface(t *testing.T) {
|
||||
var _ Ruleset = (*RoyaleRuleset)(nil)
|
||||
func getRoyaleRuleset(hazardDamagePerTurn, shrinkEveryNTurns int) Ruleset {
|
||||
settings := NewSettingsWithParams(
|
||||
ParamHazardDamagePerTurn, fmt.Sprint(hazardDamagePerTurn),
|
||||
ParamShrinkEveryNTurns, fmt.Sprint(shrinkEveryNTurns),
|
||||
)
|
||||
return NewRulesetBuilder().WithSettings(settings).NamedRuleset(GameTypeRoyale)
|
||||
}
|
||||
|
||||
func TestRoyaleDefaultSanity(t *testing.T) {
|
||||
|
|
@ -19,24 +24,19 @@ func TestRoyaleDefaultSanity(t *testing.T) {
|
|||
{ID: "2", Body: []Point{{X: 0, Y: 1}}},
|
||||
},
|
||||
}
|
||||
r := RoyaleRuleset{StandardRuleset: StandardRuleset{HazardDamagePerTurn: 1}, ShrinkEveryNTurns: 0}
|
||||
_, err := r.CreateNextBoardState(boardState, []SnakeMove{{"1", "right"}, {"2", "right"}})
|
||||
r := getRoyaleRuleset(1, 0)
|
||||
_, _, err := r.Execute(boardState, []SnakeMove{{"1", "right"}, {"2", "right"}})
|
||||
require.Error(t, err)
|
||||
require.Equal(t, errors.New("royale game can't shrink more frequently than every turn"), err)
|
||||
|
||||
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{})
|
||||
r = getRoyaleRuleset(1, 1)
|
||||
_, boardState, err = r.Execute(boardState, []SnakeMove{})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, boardState.Hazards, 0)
|
||||
}
|
||||
|
||||
func TestRoyaleName(t *testing.T) {
|
||||
r := RoyaleRuleset{}
|
||||
r := getRoyaleRuleset(0, 0)
|
||||
require.Equal(t, "royale", r.Name())
|
||||
}
|
||||
|
||||
|
|
@ -57,39 +57,39 @@ func TestRoyaleHazards(t *testing.T) {
|
|||
{Width: 3, Height: 3, Turn: 9, ShrinkEveryNTurns: 10, ExpectedHazards: []Point{}},
|
||||
{
|
||||
Width: 3, Height: 3, Turn: 10, ShrinkEveryNTurns: 10,
|
||||
ExpectedHazards: []Point{{0, 0}, {0, 1}, {0, 2}},
|
||||
ExpectedHazards: []Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 0, Y: 2}},
|
||||
},
|
||||
{
|
||||
Width: 3, Height: 3, Turn: 11, ShrinkEveryNTurns: 10,
|
||||
ExpectedHazards: []Point{{0, 0}, {0, 1}, {0, 2}},
|
||||
ExpectedHazards: []Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 0, Y: 2}},
|
||||
},
|
||||
{
|
||||
Width: 3, Height: 3, Turn: 19, ShrinkEveryNTurns: 10,
|
||||
ExpectedHazards: []Point{{0, 0}, {0, 1}, {0, 2}},
|
||||
ExpectedHazards: []Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 0, Y: 2}},
|
||||
},
|
||||
{
|
||||
Width: 3, Height: 3, Turn: 20, ShrinkEveryNTurns: 10,
|
||||
ExpectedHazards: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 2}, {2, 2}},
|
||||
ExpectedHazards: []Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 0, Y: 2}, {X: 1, Y: 2}, {X: 2, Y: 2}},
|
||||
},
|
||||
{
|
||||
Width: 3, Height: 3, Turn: 31, ShrinkEveryNTurns: 10,
|
||||
ExpectedHazards: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 1}, {1, 2}, {2, 1}, {2, 2}},
|
||||
ExpectedHazards: []Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 0, Y: 2}, {X: 1, Y: 1}, {X: 1, Y: 2}, {X: 2, Y: 1}, {X: 2, Y: 2}},
|
||||
},
|
||||
{
|
||||
Width: 3, Height: 3, Turn: 42, ShrinkEveryNTurns: 10,
|
||||
ExpectedHazards: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2}},
|
||||
ExpectedHazards: []Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 0, Y: 2}, {X: 1, Y: 0}, {X: 1, Y: 1}, {X: 1, Y: 2}, {X: 2, Y: 0}, {X: 2, Y: 1}, {X: 2, Y: 2}},
|
||||
},
|
||||
{
|
||||
Width: 3, Height: 3, Turn: 53, ShrinkEveryNTurns: 10,
|
||||
ExpectedHazards: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2}},
|
||||
ExpectedHazards: []Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 0, Y: 2}, {X: 1, Y: 0}, {X: 1, Y: 1}, {X: 1, Y: 2}, {X: 2, Y: 0}, {X: 2, Y: 1}, {X: 2, Y: 2}},
|
||||
},
|
||||
{
|
||||
Width: 3, Height: 3, Turn: 64, ShrinkEveryNTurns: 10,
|
||||
ExpectedHazards: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2}},
|
||||
ExpectedHazards: []Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 0, Y: 2}, {X: 1, Y: 0}, {X: 1, Y: 1}, {X: 1, Y: 2}, {X: 2, Y: 0}, {X: 2, Y: 1}, {X: 2, Y: 2}},
|
||||
},
|
||||
{
|
||||
Width: 3, Height: 3, Turn: 6987, ShrinkEveryNTurns: 10,
|
||||
ExpectedHazards: []Point{{0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2}},
|
||||
ExpectedHazards: []Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 0, Y: 2}, {X: 1, Y: 0}, {X: 1, Y: 1}, {X: 1, Y: 2}, {X: 2, Y: 0}, {X: 2, Y: 1}, {X: 2, Y: 2}},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -99,12 +99,10 @@ func TestRoyaleHazards(t *testing.T) {
|
|||
Width: test.Width,
|
||||
Height: test.Height,
|
||||
}
|
||||
settings := Settings{
|
||||
HazardDamagePerTurn: 1,
|
||||
RoyaleSettings: RoyaleSettings{
|
||||
ShrinkEveryNTurns: test.ShrinkEveryNTurns,
|
||||
},
|
||||
}.WithSeed(seed)
|
||||
settings := NewSettingsWithParams(
|
||||
ParamHazardDamagePerTurn, "1",
|
||||
ParamShrinkEveryNTurns, fmt.Sprint(test.ShrinkEveryNTurns),
|
||||
).WithSeed(seed)
|
||||
|
||||
_, err := PopulateHazardsRoyale(b, settings, mockSnakeMoves())
|
||||
require.Equal(t, test.Error, err)
|
||||
|
|
@ -139,12 +137,12 @@ var royaleCaseHazardsPlaced = gameTestCase{
|
|||
Snakes: []Snake{
|
||||
{
|
||||
ID: "one",
|
||||
Body: []Point{{1, 1}, {1, 2}},
|
||||
Body: []Point{{X: 1, Y: 1}, {X: 1, Y: 2}},
|
||||
Health: 100,
|
||||
},
|
||||
{
|
||||
ID: "two",
|
||||
Body: []Point{{3, 4}, {3, 3}},
|
||||
Body: []Point{{X: 3, Y: 4}, {X: 3, Y: 3}},
|
||||
Health: 100,
|
||||
},
|
||||
{
|
||||
|
|
@ -154,7 +152,7 @@ var royaleCaseHazardsPlaced = gameTestCase{
|
|||
EliminatedCause: EliminatedByOutOfBounds,
|
||||
},
|
||||
},
|
||||
Food: []Point{{0, 0}, {1, 0}},
|
||||
Food: []Point{{X: 0, Y: 0}, {X: 1, Y: 0}},
|
||||
Hazards: []Point{},
|
||||
},
|
||||
[]SnakeMove{
|
||||
|
|
@ -169,12 +167,12 @@ var royaleCaseHazardsPlaced = gameTestCase{
|
|||
Snakes: []Snake{
|
||||
{
|
||||
ID: "one",
|
||||
Body: []Point{{1, 0}, {1, 1}, {1, 1}},
|
||||
Body: []Point{{X: 1, Y: 0}, {X: 1, Y: 1}, {X: 1, Y: 1}},
|
||||
Health: 100,
|
||||
},
|
||||
{
|
||||
ID: "two",
|
||||
Body: []Point{{3, 5}, {3, 4}},
|
||||
Body: []Point{{X: 3, Y: 5}, {X: 3, Y: 4}},
|
||||
Health: 99,
|
||||
},
|
||||
{
|
||||
|
|
@ -184,7 +182,7 @@ var royaleCaseHazardsPlaced = gameTestCase{
|
|||
EliminatedCause: EliminatedByOutOfBounds,
|
||||
},
|
||||
},
|
||||
Food: []Point{{0, 0}},
|
||||
Food: []Point{{X: 0, Y: 0}},
|
||||
Hazards: []Point{{X: 0, Y: 0}, {X: 1, Y: 0}, {X: 2, Y: 0}, {X: 3, Y: 0}, {X: 4, Y: 0}, {X: 5, Y: 0}, {X: 6, Y: 0}, {X: 7, Y: 0}, {X: 8, Y: 0}, {X: 9, Y: 0}},
|
||||
},
|
||||
}
|
||||
|
|
@ -204,22 +202,14 @@ func TestRoyaleCreateNextBoardState(t *testing.T) {
|
|||
*s2,
|
||||
royaleCaseHazardsPlaced,
|
||||
}
|
||||
r := RoyaleRuleset{
|
||||
StandardRuleset: StandardRuleset{
|
||||
HazardDamagePerTurn: 1,
|
||||
},
|
||||
ShrinkEveryNTurns: 1,
|
||||
}
|
||||
rb := NewRulesetBuilder().WithParams(map[string]string{
|
||||
ParamGameType: GameTypeRoyale,
|
||||
ParamHazardDamagePerTurn: "1",
|
||||
ParamShrinkEveryNTurns: "1",
|
||||
}).WithSeed(1234)
|
||||
for _, gc := range cases {
|
||||
rand.Seed(1234)
|
||||
gc.requireValidNextState(t, &r)
|
||||
// also test a RulesBuilder constructed instance
|
||||
gc.requireValidNextState(t, rb.Ruleset())
|
||||
// test a RulesBuilder constructed instance
|
||||
gc.requireValidNextState(t, rb.NamedRuleset(GameTypeRoyale))
|
||||
// also test a pipeline with the same settings
|
||||
gc.requireValidNextState(t, rb.PipelineRuleset(GameTypeRoyale, NewPipeline(royaleRulesetStages...)))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue