add turn to BoardState and remove it from RoyaleRuleset (#52)

This commit is contained in:
Rob O'Dwyer 2021-08-27 13:28:12 -07:00 committed by GitHub
parent 17556e15c1
commit e9f408cdbb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 27 deletions

View file

@ -3,6 +3,7 @@ package rules
import "math/rand" import "math/rand"
type BoardState struct { type BoardState struct {
Turn int32
Height int32 Height int32
Width int32 Width int32
Food []Point Food []Point
@ -13,6 +14,7 @@ type BoardState struct {
// NewBoardState returns an empty but fully initialized BoardState // NewBoardState returns an empty but fully initialized BoardState
func NewBoardState(width, height int32) *BoardState { func NewBoardState(width, height int32) *BoardState {
return &BoardState{ return &BoardState{
Turn: 0,
Height: height, Height: height,
Width: width, Width: width,
Food: []Point{}, Food: []Point{},
@ -24,6 +26,7 @@ func NewBoardState(width, height int32) *BoardState {
// Clone returns a deep copy of prevState that can be safely modified inside Ruleset.CreateNextBoardState // Clone returns a deep copy of prevState that can be safely modified inside Ruleset.CreateNextBoardState
func (prevState *BoardState) Clone() *BoardState { func (prevState *BoardState) Clone() *BoardState {
nextState := &BoardState{ nextState := &BoardState{
Turn: prevState.Turn,
Height: prevState.Height, Height: prevState.Height,
Width: prevState.Width, Width: prevState.Width,
Food: append([]Point{}, prevState.Food...), Food: append([]Point{}, prevState.Food...),

View file

@ -134,8 +134,7 @@ var run = func(cmd *cobra.Command, args []string) {
snakes := buildSnakesFromOptions() snakes := buildSnakesFromOptions()
var ruleset rules.Ruleset ruleset := getRuleset(Seed, snakes)
ruleset = getRuleset(Seed, Turn, snakes)
state := initializeBoardFromArgs(ruleset, snakes) state := initializeBoardFromArgs(ruleset, snakes)
for _, snake := range snakes { for _, snake := range snakes {
Battlesnakes[snake.ID] = snake Battlesnakes[snake.ID] = snake
@ -143,8 +142,7 @@ var run = func(cmd *cobra.Command, args []string) {
for v := false; !v; v, _ = ruleset.IsGameOver(state) { for v := false; !v; v, _ = ruleset.IsGameOver(state) {
Turn++ Turn++
ruleset = getRuleset(Seed, Turn, snakes) state = createNextBoardState(ruleset, state, snakes, Turn)
state = createNextBoardState(ruleset, state, snakes)
if ViewMap { if ViewMap {
printMap(state, Turn) printMap(state, Turn)
@ -178,7 +176,7 @@ var run = func(cmd *cobra.Command, args []string) {
} }
} }
func getRuleset(seed int64, gameTurn int32, snakes []Battlesnake) rules.Ruleset { func getRuleset(seed int64, snakes []Battlesnake) rules.Ruleset {
var ruleset rules.Ruleset var ruleset rules.Ruleset
var royale rules.RoyaleRuleset var royale rules.RoyaleRuleset
@ -193,7 +191,6 @@ func getRuleset(seed int64, gameTurn int32, snakes []Battlesnake) rules.Ruleset
royale = rules.RoyaleRuleset{ royale = rules.RoyaleRuleset{
StandardRuleset: standard, StandardRuleset: standard,
Seed: seed, Seed: seed,
Turn: gameTurn,
ShrinkEveryNTurns: 10, ShrinkEveryNTurns: 10,
} }
ruleset = &royale ruleset = &royale
@ -261,7 +258,7 @@ func initializeBoardFromArgs(ruleset rules.Ruleset, snakes []Battlesnake) *rules
return state return state
} }
func createNextBoardState(ruleset rules.Ruleset, state *rules.BoardState, snakes []Battlesnake) *rules.BoardState { func createNextBoardState(ruleset rules.Ruleset, state *rules.BoardState, snakes []Battlesnake, turn int32) *rules.BoardState {
var moves []rules.SnakeMove var moves []rules.SnakeMove
if Sequential { if Sequential {
for _, snake := range snakes { for _, snake := range snakes {
@ -301,6 +298,9 @@ func createNextBoardState(ruleset rules.Ruleset, state *rules.BoardState, snakes
log.Panic("[PANIC]: Error Producing Next Board State") log.Panic("[PANIC]: Error Producing Next Board State")
panic(err) panic(err)
} }
state.Turn = turn
return state return state
} }

View file

@ -10,8 +10,6 @@ type RoyaleRuleset struct {
Seed int64 Seed int64
// TODO: move Turn into BoardState?
Turn int32
ShrinkEveryNTurns int32 ShrinkEveryNTurns int32
} }
@ -28,7 +26,7 @@ func (r *RoyaleRuleset) CreateNextBoardState(prevState *BoardState, moves []Snak
} }
// Royale's only job is now to populate the hazards for next turn - StandardRuleset takes care of applying hazard damage. // Royale's only job is now to populate the hazards for next turn - StandardRuleset takes care of applying hazard damage.
err = r.populateHazards(nextBoardState, r.Turn) err = r.populateHazards(nextBoardState, prevState.Turn+1)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -89,6 +89,7 @@ func TestRoyaleHazards(t *testing.T) {
for _, test := range tests { for _, test := range tests {
b := &BoardState{ b := &BoardState{
Turn: test.Turn,
Width: test.Width, Width: test.Width,
Height: test.Height, Height: test.Height,
} }
@ -97,7 +98,6 @@ func TestRoyaleHazards(t *testing.T) {
HazardDamagePerTurn: 1, HazardDamagePerTurn: 1,
}, },
Seed: seed, Seed: seed,
Turn: test.Turn,
ShrinkEveryNTurns: test.ShrinkEveryNTurns, ShrinkEveryNTurns: test.ShrinkEveryNTurns,
} }
@ -127,46 +127,49 @@ func TestRoyalDamageNextTurn(t *testing.T) {
r := RoyaleRuleset{StandardRuleset: StandardRuleset{HazardDamagePerTurn: 30}, Seed: seed, ShrinkEveryNTurns: 10} r := RoyaleRuleset{StandardRuleset: StandardRuleset{HazardDamagePerTurn: 30}, Seed: seed, ShrinkEveryNTurns: 10}
m := []SnakeMove{{ID: "one", Move: "down"}} m := []SnakeMove{{ID: "one", Move: "down"}}
r.Turn = 10 stateAfterTurn := func(prevState *BoardState, turn int32) *BoardState {
err := r.populateHazards(base, r.Turn-1) nextState := prevState.Clone()
nextState.Turn = turn - 1
err := r.populateHazards(nextState, turn)
require.NoError(t, err) require.NoError(t, err)
next, err := r.CreateNextBoardState(base, m) nextState.Turn = turn
return nextState
}
prevState := stateAfterTurn(base, 9)
next, err := r.CreateNextBoardState(prevState, m)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, NotEliminated, next.Snakes[0].EliminatedCause) require.Equal(t, NotEliminated, next.Snakes[0].EliminatedCause)
require.Equal(t, int32(99), next.Snakes[0].Health) require.Equal(t, int32(99), next.Snakes[0].Health)
require.Equal(t, Point{9, 0}, next.Snakes[0].Body[0]) require.Equal(t, Point{9, 0}, next.Snakes[0].Body[0])
require.Equal(t, 10, len(next.Hazards)) // X = 0 require.Equal(t, 10, len(next.Hazards)) // X = 0
r.Turn = 20 prevState = stateAfterTurn(base, 19)
err = r.populateHazards(base, r.Turn-1) next, err = r.CreateNextBoardState(prevState, m)
require.NoError(t, err)
next, err = r.CreateNextBoardState(base, m)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, NotEliminated, next.Snakes[0].EliminatedCause) require.Equal(t, NotEliminated, next.Snakes[0].EliminatedCause)
require.Equal(t, int32(99), next.Snakes[0].Health) require.Equal(t, int32(99), next.Snakes[0].Health)
require.Equal(t, Point{9, 0}, next.Snakes[0].Body[0]) require.Equal(t, Point{9, 0}, next.Snakes[0].Body[0])
require.Equal(t, 20, len(next.Hazards)) // X = 9 require.Equal(t, 20, len(next.Hazards)) // X = 9
r.Turn = 21 prevState = stateAfterTurn(base, 20)
err = r.populateHazards(base, r.Turn-1) next, err = r.CreateNextBoardState(prevState, m)
require.NoError(t, err)
next, err = r.CreateNextBoardState(base, m)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, NotEliminated, next.Snakes[0].EliminatedCause) require.Equal(t, NotEliminated, next.Snakes[0].EliminatedCause)
require.Equal(t, int32(69), next.Snakes[0].Health) require.Equal(t, int32(69), next.Snakes[0].Health)
require.Equal(t, Point{9, 0}, next.Snakes[0].Body[0]) require.Equal(t, Point{9, 0}, next.Snakes[0].Body[0])
require.Equal(t, 20, len(next.Hazards)) require.Equal(t, 20, len(next.Hazards))
base.Snakes[0].Health = 15 prevState.Snakes[0].Health = 15
next, err = r.CreateNextBoardState(base, m) next, err = r.CreateNextBoardState(prevState, m)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, EliminatedByOutOfHealth, next.Snakes[0].EliminatedCause) require.Equal(t, EliminatedByOutOfHealth, next.Snakes[0].EliminatedCause)
require.Equal(t, int32(0), next.Snakes[0].Health) require.Equal(t, int32(0), next.Snakes[0].Health)
require.Equal(t, Point{9, 0}, next.Snakes[0].Body[0]) require.Equal(t, Point{9, 0}, next.Snakes[0].Body[0])
require.Equal(t, 20, len(next.Hazards)) require.Equal(t, 20, len(next.Hazards))
base.Food = append(base.Food, Point{9, 0}) prevState.Food = append(prevState.Food, Point{9, 0})
next, err = r.CreateNextBoardState(base, m) next, err = r.CreateNextBoardState(prevState, m)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, Point{9, 0}, next.Snakes[0].Body[0]) require.Equal(t, Point{9, 0}, next.Snakes[0].Body[0])
require.Equal(t, NotEliminated, next.Snakes[0].EliminatedCause) require.Equal(t, NotEliminated, next.Snakes[0].EliminatedCause)