Add missing ruleset params to request body and --debug-requests option (#55)
* fix sending of new params * add royale and squad settings to requests * add --debug-requests option * update test for request body and add helper Co-authored-by: Penelope Phippen <penelope@hey.com>
This commit is contained in:
parent
0cba5eff59
commit
31faba642c
5 changed files with 179 additions and 10 deletions
|
|
@ -54,9 +54,29 @@ type BoardResponse struct {
|
||||||
Snakes []SnakeResponse `json:"snakes"`
|
Snakes []SnakeResponse `json:"snakes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GameResponseRulesetSettings struct {
|
||||||
|
HazardDamagePerTurn int32 `json:"hazardDamagePerTurn"`
|
||||||
|
FoodSpawnChance int32 `json:"foodSpawnChance"`
|
||||||
|
MinimumFood int32 `json:"minimumFood"`
|
||||||
|
RoyaleSettings RoyaleSettings `json:"royale"`
|
||||||
|
SquadSettings SquadSettings `json:"squad"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RoyaleSettings struct {
|
||||||
|
ShrinkEveryNTurns int32 `json:"shrinkEveryNTurns"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SquadSettings struct {
|
||||||
|
AllowBodyCollisions bool `json:"allowBodyCollisions"`
|
||||||
|
SharedElimination bool `json:"sharedElimination"`
|
||||||
|
SharedHealth bool `json:"sharedHealth"`
|
||||||
|
SharedLength bool `json:"sharedLength"`
|
||||||
|
}
|
||||||
|
|
||||||
type GameResponseRuleset struct {
|
type GameResponseRuleset struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
|
Settings GameResponseRulesetSettings `json:"settings"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GameResponse struct {
|
type GameResponse struct {
|
||||||
|
|
@ -101,6 +121,7 @@ var GameType string
|
||||||
var ViewMap bool
|
var ViewMap bool
|
||||||
var Seed int64
|
var Seed int64
|
||||||
var TurnDelay int32
|
var TurnDelay int32
|
||||||
|
var DebugRequests bool
|
||||||
|
|
||||||
var FoodSpawnChance int32
|
var FoodSpawnChance int32
|
||||||
var MinimumFood int32
|
var MinimumFood int32
|
||||||
|
|
@ -128,6 +149,7 @@ func init() {
|
||||||
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().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().Int32VarP(&TurnDelay, "delay", "d", 0, "Turn Delay in Milliseconds")
|
||||||
|
playCmd.Flags().BoolVar(&DebugRequests, "debug-requests", false, "Log body of all requests sent")
|
||||||
|
|
||||||
playCmd.Flags().Int32Var(&FoodSpawnChance, "foodSpawnChance", 15, "Percentage chance of spawning a new food every round")
|
playCmd.Flags().Int32Var(&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().Int32Var(&MinimumFood, "minimumFood", 1, "Minimum food to keep on the board every turn")
|
||||||
|
|
@ -263,6 +285,9 @@ func initializeBoardFromArgs(ruleset rules.Ruleset, snakes []Battlesnake) *rules
|
||||||
requestBody := getIndividualBoardStateForSnake(state, snake, ruleset)
|
requestBody := getIndividualBoardStateForSnake(state, snake, ruleset)
|
||||||
u, _ := url.ParseRequestURI(snake.URL)
|
u, _ := url.ParseRequestURI(snake.URL)
|
||||||
u.Path = path.Join(u.Path, "start")
|
u.Path = path.Join(u.Path, "start")
|
||||||
|
if DebugRequests {
|
||||||
|
log.Printf("POST %s: %v", u, string(requestBody))
|
||||||
|
}
|
||||||
_, err = HttpClient.Post(u.String(), "application/json", bytes.NewBuffer(requestBody))
|
_, err = HttpClient.Post(u.String(), "application/json", bytes.NewBuffer(requestBody))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[WARN]: Request to %v failed", u.String())
|
log.Printf("[WARN]: Request to %v failed", u.String())
|
||||||
|
|
@ -326,6 +351,9 @@ func getMoveForSnake(ruleset rules.Ruleset, state *rules.BoardState, snake Battl
|
||||||
requestBody := getIndividualBoardStateForSnake(state, snake, ruleset)
|
requestBody := getIndividualBoardStateForSnake(state, snake, ruleset)
|
||||||
u, _ := url.ParseRequestURI(snake.URL)
|
u, _ := url.ParseRequestURI(snake.URL)
|
||||||
u.Path = path.Join(u.Path, "move")
|
u.Path = path.Join(u.Path, "move")
|
||||||
|
if DebugRequests {
|
||||||
|
log.Printf("POST %s: %v", u, string(requestBody))
|
||||||
|
}
|
||||||
res, err := HttpClient.Post(u.String(), "application/json", bytes.NewBuffer(requestBody))
|
res, err := HttpClient.Post(u.String(), "application/json", bytes.NewBuffer(requestBody))
|
||||||
move := snake.LastMove
|
move := snake.LastMove
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -353,6 +381,9 @@ func sendEndRequest(ruleset rules.Ruleset, state *rules.BoardState, snake Battle
|
||||||
requestBody := getIndividualBoardStateForSnake(state, snake, ruleset)
|
requestBody := getIndividualBoardStateForSnake(state, snake, ruleset)
|
||||||
u, _ := url.ParseRequestURI(snake.URL)
|
u, _ := url.ParseRequestURI(snake.URL)
|
||||||
u.Path = path.Join(u.Path, "end")
|
u.Path = path.Join(u.Path, "end")
|
||||||
|
if DebugRequests {
|
||||||
|
log.Printf("POST %s: %v", u, string(requestBody))
|
||||||
|
}
|
||||||
_, err := HttpClient.Post(u.String(), "application/json", bytes.NewBuffer(requestBody))
|
_, err := HttpClient.Post(u.String(), "application/json", bytes.NewBuffer(requestBody))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[WARN]: Request to %v failed", u.String())
|
log.Printf("[WARN]: Request to %v failed", u.String())
|
||||||
|
|
@ -371,6 +402,20 @@ func getIndividualBoardStateForSnake(state *rules.BoardState, snake Battlesnake,
|
||||||
Game: GameResponse{Id: GameId, Timeout: Timeout, Ruleset: GameResponseRuleset{
|
Game: GameResponse{Id: GameId, Timeout: Timeout, Ruleset: GameResponseRuleset{
|
||||||
Name: ruleset.Name(),
|
Name: ruleset.Name(),
|
||||||
Version: "cli", // TODO: Use GitHub Release Version
|
Version: "cli", // TODO: Use GitHub Release Version
|
||||||
|
Settings: GameResponseRulesetSettings{
|
||||||
|
HazardDamagePerTurn: HazardDamagePerTurn,
|
||||||
|
FoodSpawnChance: FoodSpawnChance,
|
||||||
|
MinimumFood: MinimumFood,
|
||||||
|
RoyaleSettings: RoyaleSettings{
|
||||||
|
ShrinkEveryNTurns: ShrinkEveryNTurns,
|
||||||
|
},
|
||||||
|
SquadSettings: SquadSettings{
|
||||||
|
AllowBodyCollisions: true,
|
||||||
|
SharedElimination: true,
|
||||||
|
SharedHealth: true,
|
||||||
|
SharedLength: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
}},
|
}},
|
||||||
Turn: Turn,
|
Turn: Turn,
|
||||||
Board: BoardResponse{
|
Board: BoardResponse{
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/BattlesnakeOfficial/rules"
|
"github.com/BattlesnakeOfficial/rules"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetIndividualBoardStateForSnake(t *testing.T) {
|
func TestGetIndividualBoardStateForSnake(t *testing.T) {
|
||||||
|
|
@ -18,6 +17,5 @@ func TestGetIndividualBoardStateForSnake(t *testing.T) {
|
||||||
snake := Battlesnake{Name: "one", URL: "", ID: "one"}
|
snake := Battlesnake{Name: "one", URL: "", ID: "one"}
|
||||||
requestBody := getIndividualBoardStateForSnake(state, snake, &rules.StandardRuleset{})
|
requestBody := getIndividualBoardStateForSnake(state, snake, &rules.StandardRuleset{})
|
||||||
|
|
||||||
expected := "{\"game\":{\"id\":\"\",\"timeout\":500,\"ruleset\":{\"name\":\"standard\",\"version\":\"cli\"}},\"turn\":0,\"board\":{\"height\":11,\"width\":11,\"food\":[],\"hazards\":[],\"snakes\":[{\"id\":\"one\",\"name\":\"\",\"health\":0,\"body\":[{\"x\":3,\"y\":3}],\"latency\":\"0\",\"head\":{\"x\":3,\"y\":3},\"length\":1,\"shout\":\"\",\"squad\":\"\"},{\"id\":\"two\",\"name\":\"\",\"health\":0,\"body\":[{\"x\":4,\"y\":3}],\"latency\":\"0\",\"head\":{\"x\":4,\"y\":3},\"length\":1,\"shout\":\"\",\"squad\":\"\"}]},\"you\":{\"id\":\"one\",\"name\":\"\",\"health\":0,\"body\":[{\"x\":3,\"y\":3}],\"latency\":\"0\",\"head\":{\"x\":3,\"y\":3},\"length\":1,\"shout\":\"\",\"squad\":\"\"}}"
|
rules.RequireJSONMatchesFixture(t, "testdata/snake_request_body.json", string(requestBody))
|
||||||
require.Equal(t, expected, string(requestBody))
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
90
cli/commands/testdata/snake_request_body.json
vendored
Normal file
90
cli/commands/testdata/snake_request_body.json
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
{
|
||||||
|
"game": {
|
||||||
|
"id": "",
|
||||||
|
"timeout": 500,
|
||||||
|
"ruleset": {
|
||||||
|
"name": "standard",
|
||||||
|
"version": "cli",
|
||||||
|
"settings": {
|
||||||
|
"hazardDamagePerTurn": 14,
|
||||||
|
"foodSpawnChance": 15,
|
||||||
|
"minimumFood": 1,
|
||||||
|
"royale": {
|
||||||
|
"shrinkEveryNTurns": 25
|
||||||
|
},
|
||||||
|
"squad": {
|
||||||
|
"allowBodyCollisions": true,
|
||||||
|
"sharedElimination": true,
|
||||||
|
"sharedHealth": true,
|
||||||
|
"sharedLength": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"turn": 0,
|
||||||
|
"board": {
|
||||||
|
"height": 11,
|
||||||
|
"width": 11,
|
||||||
|
"food": [],
|
||||||
|
"hazards": [],
|
||||||
|
"snakes": [
|
||||||
|
{
|
||||||
|
"id": "one",
|
||||||
|
"name": "",
|
||||||
|
"health": 0,
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"x": 3,
|
||||||
|
"y": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"latency": "0",
|
||||||
|
"head": {
|
||||||
|
"x": 3,
|
||||||
|
"y": 3
|
||||||
|
},
|
||||||
|
"length": 1,
|
||||||
|
"shout": "",
|
||||||
|
"squad": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "two",
|
||||||
|
"name": "",
|
||||||
|
"health": 0,
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"x": 4,
|
||||||
|
"y": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"latency": "0",
|
||||||
|
"head": {
|
||||||
|
"x": 4,
|
||||||
|
"y": 3
|
||||||
|
},
|
||||||
|
"length": 1,
|
||||||
|
"shout": "",
|
||||||
|
"squad": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"you": {
|
||||||
|
"id": "one",
|
||||||
|
"name": "",
|
||||||
|
"health": 0,
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"x": 3,
|
||||||
|
"y": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"latency": "0",
|
||||||
|
"head": {
|
||||||
|
"x": 3,
|
||||||
|
"y": 3
|
||||||
|
},
|
||||||
|
"length": 1,
|
||||||
|
"shout": "",
|
||||||
|
"squad": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
11
ruleset.go
11
ruleset.go
|
|
@ -39,11 +39,12 @@ type Point struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Snake struct {
|
type Snake struct {
|
||||||
ID string
|
ID string
|
||||||
Body []Point
|
Body []Point
|
||||||
Health int32
|
Health int32
|
||||||
EliminatedCause string
|
EliminatedCause string
|
||||||
EliminatedBy string
|
EliminatedOnTurn int32
|
||||||
|
EliminatedBy string
|
||||||
}
|
}
|
||||||
|
|
||||||
type SnakeMove struct {
|
type SnakeMove struct {
|
||||||
|
|
|
||||||
35
test_utils.go
Normal file
35
test_utils.go
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
package rules
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"flag"
|
||||||
|
"io/ioutil"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
var updateFixtures = flag.Bool("update-fixtures", false, "Regenerate fixtures in testdata based on current test output")
|
||||||
|
|
||||||
|
// RequireJSONMatchesFixture asserts that the JSON text in actual matches the
|
||||||
|
// JSON read from filename, without taking into account whitespace and
|
||||||
|
// ordering. Files can be specified relative to the calling test (e.g.
|
||||||
|
// testdata/example.json). To regenerate the expected test data automatically
|
||||||
|
// after making a code change, pass the `-update-fixtures` flag to `go test`.
|
||||||
|
func RequireJSONMatchesFixture(t *testing.T, filename string, actual string) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
if *updateFixtures {
|
||||||
|
var indented bytes.Buffer
|
||||||
|
err := json.Indent(&indented, []byte(actual), "", " ")
|
||||||
|
require.NoError(t, err, "Failed to indent JSON")
|
||||||
|
err = ioutil.WriteFile(filename, indented.Bytes(), 0644)
|
||||||
|
require.NoError(t, err, "Failed to update fixture", filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedData, err := ioutil.ReadFile(filename)
|
||||||
|
require.NoError(t, err, "Failed to read fixture", filename)
|
||||||
|
|
||||||
|
require.JSONEq(t, string(expectedData), actual)
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue