add ruleset data to the calls made by the cli (name and version) (#32)
* add ruleset data to the cli (name and version) * remove double ruleset tracking with royale mode
This commit is contained in:
parent
d750b08317
commit
f31bdff4b8
11 changed files with 86 additions and 29 deletions
|
|
@ -52,9 +52,15 @@ type BoardResponse struct {
|
|||
Snakes []SnakeResponse `json:"snakes"`
|
||||
}
|
||||
|
||||
type GameResponseRuleset struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
type GameResponse struct {
|
||||
Id string `json:"id"`
|
||||
Timeout int32 `json:"timeout"`
|
||||
Id string `json:"id"`
|
||||
Timeout int32 `json:"timeout"`
|
||||
Ruleset GameResponseRuleset `json:"ruleset"`
|
||||
}
|
||||
|
||||
type ResponsePayload struct {
|
||||
|
|
@ -125,9 +131,8 @@ var run = func(cmd *cobra.Command, args []string) {
|
|||
snakes := buildSnakesFromOptions()
|
||||
|
||||
var ruleset rules.Ruleset
|
||||
var royale rules.RoyaleRuleset
|
||||
var outOfBounds []rules.Point
|
||||
ruleset, _ = getRuleset(Seed, Turn, snakes)
|
||||
ruleset = getRuleset(Seed, Turn, snakes)
|
||||
state := initializeBoardFromArgs(ruleset, snakes)
|
||||
for _, snake := range snakes {
|
||||
Battlesnakes[snake.ID] = snake
|
||||
|
|
@ -135,8 +140,8 @@ var run = func(cmd *cobra.Command, args []string) {
|
|||
|
||||
for v := false; !v; v, _ = ruleset.IsGameOver(state) {
|
||||
Turn++
|
||||
ruleset, royale = getRuleset(Seed, Turn, snakes)
|
||||
state, outOfBounds = createNextBoardState(ruleset, royale, state, outOfBounds, snakes)
|
||||
ruleset = getRuleset(Seed, Turn, snakes)
|
||||
state = createNextBoardState(ruleset, state, outOfBounds, snakes)
|
||||
if ViewMap {
|
||||
printMap(state, outOfBounds, Turn)
|
||||
} else {
|
||||
|
|
@ -153,7 +158,7 @@ var run = func(cmd *cobra.Command, args []string) {
|
|||
if snake.EliminatedCause == rules.NotEliminated {
|
||||
isDraw = false
|
||||
winner = Battlesnakes[snake.ID].Name
|
||||
sendEndRequest(state, Battlesnakes[snake.ID])
|
||||
sendEndRequest(ruleset, state, Battlesnakes[snake.ID])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -165,7 +170,7 @@ var run = func(cmd *cobra.Command, args []string) {
|
|||
}
|
||||
}
|
||||
|
||||
func getRuleset(seed int64, gameTurn int32, snakes []Battlesnake) (rules.Ruleset, rules.RoyaleRuleset) {
|
||||
func getRuleset(seed int64, gameTurn int32, snakes []Battlesnake) rules.Ruleset {
|
||||
var ruleset rules.Ruleset
|
||||
var royale rules.RoyaleRuleset
|
||||
|
||||
|
|
@ -208,7 +213,7 @@ func getRuleset(seed int64, gameTurn int32, snakes []Battlesnake) (rules.Ruleset
|
|||
default:
|
||||
ruleset = &standard
|
||||
}
|
||||
return ruleset, royale
|
||||
return ruleset
|
||||
}
|
||||
|
||||
func initializeBoardFromArgs(ruleset rules.Ruleset, snakes []Battlesnake) *rules.BoardState {
|
||||
|
|
@ -229,7 +234,7 @@ func initializeBoardFromArgs(ruleset rules.Ruleset, snakes []Battlesnake) *rules
|
|||
panic(err)
|
||||
}
|
||||
for _, snake := range snakes {
|
||||
requestBody := getIndividualBoardStateForSnake(state, snake, nil)
|
||||
requestBody := getIndividualBoardStateForSnake(state, snake, nil, ruleset)
|
||||
u, _ := url.ParseRequestURI(snake.URL)
|
||||
u.Path = path.Join(u.Path, "start")
|
||||
_, err = HttpClient.Post(u.String(), "application/json", bytes.NewBuffer(requestBody))
|
||||
|
|
@ -240,16 +245,16 @@ func initializeBoardFromArgs(ruleset rules.Ruleset, snakes []Battlesnake) *rules
|
|||
return state
|
||||
}
|
||||
|
||||
func createNextBoardState(ruleset rules.Ruleset, royale rules.RoyaleRuleset, state *rules.BoardState, outOfBounds []rules.Point, snakes []Battlesnake) (*rules.BoardState, []rules.Point) {
|
||||
func createNextBoardState(ruleset rules.Ruleset, state *rules.BoardState, outOfBounds []rules.Point, snakes []Battlesnake) *rules.BoardState {
|
||||
var moves []rules.SnakeMove
|
||||
if Sequential {
|
||||
for _, snake := range snakes {
|
||||
moves = append(moves, getMoveForSnake(state, snake, outOfBounds))
|
||||
moves = append(moves, getMoveForSnake(ruleset, state, snake, outOfBounds))
|
||||
}
|
||||
} else {
|
||||
c := make(chan rules.SnakeMove, len(snakes))
|
||||
for _, snake := range snakes {
|
||||
go getConcurrentMoveForSnake(state, snake, outOfBounds, c)
|
||||
go getConcurrentMoveForSnake(ruleset, state, snake, outOfBounds, c)
|
||||
}
|
||||
for range snakes {
|
||||
moves = append(moves, <-c)
|
||||
|
|
@ -260,27 +265,20 @@ func createNextBoardState(ruleset rules.Ruleset, royale rules.RoyaleRuleset, sta
|
|||
snake.LastMove = move.Move
|
||||
Battlesnakes[move.ID] = snake
|
||||
}
|
||||
if GameType == "royale" {
|
||||
_, err := royale.CreateNextBoardState(state, moves)
|
||||
if err != nil {
|
||||
log.Panic("[PANIC]: Error Producing Next Royale Board State")
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
state, err := ruleset.CreateNextBoardState(state, moves)
|
||||
if err != nil {
|
||||
log.Panic("[PANIC]: Error Producing Next Board State")
|
||||
panic(err)
|
||||
}
|
||||
return state, royale.OutOfBounds
|
||||
return state
|
||||
}
|
||||
|
||||
func getConcurrentMoveForSnake(state *rules.BoardState, snake Battlesnake, outOfBounds []rules.Point, c chan rules.SnakeMove) {
|
||||
c <- getMoveForSnake(state, snake, outOfBounds)
|
||||
func getConcurrentMoveForSnake(ruleset rules.Ruleset, state *rules.BoardState, snake Battlesnake, outOfBounds []rules.Point, c chan rules.SnakeMove) {
|
||||
c <- getMoveForSnake(ruleset, state, snake, outOfBounds)
|
||||
}
|
||||
|
||||
func getMoveForSnake(state *rules.BoardState, snake Battlesnake, outOfBounds []rules.Point) rules.SnakeMove {
|
||||
requestBody := getIndividualBoardStateForSnake(state, snake, outOfBounds)
|
||||
func getMoveForSnake(ruleset rules.Ruleset, state *rules.BoardState, snake Battlesnake, outOfBounds []rules.Point) rules.SnakeMove {
|
||||
requestBody := getIndividualBoardStateForSnake(state, snake, outOfBounds, ruleset)
|
||||
u, _ := url.ParseRequestURI(snake.URL)
|
||||
u.Path = path.Join(u.Path, "move")
|
||||
res, err := HttpClient.Post(u.String(), "application/json", bytes.NewBuffer(requestBody))
|
||||
|
|
@ -306,8 +304,8 @@ func getMoveForSnake(state *rules.BoardState, snake Battlesnake, outOfBounds []r
|
|||
return rules.SnakeMove{ID: snake.ID, Move: move}
|
||||
}
|
||||
|
||||
func sendEndRequest(state *rules.BoardState, snake Battlesnake) {
|
||||
requestBody := getIndividualBoardStateForSnake(state, snake, nil)
|
||||
func sendEndRequest(ruleset rules.Ruleset, state *rules.BoardState, snake Battlesnake) {
|
||||
requestBody := getIndividualBoardStateForSnake(state, snake, nil, ruleset)
|
||||
u, _ := url.ParseRequestURI(snake.URL)
|
||||
u.Path = path.Join(u.Path, "end")
|
||||
_, err := HttpClient.Post(u.String(), "application/json", bytes.NewBuffer(requestBody))
|
||||
|
|
@ -316,7 +314,7 @@ func sendEndRequest(state *rules.BoardState, snake Battlesnake) {
|
|||
}
|
||||
}
|
||||
|
||||
func getIndividualBoardStateForSnake(state *rules.BoardState, snake Battlesnake, outOfBounds []rules.Point) []byte {
|
||||
func getIndividualBoardStateForSnake(state *rules.BoardState, snake Battlesnake, outOfBounds []rules.Point, ruleset rules.Ruleset) []byte {
|
||||
var youSnake rules.Snake
|
||||
for _, snk := range state.Snakes {
|
||||
if snake.ID == snk.ID {
|
||||
|
|
@ -325,7 +323,10 @@ func getIndividualBoardStateForSnake(state *rules.BoardState, snake Battlesnake,
|
|||
}
|
||||
}
|
||||
response := ResponsePayload{
|
||||
Game: GameResponse{Id: GameId, Timeout: Timeout},
|
||||
Game: GameResponse{Id: GameId, Timeout: Timeout, Ruleset: GameResponseRuleset{
|
||||
Name: ruleset.Name(),
|
||||
Version: ruleset.Version(),
|
||||
}},
|
||||
Turn: Turn,
|
||||
Board: BoardResponse{
|
||||
Height: state.Height,
|
||||
|
|
|
|||
22
cli/commands/play_test.go
Normal file
22
cli/commands/play_test.go
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"github.com/BattlesnakeOfficial/rules"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetIndividualBoardStateForSnake(t *testing.T) {
|
||||
s1 := rules.Snake{ID: "one", Body: []rules.Point{{X: 3, Y: 3}}}
|
||||
s2 := rules.Snake{ID: "two", Body: []rules.Point{{X: 4, Y: 3}}}
|
||||
state := &rules.BoardState{
|
||||
Height: 11,
|
||||
Width: 11,
|
||||
Snakes: []rules.Snake{s1, s2},
|
||||
}
|
||||
bs := Battlesnake{Name: "one", URL: "", ID: "one"}
|
||||
requestBody := getIndividualBoardStateForSnake(state, bs, nil, &rules.StandardRuleset{})
|
||||
|
||||
expected := "{\"game\":{\"id\":\"\",\"timeout\":500,\"ruleset\":{\"name\":\"standard\",\"version\":\"1.0.0\"}},\"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\":\"\"}}"
|
||||
require.Equal(t, expected, string(requestBody))
|
||||
}
|
||||
|
|
@ -55,6 +55,10 @@ func (r *RoyaleRuleset) CreateNextBoardState(prevState *BoardState, moves []Snak
|
|||
return nextBoardState, nil
|
||||
}
|
||||
|
||||
func (r *RoyaleRuleset) Name() string { return "royale" }
|
||||
|
||||
func (r *RoyaleRuleset) Version() string { return "1.0.0" }
|
||||
|
||||
func (r *RoyaleRuleset) populateOutOfBounds(b *BoardState, turn int32) error {
|
||||
r.OutOfBounds = []Point{}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,11 @@ func TestRoyaleDefaultSanity(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestRoyaleName(t *testing.T) {
|
||||
r := RoyaleRuleset{}
|
||||
require.Equal(t, "royale", r.Name())
|
||||
}
|
||||
|
||||
func TestRoyaleOutOfBounds(t *testing.T) {
|
||||
seed := int64(25543234525)
|
||||
tests := []struct {
|
||||
|
|
|
|||
|
|
@ -62,4 +62,6 @@ type Ruleset interface {
|
|||
CreateInitialBoardState(width int32, height int32, snakeIDs []string) (*BoardState, error)
|
||||
CreateNextBoardState(prevState *BoardState, moves []SnakeMove) (*BoardState, error)
|
||||
IsGameOver(state *BoardState) (bool, error)
|
||||
Name() string
|
||||
Version() string
|
||||
}
|
||||
|
|
|
|||
2
solo.go
2
solo.go
|
|
@ -12,3 +12,5 @@ func (r *SoloRuleset) IsGameOver(b *BoardState) (bool, error) {
|
|||
}
|
||||
return true, nil
|
||||
}
|
||||
func (r *SoloRuleset) Name() string { return "solo" }
|
||||
func (r *SoloRuleset) Version() string { return "1.0.0" }
|
||||
|
|
|
|||
|
|
@ -10,6 +10,11 @@ func TestSoloRulesetInterface(t *testing.T) {
|
|||
var _ Ruleset = (*SoloRuleset)(nil)
|
||||
}
|
||||
|
||||
func TestSoloName(t *testing.T) {
|
||||
r := SoloRuleset{}
|
||||
require.Equal(t, "solo", r.Name())
|
||||
}
|
||||
|
||||
func TestSoloCreateNextBoardStateSanity(t *testing.T) {
|
||||
boardState := &BoardState{}
|
||||
r := SoloRuleset{}
|
||||
|
|
|
|||
3
squad.go
3
squad.go
|
|
@ -18,6 +18,9 @@ type SquadRuleset struct {
|
|||
|
||||
const EliminatedBySquad = "squad-eliminated"
|
||||
|
||||
func (r *SquadRuleset) Name() string { return "squad" }
|
||||
func (r *SquadRuleset) Version() string { return "1.0.0" }
|
||||
|
||||
func (r *SquadRuleset) CreateNextBoardState(prevState *BoardState, moves []SnakeMove) (*BoardState, error) {
|
||||
nextBoardState, err := r.StandardRuleset.CreateNextBoardState(prevState, moves)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,11 @@ func TestSquadRulesetInterface(t *testing.T) {
|
|||
var _ Ruleset = (*SquadRuleset)(nil)
|
||||
}
|
||||
|
||||
func TestSquadName(t *testing.T) {
|
||||
r := SquadRuleset{}
|
||||
require.Equal(t, "squad", r.Name())
|
||||
}
|
||||
|
||||
func TestSquadCreateNextBoardStateSanity(t *testing.T) {
|
||||
boardState := &BoardState{}
|
||||
r := SquadRuleset{}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ type StandardRuleset struct {
|
|||
MinimumFood int32
|
||||
}
|
||||
|
||||
func (r *StandardRuleset) Name() string { return "standard" }
|
||||
func (r *StandardRuleset) Version() string { return "1.0.0" }
|
||||
|
||||
func (r *StandardRuleset) CreateInitialBoardState(width int32, height int32, snakeIDs []string) (*BoardState, error) {
|
||||
initialBoardState := &BoardState{
|
||||
Height: height,
|
||||
|
|
|
|||
|
|
@ -34,6 +34,11 @@ func TestSanity(t *testing.T) {
|
|||
require.Len(t, state.Snakes, 0)
|
||||
}
|
||||
|
||||
func TestStandardName(t *testing.T) {
|
||||
r := StandardRuleset{}
|
||||
require.Equal(t, "standard", r.Name())
|
||||
}
|
||||
|
||||
func TestCreateInitialBoardState(t *testing.T) {
|
||||
tests := []struct {
|
||||
Height int32
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue