change all "int32" types to "int" (#75)
This commit is contained in:
parent
2d8342018e
commit
3bd1e47bb4
19 changed files with 176 additions and 176 deletions
44
board.go
44
board.go
|
|
@ -3,17 +3,17 @@ package rules
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
type BoardState struct {
|
type BoardState struct {
|
||||||
Turn int32
|
Turn int
|
||||||
Height int32
|
Height int
|
||||||
Width int32
|
Width int
|
||||||
Food []Point
|
Food []Point
|
||||||
Snakes []Snake
|
Snakes []Snake
|
||||||
Hazards []Point
|
Hazards []Point
|
||||||
}
|
}
|
||||||
|
|
||||||
type Point struct {
|
type Point struct {
|
||||||
X int32
|
X int
|
||||||
Y int32
|
Y int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Makes it easier to copy sample points out of Go logs and test failures.
|
// Makes it easier to copy sample points out of Go logs and test failures.
|
||||||
|
|
@ -24,14 +24,14 @@ func (p Point) GoString() string {
|
||||||
type Snake struct {
|
type Snake struct {
|
||||||
ID string
|
ID string
|
||||||
Body []Point
|
Body []Point
|
||||||
Health int32
|
Health int
|
||||||
EliminatedCause string
|
EliminatedCause string
|
||||||
EliminatedOnTurn int32
|
EliminatedOnTurn int
|
||||||
EliminatedBy string
|
EliminatedBy string
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 int) *BoardState {
|
||||||
return &BoardState{
|
return &BoardState{
|
||||||
Turn: 0,
|
Turn: 0,
|
||||||
Height: height,
|
Height: height,
|
||||||
|
|
@ -66,7 +66,7 @@ func (prevState *BoardState) Clone() *BoardState {
|
||||||
// "default" board state with snakes and food.
|
// "default" board state with snakes and food.
|
||||||
// In a real game, the engine may generate the board without calling this
|
// In a real game, the engine may generate the board without calling this
|
||||||
// function, or customize the results based on game-specific settings.
|
// function, or customize the results based on game-specific settings.
|
||||||
func CreateDefaultBoardState(rand Rand, width int32, height int32, snakeIDs []string) (*BoardState, error) {
|
func CreateDefaultBoardState(rand Rand, width int, height int, snakeIDs []string) (*BoardState, error) {
|
||||||
initialBoardState := NewBoardState(width, height)
|
initialBoardState := NewBoardState(width, height)
|
||||||
|
|
||||||
err := PlaceSnakesAutomatically(rand, initialBoardState, snakeIDs)
|
err := PlaceSnakesAutomatically(rand, initialBoardState, snakeIDs)
|
||||||
|
|
@ -101,7 +101,7 @@ func PlaceSnakesFixed(rand Rand, b *BoardState, snakeIDs []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create start 8 points
|
// Create start 8 points
|
||||||
mn, md, mx := int32(1), (b.Width-1)/2, b.Width-2
|
mn, md, mx := 1, (b.Width-1)/2, b.Width-2
|
||||||
cornerPoints := []Point{
|
cornerPoints := []Point{
|
||||||
{mn, mn},
|
{mn, mn},
|
||||||
{mn, mx},
|
{mn, mx},
|
||||||
|
|
@ -207,7 +207,7 @@ func PlaceFoodAutomatically(rand Rand, b *BoardState) error {
|
||||||
if isKnownBoardSize(b) {
|
if isKnownBoardSize(b) {
|
||||||
return PlaceFoodFixed(rand, b)
|
return PlaceFoodFixed(rand, b)
|
||||||
}
|
}
|
||||||
return PlaceFoodRandomly(rand, b, int32(len(b.Snakes)))
|
return PlaceFoodRandomly(rand, b, len(b.Snakes))
|
||||||
}
|
}
|
||||||
|
|
||||||
func PlaceFoodFixed(rand Rand, b *BoardState) error {
|
func PlaceFoodFixed(rand Rand, b *BoardState) error {
|
||||||
|
|
@ -289,8 +289,8 @@ func PlaceFoodFixed(rand Rand, b *BoardState) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PlaceFoodRandomly adds up to n new food to the board in random unoccupied squares
|
// PlaceFoodRandomly adds up to n new food to the board in random unoccupied squares
|
||||||
func PlaceFoodRandomly(rand Rand, b *BoardState, n int32) error {
|
func PlaceFoodRandomly(rand Rand, b *BoardState, n int) error {
|
||||||
for i := int32(0); i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
unoccupiedPoints := GetUnoccupiedPoints(b, false)
|
unoccupiedPoints := GetUnoccupiedPoints(b, false)
|
||||||
if len(unoccupiedPoints) > 0 {
|
if len(unoccupiedPoints) > 0 {
|
||||||
newFood := unoccupiedPoints[rand.Intn(len(unoccupiedPoints))]
|
newFood := unoccupiedPoints[rand.Intn(len(unoccupiedPoints))]
|
||||||
|
|
@ -300,7 +300,7 @@ func PlaceFoodRandomly(rand Rand, b *BoardState, n int32) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func absInt32(n int32) int32 {
|
func absInt(n int) int {
|
||||||
if n < 0 {
|
if n < 0 {
|
||||||
return -n
|
return -n
|
||||||
}
|
}
|
||||||
|
|
@ -323,10 +323,10 @@ func GetEvenUnoccupiedPoints(b *BoardState) []Point {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetUnoccupiedPoints(b *BoardState, includePossibleMoves bool) []Point {
|
func GetUnoccupiedPoints(b *BoardState, includePossibleMoves bool) []Point {
|
||||||
pointIsOccupied := map[int32]map[int32]bool{}
|
pointIsOccupied := map[int]map[int]bool{}
|
||||||
for _, p := range b.Food {
|
for _, p := range b.Food {
|
||||||
if _, xExists := pointIsOccupied[p.X]; !xExists {
|
if _, xExists := pointIsOccupied[p.X]; !xExists {
|
||||||
pointIsOccupied[p.X] = map[int32]bool{}
|
pointIsOccupied[p.X] = map[int]bool{}
|
||||||
}
|
}
|
||||||
pointIsOccupied[p.X][p.Y] = true
|
pointIsOccupied[p.X][p.Y] = true
|
||||||
}
|
}
|
||||||
|
|
@ -336,7 +336,7 @@ func GetUnoccupiedPoints(b *BoardState, includePossibleMoves bool) []Point {
|
||||||
}
|
}
|
||||||
for i, p := range snake.Body {
|
for i, p := range snake.Body {
|
||||||
if _, xExists := pointIsOccupied[p.X]; !xExists {
|
if _, xExists := pointIsOccupied[p.X]; !xExists {
|
||||||
pointIsOccupied[p.X] = map[int32]bool{}
|
pointIsOccupied[p.X] = map[int]bool{}
|
||||||
}
|
}
|
||||||
pointIsOccupied[p.X][p.Y] = true
|
pointIsOccupied[p.X][p.Y] = true
|
||||||
|
|
||||||
|
|
@ -349,7 +349,7 @@ func GetUnoccupiedPoints(b *BoardState, includePossibleMoves bool) []Point {
|
||||||
}
|
}
|
||||||
for _, nextP := range nextMovePoints {
|
for _, nextP := range nextMovePoints {
|
||||||
if _, xExists := pointIsOccupied[nextP.X]; !xExists {
|
if _, xExists := pointIsOccupied[nextP.X]; !xExists {
|
||||||
pointIsOccupied[nextP.X] = map[int32]bool{}
|
pointIsOccupied[nextP.X] = map[int]bool{}
|
||||||
}
|
}
|
||||||
pointIsOccupied[nextP.X][nextP.Y] = true
|
pointIsOccupied[nextP.X][nextP.Y] = true
|
||||||
}
|
}
|
||||||
|
|
@ -358,8 +358,8 @@ func GetUnoccupiedPoints(b *BoardState, includePossibleMoves bool) []Point {
|
||||||
}
|
}
|
||||||
|
|
||||||
unoccupiedPoints := []Point{}
|
unoccupiedPoints := []Point{}
|
||||||
for x := int32(0); x < b.Width; x++ {
|
for x := 0; x < b.Width; x++ {
|
||||||
for y := int32(0); y < b.Height; y++ {
|
for y := 0; y < b.Height; y++ {
|
||||||
if _, xExists := pointIsOccupied[x]; xExists {
|
if _, xExists := pointIsOccupied[x]; xExists {
|
||||||
if isOccupied, yExists := pointIsOccupied[x][y]; yExists {
|
if isOccupied, yExists := pointIsOccupied[x][y]; yExists {
|
||||||
if isOccupied {
|
if isOccupied {
|
||||||
|
|
@ -373,8 +373,8 @@ func GetUnoccupiedPoints(b *BoardState, includePossibleMoves bool) []Point {
|
||||||
return unoccupiedPoints
|
return unoccupiedPoints
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDistanceBetweenPoints(a, b Point) int32 {
|
func getDistanceBetweenPoints(a, b Point) int {
|
||||||
return absInt32(a.X-b.X) + absInt32(a.Y-b.Y)
|
return absInt(a.X-b.X) + absInt(a.Y-b.Y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isKnownBoardSize(b *BoardState) bool {
|
func isKnownBoardSize(b *BoardState) bool {
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@ func sortPoints(p []Point) {
|
||||||
|
|
||||||
func TestCreateDefaultBoardState(t *testing.T) {
|
func TestCreateDefaultBoardState(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
Height int32
|
Height int
|
||||||
Width int32
|
Width int
|
||||||
IDs []string
|
IDs []string
|
||||||
ExpectedNumFood int
|
ExpectedNumFood int
|
||||||
Err error
|
Err error
|
||||||
|
|
@ -196,15 +196,15 @@ func TestPlaceSnakesDefault(t *testing.T) {
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(fmt.Sprint(test.BoardState.Width, test.BoardState.Height, len(test.SnakeIDs)), func(t *testing.T) {
|
t.Run(fmt.Sprint(test.BoardState.Width, test.BoardState.Height, len(test.SnakeIDs)), func(t *testing.T) {
|
||||||
require.Equal(t, test.BoardState.Width*test.BoardState.Height, int32(len(GetUnoccupiedPoints(test.BoardState, true))))
|
require.Equal(t, test.BoardState.Width*test.BoardState.Height, len(GetUnoccupiedPoints(test.BoardState, true)))
|
||||||
err := PlaceSnakesAutomatically(MaxRand, test.BoardState, test.SnakeIDs)
|
err := PlaceSnakesAutomatically(MaxRand, test.BoardState, test.SnakeIDs)
|
||||||
require.Equal(t, test.Err, err, "Snakes: %d", len(test.BoardState.Snakes))
|
require.Equal(t, test.Err, err, "Snakes: %d", len(test.BoardState.Snakes))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for i := 0; i < len(test.BoardState.Snakes); i++ {
|
for i := 0; i < len(test.BoardState.Snakes); i++ {
|
||||||
require.Len(t, test.BoardState.Snakes[i].Body, 3)
|
require.Len(t, test.BoardState.Snakes[i].Body, 3)
|
||||||
for _, point := range test.BoardState.Snakes[i].Body {
|
for _, point := range test.BoardState.Snakes[i].Body {
|
||||||
require.GreaterOrEqual(t, point.X, int32(0))
|
require.GreaterOrEqual(t, point.X, 0)
|
||||||
require.GreaterOrEqual(t, point.Y, int32(0))
|
require.GreaterOrEqual(t, point.Y, 0)
|
||||||
require.Less(t, point.X, test.BoardState.Width)
|
require.Less(t, point.X, test.BoardState.Width)
|
||||||
require.Less(t, point.Y, test.BoardState.Height)
|
require.Less(t, point.Y, test.BoardState.Height)
|
||||||
}
|
}
|
||||||
|
|
@ -400,8 +400,8 @@ func TestPlaceFood(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, test.ExpectedFood, len(test.BoardState.Food))
|
require.Equal(t, test.ExpectedFood, len(test.BoardState.Food))
|
||||||
for _, point := range test.BoardState.Food {
|
for _, point := range test.BoardState.Food {
|
||||||
require.GreaterOrEqual(t, point.X, int32(0))
|
require.GreaterOrEqual(t, point.X, 0)
|
||||||
require.GreaterOrEqual(t, point.Y, int32(0))
|
require.GreaterOrEqual(t, point.Y, 0)
|
||||||
require.Less(t, point.X, test.BoardState.Width)
|
require.Less(t, point.X, test.BoardState.Width)
|
||||||
require.Less(t, point.Y, test.BoardState.Height)
|
require.Less(t, point.Y, test.BoardState.Height)
|
||||||
}
|
}
|
||||||
|
|
@ -590,7 +590,7 @@ func TestGetDistanceBetweenPoints(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
A Point
|
A Point
|
||||||
B Point
|
B Point
|
||||||
Expected int32
|
Expected int
|
||||||
}{
|
}{
|
||||||
{Point{0, 0}, Point{0, 0}, 0},
|
{Point{0, 0}, Point{0, 0}, 0},
|
||||||
{Point{0, 0}, Point{1, 0}, 1},
|
{Point{0, 0}, Point{1, 0}, 1},
|
||||||
|
|
@ -611,8 +611,8 @@ func TestGetDistanceBetweenPoints(t *testing.T) {
|
||||||
|
|
||||||
func TestIsKnownBoardSize(t *testing.T) {
|
func TestIsKnownBoardSize(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
Width int32
|
Width int
|
||||||
Height int32
|
Height int
|
||||||
Expected bool
|
Expected bool
|
||||||
}{
|
}{
|
||||||
{1, 1, false},
|
{1, 1, false},
|
||||||
|
|
|
||||||
|
|
@ -32,25 +32,25 @@ Usage:
|
||||||
battlesnake play [flags]
|
battlesnake play [flags]
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
-W, --width int32 Width of Board (default 11)
|
-W, --width int Width of Board (default 11)
|
||||||
-H, --height int32 Height of Board (default 11)
|
-H, --height int Height of Board (default 11)
|
||||||
-n, --name stringArray Name of Snake
|
-n, --name stringArray Name of Snake
|
||||||
-u, --url stringArray URL of Snake
|
-u, --url stringArray URL of Snake
|
||||||
-S, --squad stringArray Squad of Snake
|
-S, --squad stringArray Squad of Snake
|
||||||
-t, --timeout int32 Request Timeout (default 500)
|
-t, --timeout int Request Timeout (default 500)
|
||||||
-s, --sequential Use Sequential Processing
|
-s, --sequential Use Sequential Processing
|
||||||
-g, --gametype string Type of Game Rules (default "standard")
|
-g, --gametype string Type of Game Rules (default "standard")
|
||||||
-v, --viewmap View the Map Each Turn
|
-v, --viewmap View the Map Each Turn
|
||||||
-c, --color Use color to draw the map
|
-c, --color Use color to draw the map
|
||||||
-r, --seed int Random Seed (default 1649588785026867900)
|
-r, --seed int Random Seed (default 1649588785026867900)
|
||||||
-d, --delay int32 Turn Delay in Milliseconds
|
-d, --delay int Turn Delay in Milliseconds
|
||||||
-D, --duration int32 Minimum Turn Duration in Milliseconds
|
-D, --duration int Minimum Turn Duration in Milliseconds
|
||||||
--debug-requests Log body of all requests sent
|
--debug-requests Log body of all requests sent
|
||||||
-o, --output string File path to output game state to. Existing files will be overwritten
|
-o, --output string File path to output game state to. Existing files will be overwritten
|
||||||
--foodSpawnChance int32 Percentage chance of spawning a new food every round (default 15)
|
--foodSpawnChance int Percentage chance of spawning a new food every round (default 15)
|
||||||
--minimumFood int32 Minimum food to keep on the board every turn (default 1)
|
--minimumFood int Minimum food to keep on the board every turn (default 1)
|
||||||
--hazardDamagePerTurn int32 Health damage a snake will take when ending its turn in a hazard (default 14)
|
--hazardDamagePerTurn int Health damage a snake will take when ending its turn in a hazard (default 14)
|
||||||
--shrinkEveryNTurns int32 In Royale mode, the number of turns between generating new hazards (default 25)
|
--shrinkEveryNTurns int In Royale mode, the number of turns between generating new hazards (default 25)
|
||||||
-h, --help help for play
|
-h, --help help for play
|
||||||
|
|
||||||
Global Flags:
|
Global Flags:
|
||||||
|
|
|
||||||
|
|
@ -35,28 +35,28 @@ type SnakeState struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var GameId string
|
var GameId string
|
||||||
var Turn int32
|
var Turn int
|
||||||
var HttpClient http.Client
|
var HttpClient http.Client
|
||||||
var Width int32
|
var Width int
|
||||||
var Height int32
|
var Height int
|
||||||
var Names []string
|
var Names []string
|
||||||
var URLs []string
|
var URLs []string
|
||||||
var Squads []string
|
var Squads []string
|
||||||
var Timeout int32
|
var Timeout int
|
||||||
var TurnDuration int32
|
var TurnDuration int
|
||||||
var Sequential bool
|
var Sequential bool
|
||||||
var GameType string
|
var GameType string
|
||||||
var ViewMap bool
|
var ViewMap bool
|
||||||
var UseColor bool
|
var UseColor bool
|
||||||
var Seed int64
|
var Seed int64
|
||||||
var TurnDelay int32
|
var TurnDelay int
|
||||||
var DebugRequests bool
|
var DebugRequests bool
|
||||||
var Output string
|
var Output string
|
||||||
|
|
||||||
var FoodSpawnChance int32
|
var FoodSpawnChance int
|
||||||
var MinimumFood int32
|
var MinimumFood int
|
||||||
var HazardDamagePerTurn int32
|
var HazardDamagePerTurn int
|
||||||
var ShrinkEveryNTurns int32
|
var ShrinkEveryNTurns int
|
||||||
|
|
||||||
var defaultConfig = map[string]string{
|
var defaultConfig = map[string]string{
|
||||||
// default to standard ruleset
|
// default to standard ruleset
|
||||||
|
|
@ -79,26 +79,26 @@ var playCmd = &cobra.Command{
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(playCmd)
|
rootCmd.AddCommand(playCmd)
|
||||||
|
|
||||||
playCmd.Flags().Int32VarP(&Width, "width", "W", 11, "Width of Board")
|
playCmd.Flags().IntVarP(&Width, "width", "W", 11, "Width of Board")
|
||||||
playCmd.Flags().Int32VarP(&Height, "height", "H", 11, "Height of Board")
|
playCmd.Flags().IntVarP(&Height, "height", "H", 11, "Height of Board")
|
||||||
playCmd.Flags().StringArrayVarP(&Names, "name", "n", nil, "Name of Snake")
|
playCmd.Flags().StringArrayVarP(&Names, "name", "n", nil, "Name of Snake")
|
||||||
playCmd.Flags().StringArrayVarP(&URLs, "url", "u", nil, "URL of Snake")
|
playCmd.Flags().StringArrayVarP(&URLs, "url", "u", nil, "URL of Snake")
|
||||||
playCmd.Flags().StringArrayVarP(&Names, "squad", "S", nil, "Squad of Snake")
|
playCmd.Flags().StringArrayVarP(&Names, "squad", "S", nil, "Squad of Snake")
|
||||||
playCmd.Flags().Int32VarP(&Timeout, "timeout", "t", 500, "Request Timeout")
|
playCmd.Flags().IntVarP(&Timeout, "timeout", "t", 500, "Request Timeout")
|
||||||
playCmd.Flags().BoolVarP(&Sequential, "sequential", "s", false, "Use Sequential Processing")
|
playCmd.Flags().BoolVarP(&Sequential, "sequential", "s", false, "Use Sequential Processing")
|
||||||
playCmd.Flags().StringVarP(&GameType, "gametype", "g", "standard", "Type of Game Rules")
|
playCmd.Flags().StringVarP(&GameType, "gametype", "g", "standard", "Type of Game Rules")
|
||||||
playCmd.Flags().BoolVarP(&ViewMap, "viewmap", "v", false, "View the Map Each Turn")
|
playCmd.Flags().BoolVarP(&ViewMap, "viewmap", "v", false, "View the Map Each Turn")
|
||||||
playCmd.Flags().BoolVarP(&UseColor, "color", "c", false, "Use color to draw the map")
|
playCmd.Flags().BoolVarP(&UseColor, "color", "c", false, "Use color to draw the map")
|
||||||
playCmd.Flags().Int64VarP(&Seed, "seed", "r", time.Now().UTC().UnixNano(), "Random Seed")
|
playCmd.Flags().Int64VarP(&Seed, "seed", "r", time.Now().UTC().UnixNano(), "Random Seed")
|
||||||
playCmd.Flags().Int32VarP(&TurnDelay, "delay", "d", 0, "Turn Delay in Milliseconds")
|
playCmd.Flags().IntVarP(&TurnDelay, "delay", "d", 0, "Turn Delay in Milliseconds")
|
||||||
playCmd.Flags().Int32VarP(&TurnDuration, "duration", "D", 0, "Minimum Turn Duration in Milliseconds")
|
playCmd.Flags().IntVarP(&TurnDuration, "duration", "D", 0, "Minimum Turn Duration in Milliseconds")
|
||||||
playCmd.Flags().BoolVar(&DebugRequests, "debug-requests", false, "Log body of all requests sent")
|
playCmd.Flags().BoolVar(&DebugRequests, "debug-requests", false, "Log body of all requests sent")
|
||||||
playCmd.Flags().StringVarP(&Output, "output", "o", "", "File path to output game state to. Existing files will be overwritten")
|
playCmd.Flags().StringVarP(&Output, "output", "o", "", "File path to output game state to. Existing files will be overwritten")
|
||||||
|
|
||||||
playCmd.Flags().Int32Var(&FoodSpawnChance, "foodSpawnChance", 15, "Percentage chance of spawning a new food every round")
|
playCmd.Flags().IntVar(&FoodSpawnChance, "foodSpawnChance", 15, "Percentage chance of spawning a new food every round")
|
||||||
playCmd.Flags().Int32Var(&MinimumFood, "minimumFood", 1, "Minimum food to keep on the board every turn")
|
playCmd.Flags().IntVar(&MinimumFood, "minimumFood", 1, "Minimum food to keep on the board every turn")
|
||||||
playCmd.Flags().Int32Var(&HazardDamagePerTurn, "hazardDamagePerTurn", 14, "Health damage a snake will take when ending its turn in a hazard")
|
playCmd.Flags().IntVar(&HazardDamagePerTurn, "hazardDamagePerTurn", 14, "Health damage a snake will take when ending its turn in a hazard")
|
||||||
playCmd.Flags().Int32Var(&ShrinkEveryNTurns, "shrinkEveryNTurns", 25, "In Royale mode, the number of turns between generating new hazards")
|
playCmd.Flags().IntVar(&ShrinkEveryNTurns, "shrinkEveryNTurns", 25, "In Royale mode, the number of turns between generating new hazards")
|
||||||
|
|
||||||
playCmd.Flags().SortFlags = false
|
playCmd.Flags().SortFlags = false
|
||||||
}
|
}
|
||||||
|
|
@ -256,7 +256,7 @@ func initializeBoardFromArgs(ruleset rules.Ruleset, snakeStates map[string]Snake
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
func createNextBoardState(ruleset rules.Ruleset, state *rules.BoardState, snakeStates map[string]SnakeState, turn int32) *rules.BoardState {
|
func createNextBoardState(ruleset rules.Ruleset, state *rules.BoardState, snakeStates map[string]SnakeState, turn int) *rules.BoardState {
|
||||||
var moves []rules.SnakeMove
|
var moves []rules.SnakeMove
|
||||||
if Sequential {
|
if Sequential {
|
||||||
for _, snakeState := range snakeStates {
|
for _, snakeState := range snakeStates {
|
||||||
|
|
@ -391,7 +391,7 @@ func convertRulesSnake(snake rules.Snake, snakeState SnakeState) client.Snake {
|
||||||
Body: client.CoordFromPointArray(snake.Body),
|
Body: client.CoordFromPointArray(snake.Body),
|
||||||
Latency: "0",
|
Latency: "0",
|
||||||
Head: client.CoordFromPoint(snake.Body[0]),
|
Head: client.CoordFromPoint(snake.Body[0]),
|
||||||
Length: int32(len(snake.Body)),
|
Length: len(snake.Body),
|
||||||
Shout: "",
|
Shout: "",
|
||||||
Squad: snakeState.Squad,
|
Squad: snakeState.Squad,
|
||||||
Customizations: client.Customizations{
|
Customizations: client.Customizations{
|
||||||
|
|
@ -518,15 +518,15 @@ func parseSnakeColor(color string) (int64, int64, int64) {
|
||||||
return 136, 136, 136
|
return 136, 136, 136
|
||||||
}
|
}
|
||||||
|
|
||||||
func printMap(state *rules.BoardState, snakeStates map[string]SnakeState, gameTurn int32) {
|
func printMap(state *rules.BoardState, snakeStates map[string]SnakeState, gameTurn int) {
|
||||||
var o bytes.Buffer
|
var o bytes.Buffer
|
||||||
o.WriteString(fmt.Sprintf("Ruleset: %s, Seed: %d, Turn: %v\n", GameType, Seed, gameTurn))
|
o.WriteString(fmt.Sprintf("Ruleset: %s, Seed: %d, Turn: %v\n", GameType, Seed, gameTurn))
|
||||||
board := make([][]string, state.Width)
|
board := make([][]string, state.Width)
|
||||||
for i := range board {
|
for i := range board {
|
||||||
board[i] = make([]string, state.Height)
|
board[i] = make([]string, state.Height)
|
||||||
}
|
}
|
||||||
for y := int32(0); y < state.Height; y++ {
|
for y := 0; y < state.Height; y++ {
|
||||||
for x := int32(0); x < state.Width; x++ {
|
for x := 0; x < state.Width; x++ {
|
||||||
if UseColor {
|
if UseColor {
|
||||||
board[x][y] = TERM_FG_LIGHTGRAY + "□"
|
board[x][y] = TERM_FG_LIGHTGRAY + "□"
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -579,7 +579,7 @@ func printMap(state *rules.BoardState, snakeStates map[string]SnakeState, gameTu
|
||||||
if UseColor {
|
if UseColor {
|
||||||
o.WriteString(TERM_BG_WHITE)
|
o.WriteString(TERM_BG_WHITE)
|
||||||
}
|
}
|
||||||
for x := int32(0); x < state.Width; x++ {
|
for x := 0; x < state.Width; x++ {
|
||||||
o.WriteString(board[x][y])
|
o.WriteString(board[x][y])
|
||||||
}
|
}
|
||||||
if UseColor {
|
if UseColor {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import "github.com/BattlesnakeOfficial/rules"
|
||||||
// The top-level message sent in /start, /move, and /end requests
|
// The top-level message sent in /start, /move, and /end requests
|
||||||
type SnakeRequest struct {
|
type SnakeRequest struct {
|
||||||
Game Game `json:"game"`
|
Game Game `json:"game"`
|
||||||
Turn int32 `json:"turn"`
|
Turn int `json:"turn"`
|
||||||
Board Board `json:"board"`
|
Board Board `json:"board"`
|
||||||
You Snake `json:"you"`
|
You Snake `json:"you"`
|
||||||
}
|
}
|
||||||
|
|
@ -15,14 +15,14 @@ type Game struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Ruleset Ruleset `json:"ruleset"`
|
Ruleset Ruleset `json:"ruleset"`
|
||||||
Map string `json:"map"`
|
Map string `json:"map"`
|
||||||
Timeout int32 `json:"timeout"`
|
Timeout int `json:"timeout"`
|
||||||
Source string `json:"source"`
|
Source string `json:"source"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Board provides information about the game board
|
// Board provides information about the game board
|
||||||
type Board struct {
|
type Board struct {
|
||||||
Height int32 `json:"height"`
|
Height int `json:"height"`
|
||||||
Width int32 `json:"width"`
|
Width int `json:"width"`
|
||||||
Snakes []Snake `json:"snakes"`
|
Snakes []Snake `json:"snakes"`
|
||||||
Food []Coord `json:"food"`
|
Food []Coord `json:"food"`
|
||||||
Hazards []Coord `json:"hazards"`
|
Hazards []Coord `json:"hazards"`
|
||||||
|
|
@ -33,10 +33,10 @@ type Snake struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Latency string `json:"latency"`
|
Latency string `json:"latency"`
|
||||||
Health int32 `json:"health"`
|
Health int `json:"health"`
|
||||||
Body []Coord `json:"body"`
|
Body []Coord `json:"body"`
|
||||||
Head Coord `json:"head"`
|
Head Coord `json:"head"`
|
||||||
Length int32 `json:"length"`
|
Length int `json:"length"`
|
||||||
Shout string `json:"shout"`
|
Shout string `json:"shout"`
|
||||||
Squad string `json:"squad"`
|
Squad string `json:"squad"`
|
||||||
Customizations Customizations `json:"customizations"`
|
Customizations Customizations `json:"customizations"`
|
||||||
|
|
@ -65,8 +65,8 @@ type SquadSettings rules.SquadSettings
|
||||||
|
|
||||||
// Coord represents a point on the board
|
// Coord represents a point on the board
|
||||||
type Coord struct {
|
type Coord struct {
|
||||||
X int32 `json:"x"`
|
X int `json:"x"`
|
||||||
Y int32 `json:"y"`
|
Y int `json:"y"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// The expected format of the response body from a /move request
|
// The expected format of the response body from a /move request
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ func TestConstrictorRulesetInterface(t *testing.T) {
|
||||||
|
|
||||||
func TestConstrictorModifyInitialBoardState(t *testing.T) {
|
func TestConstrictorModifyInitialBoardState(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
Height int32
|
Height int
|
||||||
Width int32
|
Width int
|
||||||
IDs []string
|
IDs []string
|
||||||
}{
|
}{
|
||||||
{1, 1, []string{}},
|
{1, 1, []string{}},
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ type Editor interface {
|
||||||
RemoveHazard(rules.Point)
|
RemoveHazard(rules.Point)
|
||||||
|
|
||||||
// Updates the body and health of a snake.
|
// Updates the body and health of a snake.
|
||||||
PlaceSnake(id string, body []rules.Point, health int32)
|
PlaceSnake(id string, body []rules.Point, health int)
|
||||||
}
|
}
|
||||||
|
|
||||||
// An Editor backed by a BoardState.
|
// An Editor backed by a BoardState.
|
||||||
|
|
@ -91,7 +91,7 @@ func (editor *BoardStateEditor) RemoveHazard(p rules.Point) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (editor *BoardStateEditor) PlaceSnake(id string, body []rules.Point, health int32) {
|
func (editor *BoardStateEditor) PlaceSnake(id string, body []rules.Point, health int) {
|
||||||
for index, snake := range editor.Snakes {
|
for index, snake := range editor.Snakes {
|
||||||
if snake.ID == id {
|
if snake.ID == id {
|
||||||
editor.Snakes[index].Body = body
|
editor.Snakes[index].Body = body
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import "github.com/BattlesnakeOfficial/rules"
|
||||||
|
|
||||||
// SetupBoard is a shortcut for looking up a map by ID and initializing a new board state with it.
|
// SetupBoard is a shortcut for looking up a map by ID and initializing a new board state with it.
|
||||||
func SetupBoard(mapID string, settings rules.Settings, width, height int, snakeIDs []string) (*rules.BoardState, error) {
|
func SetupBoard(mapID string, settings rules.Settings, width, height int, snakeIDs []string) (*rules.BoardState, error) {
|
||||||
boardState := rules.NewBoardState(int32(width), int32(height))
|
boardState := rules.NewBoardState(width, height)
|
||||||
|
|
||||||
rules.InitializeSnakes(boardState, snakeIDs)
|
rules.InitializeSnakes(boardState, snakeIDs)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,9 @@ func (m RoyaleHazardsMap) UpdateBoard(lastBoardState *rules.BoardState, settings
|
||||||
randGenerator := settings.GetRand(0)
|
randGenerator := settings.GetRand(0)
|
||||||
|
|
||||||
numShrinks := turn / settings.RoyaleSettings.ShrinkEveryNTurns
|
numShrinks := turn / settings.RoyaleSettings.ShrinkEveryNTurns
|
||||||
minX, maxX := int32(0), lastBoardState.Width-1
|
minX, maxX := 0, lastBoardState.Width-1
|
||||||
minY, maxY := int32(0), lastBoardState.Height-1
|
minY, maxY := 0, lastBoardState.Height-1
|
||||||
for i := int32(0); i < numShrinks; i++ {
|
for i := 0; i < numShrinks; i++ {
|
||||||
switch randGenerator.Intn(4) {
|
switch randGenerator.Intn(4) {
|
||||||
case 0:
|
case 0:
|
||||||
minX += 1
|
minX += 1
|
||||||
|
|
@ -62,8 +62,8 @@ func (m RoyaleHazardsMap) UpdateBoard(lastBoardState *rules.BoardState, settings
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for x := int32(0); x < lastBoardState.Width; x++ {
|
for x := 0; x < lastBoardState.Width; x++ {
|
||||||
for y := int32(0); y < lastBoardState.Height; y++ {
|
for y := 0; y < lastBoardState.Height; y++ {
|
||||||
if x < minX || x > maxX || y < minY || y > maxY {
|
if x < minX || x > maxX || y < minY || y > maxY {
|
||||||
editor.AddHazard(rules.Point{X: x, Y: y})
|
editor.AddHazard(rules.Point{X: x, Y: y})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
royale.go
12
royale.go
|
|
@ -21,7 +21,7 @@ type RoyaleRuleset struct {
|
||||||
|
|
||||||
Seed int64
|
Seed int64
|
||||||
|
|
||||||
ShrinkEveryNTurns int32
|
ShrinkEveryNTurns int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RoyaleRuleset) Name() string { return GameTypeRoyale }
|
func (r *RoyaleRuleset) Name() string { return GameTypeRoyale }
|
||||||
|
|
@ -58,9 +58,9 @@ func PopulateHazardsRoyale(b *BoardState, settings Settings, moves []SnakeMove)
|
||||||
randGenerator := rand.New(rand.NewSource(settings.RoyaleSettings.seed))
|
randGenerator := rand.New(rand.NewSource(settings.RoyaleSettings.seed))
|
||||||
|
|
||||||
numShrinks := turn / settings.RoyaleSettings.ShrinkEveryNTurns
|
numShrinks := turn / settings.RoyaleSettings.ShrinkEveryNTurns
|
||||||
minX, maxX := int32(0), b.Width-1
|
minX, maxX := 0, b.Width-1
|
||||||
minY, maxY := int32(0), b.Height-1
|
minY, maxY := 0, b.Height-1
|
||||||
for i := int32(0); i < numShrinks; i++ {
|
for i := 0; i < numShrinks; i++ {
|
||||||
switch randGenerator.Intn(4) {
|
switch randGenerator.Intn(4) {
|
||||||
case 0:
|
case 0:
|
||||||
minX += 1
|
minX += 1
|
||||||
|
|
@ -73,8 +73,8 @@ func PopulateHazardsRoyale(b *BoardState, settings Settings, moves []SnakeMove)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for x := int32(0); x < b.Width; x++ {
|
for x := 0; x < b.Width; x++ {
|
||||||
for y := int32(0); y < b.Height; y++ {
|
for y := 0; y < b.Height; y++ {
|
||||||
if x < minX || x > maxX || y < minY || y > maxY {
|
if x < minX || x > maxX || y < minY || y > maxY {
|
||||||
b.Hazards = append(b.Hazards, Point{x, y})
|
b.Hazards = append(b.Hazards, Point{x, y})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,10 @@ func TestRoyaleName(t *testing.T) {
|
||||||
func TestRoyaleHazards(t *testing.T) {
|
func TestRoyaleHazards(t *testing.T) {
|
||||||
seed := int64(25543234525)
|
seed := int64(25543234525)
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
Width int32
|
Width int
|
||||||
Height int32
|
Height int
|
||||||
Turn int32
|
Turn int
|
||||||
ShrinkEveryNTurns int32
|
ShrinkEveryNTurns int
|
||||||
Error error
|
Error error
|
||||||
ExpectedHazards []Point
|
ExpectedHazards []Point
|
||||||
}{
|
}{
|
||||||
|
|
@ -128,7 +128,7 @@ 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"}}
|
||||||
|
|
||||||
stateAfterTurn := func(prevState *BoardState, turn int32) *BoardState {
|
stateAfterTurn := func(prevState *BoardState, turn int) *BoardState {
|
||||||
nextState := prevState.Clone()
|
nextState := prevState.Clone()
|
||||||
nextState.Turn = turn - 1
|
nextState.Turn = turn - 1
|
||||||
_, err := PopulateHazardsRoyale(nextState, r.Settings(), nil)
|
_, err := PopulateHazardsRoyale(nextState, r.Settings(), nil)
|
||||||
|
|
@ -141,7 +141,7 @@ func TestRoyalDamageNextTurn(t *testing.T) {
|
||||||
next, err := r.CreateNextBoardState(prevState, m)
|
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, 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
|
||||||
|
|
||||||
|
|
@ -149,7 +149,7 @@ func TestRoyalDamageNextTurn(t *testing.T) {
|
||||||
next, err = r.CreateNextBoardState(prevState, m)
|
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, 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
|
||||||
|
|
||||||
|
|
@ -157,7 +157,7 @@ func TestRoyalDamageNextTurn(t *testing.T) {
|
||||||
next, err = r.CreateNextBoardState(prevState, m)
|
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(69), next.Snakes[0].Health)
|
require.Equal(t, 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))
|
||||||
|
|
||||||
|
|
@ -165,7 +165,7 @@ func TestRoyalDamageNextTurn(t *testing.T) {
|
||||||
next, err = r.CreateNextBoardState(prevState, 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, 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))
|
||||||
|
|
||||||
|
|
@ -174,7 +174,7 @@ func TestRoyalDamageNextTurn(t *testing.T) {
|
||||||
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)
|
||||||
require.Equal(t, int32(100), next.Snakes[0].Health)
|
require.Equal(t, 100, 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))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
32
ruleset.go
32
ruleset.go
|
|
@ -21,9 +21,9 @@ type SnakeMove struct {
|
||||||
// Settings contains all settings relevant to a game.
|
// Settings contains all settings relevant to a game.
|
||||||
// It is used by game logic to take a previous game state and produce a next game state.
|
// It is used by game logic to take a previous game state and produce a next game state.
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
FoodSpawnChance int32 `json:"foodSpawnChance"`
|
FoodSpawnChance int `json:"foodSpawnChance"`
|
||||||
MinimumFood int32 `json:"minimumFood"`
|
MinimumFood int `json:"minimumFood"`
|
||||||
HazardDamagePerTurn int32 `json:"hazardDamagePerTurn"`
|
HazardDamagePerTurn int `json:"hazardDamagePerTurn"`
|
||||||
HazardMap string `json:"hazardMap"`
|
HazardMap string `json:"hazardMap"`
|
||||||
HazardMapAuthor string `json:"hazardMapAuthor"`
|
HazardMapAuthor string `json:"hazardMapAuthor"`
|
||||||
RoyaleSettings RoyaleSettings `json:"royale"`
|
RoyaleSettings RoyaleSettings `json:"royale"`
|
||||||
|
|
@ -34,7 +34,7 @@ type Settings struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a random number generator initialized based on the seed and current turn.
|
// Get a random number generator initialized based on the seed and current turn.
|
||||||
func (settings Settings) GetRand(turn int32) Rand {
|
func (settings Settings) GetRand(turn int) Rand {
|
||||||
// Allow overriding the random generator for testing
|
// Allow overriding the random generator for testing
|
||||||
if settings.rand != nil {
|
if settings.rand != nil {
|
||||||
return settings.rand
|
return settings.rand
|
||||||
|
|
@ -65,7 +65,7 @@ func (settings Settings) WithSeed(seed int64) Settings {
|
||||||
// RoyaleSettings contains settings that are specific to the "royale" game mode
|
// RoyaleSettings contains settings that are specific to the "royale" game mode
|
||||||
type RoyaleSettings struct {
|
type RoyaleSettings struct {
|
||||||
seed int64
|
seed int64
|
||||||
ShrinkEveryNTurns int32 `json:"shrinkEveryNTurns"`
|
ShrinkEveryNTurns int `json:"shrinkEveryNTurns"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SquadSettings contains settings that are specific to the "squad" game mode
|
// SquadSettings contains settings that are specific to the "squad" game mode
|
||||||
|
|
@ -132,9 +132,9 @@ func (rb *rulesetBuilder) AddSnakeToSquad(snakeID, squadName string) *rulesetBui
|
||||||
// Ruleset constructs a customised ruleset using the parameters passed to the builder.
|
// Ruleset constructs a customised ruleset using the parameters passed to the builder.
|
||||||
func (rb rulesetBuilder) Ruleset() PipelineRuleset {
|
func (rb rulesetBuilder) Ruleset() PipelineRuleset {
|
||||||
standardRuleset := &StandardRuleset{
|
standardRuleset := &StandardRuleset{
|
||||||
FoodSpawnChance: paramsInt32(rb.params, ParamFoodSpawnChance, 0),
|
FoodSpawnChance: paramsInt(rb.params, ParamFoodSpawnChance, 0),
|
||||||
MinimumFood: paramsInt32(rb.params, ParamMinimumFood, 0),
|
MinimumFood: paramsInt(rb.params, ParamMinimumFood, 0),
|
||||||
HazardDamagePerTurn: paramsInt32(rb.params, ParamHazardDamagePerTurn, 0),
|
HazardDamagePerTurn: paramsInt(rb.params, ParamHazardDamagePerTurn, 0),
|
||||||
HazardMap: rb.params[ParamHazardMap],
|
HazardMap: rb.params[ParamHazardMap],
|
||||||
HazardMapAuthor: rb.params[ParamHazardMapAuthor],
|
HazardMapAuthor: rb.params[ParamHazardMapAuthor],
|
||||||
}
|
}
|
||||||
|
|
@ -153,7 +153,7 @@ func (rb rulesetBuilder) Ruleset() PipelineRuleset {
|
||||||
return &RoyaleRuleset{
|
return &RoyaleRuleset{
|
||||||
StandardRuleset: *standardRuleset,
|
StandardRuleset: *standardRuleset,
|
||||||
Seed: rb.seed,
|
Seed: rb.seed,
|
||||||
ShrinkEveryNTurns: paramsInt32(rb.params, ParamShrinkEveryNTurns, 0),
|
ShrinkEveryNTurns: paramsInt(rb.params, ParamShrinkEveryNTurns, 0),
|
||||||
}
|
}
|
||||||
case GameTypeSolo:
|
case GameTypeSolo:
|
||||||
return &SoloRuleset{
|
return &SoloRuleset{
|
||||||
|
|
@ -192,14 +192,14 @@ func (rb rulesetBuilder) PipelineRuleset(name string, p Pipeline) PipelineRulese
|
||||||
name: name,
|
name: name,
|
||||||
pipeline: p,
|
pipeline: p,
|
||||||
settings: Settings{
|
settings: Settings{
|
||||||
FoodSpawnChance: paramsInt32(rb.params, ParamFoodSpawnChance, 0),
|
FoodSpawnChance: paramsInt(rb.params, ParamFoodSpawnChance, 0),
|
||||||
MinimumFood: paramsInt32(rb.params, ParamMinimumFood, 0),
|
MinimumFood: paramsInt(rb.params, ParamMinimumFood, 0),
|
||||||
HazardDamagePerTurn: paramsInt32(rb.params, ParamHazardDamagePerTurn, 0),
|
HazardDamagePerTurn: paramsInt(rb.params, ParamHazardDamagePerTurn, 0),
|
||||||
HazardMap: rb.params[ParamHazardMap],
|
HazardMap: rb.params[ParamHazardMap],
|
||||||
HazardMapAuthor: rb.params[ParamHazardMapAuthor],
|
HazardMapAuthor: rb.params[ParamHazardMapAuthor],
|
||||||
RoyaleSettings: RoyaleSettings{
|
RoyaleSettings: RoyaleSettings{
|
||||||
seed: rb.seed,
|
seed: rb.seed,
|
||||||
ShrinkEveryNTurns: paramsInt32(rb.params, ParamShrinkEveryNTurns, 0),
|
ShrinkEveryNTurns: paramsInt(rb.params, ParamShrinkEveryNTurns, 0),
|
||||||
},
|
},
|
||||||
SquadSettings: SquadSettings{
|
SquadSettings: SquadSettings{
|
||||||
squadMap: rb.squadMap(),
|
squadMap: rb.squadMap(),
|
||||||
|
|
@ -224,14 +224,14 @@ func paramsBool(params map[string]string, paramName string, defaultValue bool) b
|
||||||
return defaultValue
|
return defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
// paramsInt32 returns the int32 value for the specified parameter.
|
// paramsInt returns the int value for the specified parameter.
|
||||||
// If the parameter doesn't exist, the default value will be returned.
|
// If the parameter doesn't exist, the default value will be returned.
|
||||||
// If the parameter does exist, but is not a valid int, the default value will be returned.
|
// If the parameter does exist, but is not a valid int, the default value will be returned.
|
||||||
func paramsInt32(params map[string]string, paramName string, defaultValue int32) int32 {
|
func paramsInt(params map[string]string, paramName string, defaultValue int) int {
|
||||||
if val, ok := params[paramName]; ok {
|
if val, ok := params[paramName]; ok {
|
||||||
i, err := strconv.Atoi(val)
|
i, err := strconv.Atoi(val)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return int32(i)
|
return i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return defaultValue
|
return defaultValue
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,11 @@ import (
|
||||||
_ "github.com/BattlesnakeOfficial/rules/test"
|
_ "github.com/BattlesnakeOfficial/rules/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestParamInt32(t *testing.T) {
|
func TestParamInt(t *testing.T) {
|
||||||
require.Equal(t, int32(5), paramsInt32(nil, "test", 5), "nil map")
|
require.Equal(t, 5, paramsInt(nil, "test", 5), "nil map")
|
||||||
require.Equal(t, int32(10), paramsInt32(map[string]string{}, "foo", 10), "empty map")
|
require.Equal(t, 10, paramsInt(map[string]string{}, "foo", 10), "empty map")
|
||||||
require.Equal(t, int32(10), paramsInt32(map[string]string{"hullo": "there"}, "hullo", 10), "invalid value")
|
require.Equal(t, 10, paramsInt(map[string]string{"hullo": "there"}, "hullo", 10), "invalid value")
|
||||||
require.Equal(t, int32(20), paramsInt32(map[string]string{"bonjour": "20"}, "bonjour", 20), "valid value")
|
require.Equal(t, 20, paramsInt(map[string]string{"bonjour": "20"}, "bonjour", 20), "valid value")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParamBool(t *testing.T) {
|
func TestParamBool(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -172,9 +172,9 @@ func TestRulesetBuilder(t *testing.T) {
|
||||||
require.NotNil(t, rsb.Ruleset())
|
require.NotNil(t, rsb.Ruleset())
|
||||||
require.Equal(t, expected.GameType, rsb.Ruleset().Name())
|
require.Equal(t, expected.GameType, rsb.Ruleset().Name())
|
||||||
// All the standard settings should always be copied over
|
// All the standard settings should always be copied over
|
||||||
require.Equal(t, int32(10), rsb.Ruleset().Settings().FoodSpawnChance)
|
require.Equal(t, 10, rsb.Ruleset().Settings().FoodSpawnChance)
|
||||||
require.Equal(t, int32(12), rsb.Ruleset().Settings().HazardDamagePerTurn)
|
require.Equal(t, 12, rsb.Ruleset().Settings().HazardDamagePerTurn)
|
||||||
require.Equal(t, int32(5), rsb.Ruleset().Settings().MinimumFood)
|
require.Equal(t, 5, rsb.Ruleset().Settings().MinimumFood)
|
||||||
require.Equal(t, "test", rsb.Ruleset().Settings().HazardMap)
|
require.Equal(t, "test", rsb.Ruleset().Settings().HazardMap)
|
||||||
require.Equal(t, "tester", rsb.Ruleset().Settings().HazardMapAuthor)
|
require.Equal(t, "tester", rsb.Ruleset().Settings().HazardMapAuthor)
|
||||||
})
|
})
|
||||||
|
|
@ -194,7 +194,7 @@ func TestStageFuncContract(t *testing.T) {
|
||||||
|
|
||||||
func TestRulesetBuilderGetRand(t *testing.T) {
|
func TestRulesetBuilderGetRand(t *testing.T) {
|
||||||
var seed int64 = 12345
|
var seed int64 = 12345
|
||||||
var turn int32 = 5
|
var turn int = 5
|
||||||
ruleset := rules.NewRulesetBuilder().WithSeed(seed).PipelineRuleset("example", rules.NewPipeline(rules.StageGameOverStandard))
|
ruleset := rules.NewRulesetBuilder().WithSeed(seed).PipelineRuleset("example", rules.NewPipeline(rules.StageGameOverStandard))
|
||||||
|
|
||||||
rand1 := ruleset.Settings().GetRand(turn)
|
rand1 := ruleset.Settings().GetRand(turn)
|
||||||
|
|
|
||||||
|
|
@ -121,8 +121,8 @@ func TestSquadShareSquadHealth(t *testing.T) {
|
||||||
testSnakes := []struct {
|
testSnakes := []struct {
|
||||||
SnakeID string
|
SnakeID string
|
||||||
SquadID string
|
SquadID string
|
||||||
Health int32
|
Health int
|
||||||
ExpectedHealth int32
|
ExpectedHealth int
|
||||||
}{
|
}{
|
||||||
// Red Squad
|
// Red Squad
|
||||||
{"R1", "red", 11, 88},
|
{"R1", "red", 11, 88},
|
||||||
|
|
|
||||||
12
standard.go
12
standard.go
|
|
@ -6,9 +6,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type StandardRuleset struct {
|
type StandardRuleset struct {
|
||||||
FoodSpawnChance int32 // [0, 100]
|
FoodSpawnChance int // [0, 100]
|
||||||
MinimumFood int32
|
MinimumFood int
|
||||||
HazardDamagePerTurn int32
|
HazardDamagePerTurn int
|
||||||
HazardMap string // optional
|
HazardMap string // optional
|
||||||
HazardMapAuthor string // optional
|
HazardMapAuthor string // optional
|
||||||
}
|
}
|
||||||
|
|
@ -318,7 +318,7 @@ func snakeIsOutOfHealth(s *Snake) bool {
|
||||||
return s.Health <= 0
|
return s.Health <= 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func snakeIsOutOfBounds(s *Snake, boardWidth int32, boardHeight int32) bool {
|
func snakeIsOutOfBounds(s *Snake, boardWidth int, boardHeight int) bool {
|
||||||
for _, point := range s.Body {
|
for _, point := range s.Body {
|
||||||
if (point.X < 0) || (point.X >= boardWidth) {
|
if (point.X < 0) || (point.X >= boardWidth) {
|
||||||
return true
|
return true
|
||||||
|
|
@ -391,11 +391,11 @@ func SpawnFoodStandard(b *BoardState, settings Settings, moves []SnakeMove) (boo
|
||||||
if IsInitialization(b, settings, moves) {
|
if IsInitialization(b, settings, moves) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
numCurrentFood := int32(len(b.Food))
|
numCurrentFood := int(len(b.Food))
|
||||||
if numCurrentFood < settings.MinimumFood {
|
if numCurrentFood < settings.MinimumFood {
|
||||||
return false, PlaceFoodRandomly(GlobalRand, b, settings.MinimumFood-numCurrentFood)
|
return false, PlaceFoodRandomly(GlobalRand, b, settings.MinimumFood-numCurrentFood)
|
||||||
}
|
}
|
||||||
if settings.FoodSpawnChance > 0 && int32(rand.Intn(100)) < settings.FoodSpawnChance {
|
if settings.FoodSpawnChance > 0 && int(rand.Intn(100)) < settings.FoodSpawnChance {
|
||||||
return false, PlaceFoodRandomly(GlobalRand, b, 1)
|
return false, PlaceFoodRandomly(GlobalRand, b, 1)
|
||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ func TestSanity(t *testing.T) {
|
||||||
state, err = r.ModifyInitialBoardState(state)
|
state, err = r.ModifyInitialBoardState(state)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, state)
|
require.NotNil(t, state)
|
||||||
require.Equal(t, int32(0), state.Width)
|
require.Equal(t, 0, state.Width)
|
||||||
require.Equal(t, int32(0), state.Height)
|
require.Equal(t, 0, state.Height)
|
||||||
require.Len(t, state.Food, 0)
|
require.Len(t, state.Food, 0)
|
||||||
require.Len(t, state.Snakes, 0)
|
require.Len(t, state.Snakes, 0)
|
||||||
|
|
||||||
|
|
@ -33,8 +33,8 @@ func TestSanity(t *testing.T) {
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, next)
|
require.NotNil(t, next)
|
||||||
require.Equal(t, int32(0), state.Width)
|
require.Equal(t, 0, state.Width)
|
||||||
require.Equal(t, int32(0), state.Height)
|
require.Equal(t, 0, state.Height)
|
||||||
require.Len(t, state.Snakes, 0)
|
require.Len(t, state.Snakes, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -564,9 +564,9 @@ func TestMoveSnakes(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, b.Snakes, 3)
|
require.Len(t, b.Snakes, 3)
|
||||||
|
|
||||||
require.Equal(t, int32(111111), b.Snakes[0].Health)
|
require.Equal(t, 111111, b.Snakes[0].Health)
|
||||||
require.Equal(t, int32(222222), b.Snakes[1].Health)
|
require.Equal(t, 222222, b.Snakes[1].Health)
|
||||||
require.Equal(t, int32(1), b.Snakes[2].Health)
|
require.Equal(t, 1, b.Snakes[2].Health)
|
||||||
|
|
||||||
require.Len(t, b.Snakes[0].Body, 2)
|
require.Len(t, b.Snakes[0].Body, 2)
|
||||||
require.Len(t, b.Snakes[1].Body, 4)
|
require.Len(t, b.Snakes[1].Body, 4)
|
||||||
|
|
@ -804,35 +804,35 @@ func TestReduceSnakeHealth(t *testing.T) {
|
||||||
r := StandardRuleset{}
|
r := StandardRuleset{}
|
||||||
_, err := ReduceSnakeHealthStandard(b, r.Settings(), mockSnakeMoves())
|
_, err := ReduceSnakeHealthStandard(b, r.Settings(), mockSnakeMoves())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, b.Snakes[0].Health, int32(98))
|
require.Equal(t, b.Snakes[0].Health, 98)
|
||||||
require.Equal(t, b.Snakes[1].Health, int32(1))
|
require.Equal(t, b.Snakes[1].Health, 1)
|
||||||
require.Equal(t, b.Snakes[2].Health, int32(50))
|
require.Equal(t, b.Snakes[2].Health, 50)
|
||||||
|
|
||||||
_, err = ReduceSnakeHealthStandard(b, r.Settings(), mockSnakeMoves())
|
_, err = ReduceSnakeHealthStandard(b, r.Settings(), mockSnakeMoves())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, b.Snakes[0].Health, int32(97))
|
require.Equal(t, b.Snakes[0].Health, 97)
|
||||||
require.Equal(t, b.Snakes[1].Health, int32(0))
|
require.Equal(t, b.Snakes[1].Health, 0)
|
||||||
require.Equal(t, b.Snakes[2].Health, int32(50))
|
require.Equal(t, b.Snakes[2].Health, 50)
|
||||||
|
|
||||||
_, err = ReduceSnakeHealthStandard(b, r.Settings(), mockSnakeMoves())
|
_, err = ReduceSnakeHealthStandard(b, r.Settings(), mockSnakeMoves())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, b.Snakes[0].Health, int32(96))
|
require.Equal(t, b.Snakes[0].Health, 96)
|
||||||
require.Equal(t, b.Snakes[1].Health, int32(-1))
|
require.Equal(t, b.Snakes[1].Health, -1)
|
||||||
require.Equal(t, b.Snakes[2].Health, int32(50))
|
require.Equal(t, b.Snakes[2].Health, 50)
|
||||||
|
|
||||||
_, err = ReduceSnakeHealthStandard(b, r.Settings(), mockSnakeMoves())
|
_, err = ReduceSnakeHealthStandard(b, r.Settings(), mockSnakeMoves())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, b.Snakes[0].Health, int32(95))
|
require.Equal(t, b.Snakes[0].Health, 95)
|
||||||
require.Equal(t, b.Snakes[1].Health, int32(-2))
|
require.Equal(t, b.Snakes[1].Health, -2)
|
||||||
require.Equal(t, b.Snakes[2].Health, int32(50))
|
require.Equal(t, b.Snakes[2].Health, 50)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSnakeIsOutOfHealth(t *testing.T) {
|
func TestSnakeIsOutOfHealth(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
Health int32
|
Health int
|
||||||
Expected bool
|
Expected bool
|
||||||
}{
|
}{
|
||||||
{Health: math.MinInt32, Expected: true},
|
{Health: math.MinInt, Expected: true},
|
||||||
{Health: -10, Expected: true},
|
{Health: -10, Expected: true},
|
||||||
{Health: -2, Expected: true},
|
{Health: -2, Expected: true},
|
||||||
{Health: -1, Expected: true},
|
{Health: -1, Expected: true},
|
||||||
|
|
@ -840,7 +840,7 @@ func TestSnakeIsOutOfHealth(t *testing.T) {
|
||||||
{Health: 1, Expected: false},
|
{Health: 1, Expected: false},
|
||||||
{Health: 2, Expected: false},
|
{Health: 2, Expected: false},
|
||||||
{Health: 10, Expected: false},
|
{Health: 10, Expected: false},
|
||||||
{Health: math.MaxInt32, Expected: false},
|
{Health: math.MaxInt, Expected: false},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
|
@ -850,16 +850,16 @@ func TestSnakeIsOutOfHealth(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSnakeIsOutOfBounds(t *testing.T) {
|
func TestSnakeIsOutOfBounds(t *testing.T) {
|
||||||
boardWidth := int32(10)
|
boardWidth := 10
|
||||||
boardHeight := int32(100)
|
boardHeight := 100
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
Point Point
|
Point Point
|
||||||
Expected bool
|
Expected bool
|
||||||
}{
|
}{
|
||||||
{Point{X: math.MinInt32, Y: math.MinInt32}, true},
|
{Point{X: math.MinInt, Y: math.MinInt}, true},
|
||||||
{Point{X: math.MinInt32, Y: 0}, true},
|
{Point{X: math.MinInt, Y: 0}, true},
|
||||||
{Point{X: 0, Y: math.MinInt32}, true},
|
{Point{X: 0, Y: math.MinInt}, true},
|
||||||
{Point{X: -1, Y: -1}, true},
|
{Point{X: -1, Y: -1}, true},
|
||||||
{Point{X: -1, Y: 0}, true},
|
{Point{X: -1, Y: 0}, true},
|
||||||
{Point{X: 0, Y: -1}, true},
|
{Point{X: 0, Y: -1}, true},
|
||||||
|
|
@ -876,12 +876,12 @@ func TestSnakeIsOutOfBounds(t *testing.T) {
|
||||||
{Point{X: 11, Y: 9}, true},
|
{Point{X: 11, Y: 9}, true},
|
||||||
{Point{X: 11, Y: 10}, true},
|
{Point{X: 11, Y: 10}, true},
|
||||||
{Point{X: 11, Y: 11}, true},
|
{Point{X: 11, Y: 11}, true},
|
||||||
{Point{X: math.MaxInt32, Y: 11}, true},
|
{Point{X: math.MaxInt, Y: 11}, true},
|
||||||
{Point{X: 9, Y: 99}, false},
|
{Point{X: 9, Y: 99}, false},
|
||||||
{Point{X: 9, Y: 100}, true},
|
{Point{X: 9, Y: 100}, true},
|
||||||
{Point{X: 9, Y: 101}, true},
|
{Point{X: 9, Y: 101}, true},
|
||||||
{Point{X: 9, Y: math.MaxInt32}, true},
|
{Point{X: 9, Y: math.MaxInt}, true},
|
||||||
{Point{X: math.MaxInt32, Y: math.MaxInt32}, true},
|
{Point{X: math.MaxInt, Y: math.MaxInt}, true},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
|
@ -1339,10 +1339,10 @@ func TestMaybeDamageHazards(t *testing.T) {
|
||||||
|
|
||||||
func TestHazardDamagePerTurn(t *testing.T) {
|
func TestHazardDamagePerTurn(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
Health int32
|
Health int
|
||||||
HazardDamagePerTurn int32
|
HazardDamagePerTurn int
|
||||||
Food bool
|
Food bool
|
||||||
ExpectedHealth int32
|
ExpectedHealth int
|
||||||
ExpectedEliminationCause string
|
ExpectedEliminationCause string
|
||||||
Error error
|
Error error
|
||||||
}{
|
}{
|
||||||
|
|
@ -1461,7 +1461,7 @@ func TestMaybeFeedSnakes(t *testing.T) {
|
||||||
|
|
||||||
func TestMaybeSpawnFoodMinimum(t *testing.T) {
|
func TestMaybeSpawnFoodMinimum(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
MinimumFood int32
|
MinimumFood int
|
||||||
Food []Point
|
Food []Point
|
||||||
ExpectedFood int
|
ExpectedFood int
|
||||||
}{
|
}{
|
||||||
|
|
@ -1530,7 +1530,7 @@ func TestMaybeSpawnFoodHalfChance(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
Seed int64
|
Seed int64
|
||||||
Food []Point
|
Food []Point
|
||||||
ExpectedFood int32
|
ExpectedFood int
|
||||||
}{
|
}{
|
||||||
// Use pre-tested seeds and results
|
// Use pre-tested seeds and results
|
||||||
{123, []Point{}, 1},
|
{123, []Point{}, 1},
|
||||||
|
|
@ -1556,7 +1556,7 @@ func TestMaybeSpawnFoodHalfChance(t *testing.T) {
|
||||||
rand.Seed(test.Seed)
|
rand.Seed(test.Seed)
|
||||||
_, err := SpawnFoodStandard(b, r.Settings(), mockSnakeMoves())
|
_, err := SpawnFoodStandard(b, r.Settings(), mockSnakeMoves())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, test.ExpectedFood, int32(len(b.Food)), "Seed %d", test.Seed)
|
require.Equal(t, test.ExpectedFood, len(b.Food), "Seed %d", test.Seed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ func (r *WrappedRuleset) IsGameOver(b *BoardState) (bool, error) {
|
||||||
return GameOverStandard(b, r.Settings(), nil)
|
return GameOverStandard(b, r.Settings(), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func wrap(value, min, max int32) int32 {
|
func wrap(value, min, max int) int {
|
||||||
if value < min {
|
if value < min {
|
||||||
return max
|
return max
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -250,16 +250,16 @@ func TestEdgeCrossingEating(t *testing.T) {
|
||||||
|
|
||||||
func TestWrap(t *testing.T) {
|
func TestWrap(t *testing.T) {
|
||||||
// no wrap
|
// no wrap
|
||||||
assert.Equal(t, int32(0), wrap(0, 0, 0))
|
assert.Equal(t, 0, wrap(0, 0, 0))
|
||||||
assert.Equal(t, int32(0), wrap(0, 1, 0))
|
assert.Equal(t, 0, wrap(0, 1, 0))
|
||||||
assert.Equal(t, int32(0), wrap(0, 0, 1))
|
assert.Equal(t, 0, wrap(0, 0, 1))
|
||||||
assert.Equal(t, int32(1), wrap(1, 0, 1))
|
assert.Equal(t, 1, wrap(1, 0, 1))
|
||||||
|
|
||||||
// wrap to min
|
// wrap to min
|
||||||
assert.Equal(t, int32(0), wrap(2, 0, 1))
|
assert.Equal(t, 0, wrap(2, 0, 1))
|
||||||
|
|
||||||
// wrap to max
|
// wrap to max
|
||||||
assert.Equal(t, int32(1), wrap(-1, 0, 1))
|
assert.Equal(t, 1, wrap(-1, 0, 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks that snakes moving out of bounds get wrapped to the other side.
|
// Checks that snakes moving out of bounds get wrapped to the other side.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue