* Convert errors to constant error interfaces.
This commit is contained in:
parent
f0f2ff5961
commit
2cbf8884bf
3 changed files with 38 additions and 26 deletions
|
|
@ -37,3 +37,7 @@ type Ruleset interface {
|
||||||
CreateNextBoardState(prevState *BoardState, moves []SnakeMove) (*BoardState, error)
|
CreateNextBoardState(prevState *BoardState, moves []SnakeMove) (*BoardState, error)
|
||||||
IsGameOver(state *BoardState) (bool, error)
|
IsGameOver(state *BoardState) (bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RulesetError string
|
||||||
|
|
||||||
|
func (err RulesetError) Error() string { return string(err) }
|
||||||
|
|
|
||||||
26
standard.go
26
standard.go
|
|
@ -1,7 +1,7 @@
|
||||||
package rules
|
package rules
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
//"errors"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
@ -28,6 +28,14 @@ const (
|
||||||
EliminatedByOutOfBounds = "wall-collision"
|
EliminatedByOutOfBounds = "wall-collision"
|
||||||
|
|
||||||
// TODO - Error consts
|
// TODO - Error consts
|
||||||
|
ErrorTooManySnakes = RulesetError("too many snakes for fixed start positions")
|
||||||
|
ErrorNoRoomForSnake = RulesetError("not enough space to place snake")
|
||||||
|
ErrorNoRoomForFood = RulesetError("not enough space to place food")
|
||||||
|
ErrorNoMoveFound = RulesetError("move not provided for snake")
|
||||||
|
|
||||||
|
// TODO: These two error codes seem equivalent, Do we only need one ?
|
||||||
|
ErrorSizeZeroBody = RulesetError("found snake with zero size body")
|
||||||
|
ErrorZeroLengthSnake = RulesetError("snake is length zero")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *StandardRuleset) CreateInitialBoardState(width int32, height int32, snakeIDs []string) (*BoardState, error) {
|
func (r *StandardRuleset) CreateInitialBoardState(width int32, height int32, snakeIDs []string) (*BoardState, error) {
|
||||||
|
|
@ -80,7 +88,7 @@ func (r *StandardRuleset) placeSnakesFixed(b *BoardState) error {
|
||||||
|
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if len(b.Snakes) > len(startPoints) {
|
if len(b.Snakes) > len(startPoints) {
|
||||||
return errors.New("too many snakes for fixed start positions")
|
return ErrorTooManySnakes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Randomly order them
|
// Randomly order them
|
||||||
|
|
@ -103,7 +111,7 @@ func (r *StandardRuleset) placeSnakesRandomly(b *BoardState) error {
|
||||||
for i := 0; i < len(b.Snakes); i++ {
|
for i := 0; i < len(b.Snakes); i++ {
|
||||||
unoccupiedPoints := r.getEvenUnoccupiedPoints(b)
|
unoccupiedPoints := r.getEvenUnoccupiedPoints(b)
|
||||||
if len(unoccupiedPoints) <= 0 {
|
if len(unoccupiedPoints) <= 0 {
|
||||||
return errors.New("not enough space to place snake")
|
return ErrorNoRoomForSnake
|
||||||
}
|
}
|
||||||
p := unoccupiedPoints[rand.Intn(len(unoccupiedPoints))]
|
p := unoccupiedPoints[rand.Intn(len(unoccupiedPoints))]
|
||||||
for j := 0; j < SnakeStartSize; j++ {
|
for j := 0; j < SnakeStartSize; j++ {
|
||||||
|
|
@ -147,7 +155,7 @@ func (r *StandardRuleset) placeFoodFixed(b *BoardState) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(availableFoodLocations) <= 0 {
|
if len(availableFoodLocations) <= 0 {
|
||||||
return errors.New("not enough space to place food")
|
return ErrorNoRoomForFood
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select randomly from available locations
|
// Select randomly from available locations
|
||||||
|
|
@ -166,7 +174,7 @@ func (r *StandardRuleset) placeFoodFixed(b *BoardState) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if isCenterOccupied {
|
if isCenterOccupied {
|
||||||
return errors.New("not enough space to place food")
|
return ErrorNoRoomForFood
|
||||||
}
|
}
|
||||||
b.Food = append(b.Food, centerCoord)
|
b.Food = append(b.Food, centerCoord)
|
||||||
|
|
||||||
|
|
@ -255,7 +263,7 @@ func (r *StandardRuleset) moveSnakes(b *BoardState, moves []SnakeMove) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(snake.Body) == 0 {
|
if len(snake.Body) == 0 {
|
||||||
return errors.New("found snake with zero size body")
|
return ErrorSizeZeroBody
|
||||||
}
|
}
|
||||||
moveFound := false
|
moveFound := false
|
||||||
for _, move := range moves {
|
for _, move := range moves {
|
||||||
|
|
@ -265,7 +273,7 @@ func (r *StandardRuleset) moveSnakes(b *BoardState, moves []SnakeMove) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !moveFound {
|
if !moveFound {
|
||||||
return errors.New("move not provided for snake")
|
return ErrorNoMoveFound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -346,7 +354,7 @@ func (r *StandardRuleset) maybeEliminateSnakes(b *BoardState) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if len(snake.Body) <= 0 {
|
if len(snake.Body) <= 0 {
|
||||||
return errors.New("snake is length zero")
|
return ErrorZeroLengthSnake
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.snakeIsOutOfHealth(snake) {
|
if r.snakeIsOutOfHealth(snake) {
|
||||||
|
|
@ -374,7 +382,7 @@ func (r *StandardRuleset) maybeEliminateSnakes(b *BoardState) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if len(snake.Body) <= 0 {
|
if len(snake.Body) <= 0 {
|
||||||
return errors.New("snake is length zero")
|
return ErrorZeroLengthSnake
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for self-collisions first
|
// Check for self-collisions first
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package rules
|
package rules
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
//"errors"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
@ -49,8 +49,8 @@ func TestCreateInitialBoardState(t *testing.T) {
|
||||||
{2, 2, []string{"one"}, 1, nil},
|
{2, 2, []string{"one"}, 1, nil},
|
||||||
{9, 8, []string{"one"}, 1, nil},
|
{9, 8, []string{"one"}, 1, nil},
|
||||||
{2, 2, []string{"one", "two"}, 0, nil},
|
{2, 2, []string{"one", "two"}, 0, nil},
|
||||||
{1, 1, []string{"one", "two"}, 2, errors.New("not enough space to place snake")},
|
{1, 1, []string{"one", "two"}, 2, ErrorNoRoomForSnake},
|
||||||
{1, 2, []string{"one", "two"}, 2, errors.New("not enough space to place snake")},
|
{1, 2, []string{"one", "two"}, 2, ErrorNoRoomForSnake},
|
||||||
{BoardSizeSmall, BoardSizeSmall, []string{"one", "two"}, 3, nil},
|
{BoardSizeSmall, BoardSizeSmall, []string{"one", "two"}, 3, nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,7 +95,7 @@ func TestPlaceSnakes(t *testing.T) {
|
||||||
Height: 1,
|
Height: 1,
|
||||||
Snakes: make([]Snake, 2),
|
Snakes: make([]Snake, 2),
|
||||||
},
|
},
|
||||||
errors.New("not enough space to place snake"),
|
ErrorNoRoomForSnake,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
&BoardState{
|
&BoardState{
|
||||||
|
|
@ -103,7 +103,7 @@ func TestPlaceSnakes(t *testing.T) {
|
||||||
Height: 1,
|
Height: 1,
|
||||||
Snakes: make([]Snake, 2),
|
Snakes: make([]Snake, 2),
|
||||||
},
|
},
|
||||||
errors.New("not enough space to place snake"),
|
ErrorNoRoomForSnake,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
&BoardState{
|
&BoardState{
|
||||||
|
|
@ -111,7 +111,7 @@ func TestPlaceSnakes(t *testing.T) {
|
||||||
Height: 2,
|
Height: 2,
|
||||||
Snakes: make([]Snake, 2),
|
Snakes: make([]Snake, 2),
|
||||||
},
|
},
|
||||||
errors.New("not enough space to place snake"),
|
ErrorNoRoomForSnake,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
&BoardState{
|
&BoardState{
|
||||||
|
|
@ -135,7 +135,7 @@ func TestPlaceSnakes(t *testing.T) {
|
||||||
Height: 5,
|
Height: 5,
|
||||||
Snakes: make([]Snake, 49),
|
Snakes: make([]Snake, 49),
|
||||||
},
|
},
|
||||||
errors.New("not enough space to place snake"),
|
ErrorNoRoomForSnake,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
&BoardState{
|
&BoardState{
|
||||||
|
|
@ -143,7 +143,7 @@ func TestPlaceSnakes(t *testing.T) {
|
||||||
Height: 10,
|
Height: 10,
|
||||||
Snakes: make([]Snake, 50),
|
Snakes: make([]Snake, 50),
|
||||||
},
|
},
|
||||||
errors.New("not enough space to place snake"),
|
ErrorNoRoomForSnake,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
&BoardState{
|
&BoardState{
|
||||||
|
|
@ -151,7 +151,7 @@ func TestPlaceSnakes(t *testing.T) {
|
||||||
Height: 2,
|
Height: 2,
|
||||||
Snakes: make([]Snake, 51),
|
Snakes: make([]Snake, 51),
|
||||||
},
|
},
|
||||||
errors.New("not enough space to place snake"),
|
ErrorNoRoomForSnake,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
&BoardState{
|
&BoardState{
|
||||||
|
|
@ -175,7 +175,7 @@ func TestPlaceSnakes(t *testing.T) {
|
||||||
Height: BoardSizeSmall,
|
Height: BoardSizeSmall,
|
||||||
Snakes: make([]Snake, 9),
|
Snakes: make([]Snake, 9),
|
||||||
},
|
},
|
||||||
errors.New("too many snakes for fixed start positions"),
|
ErrorTooManySnakes,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
&BoardState{
|
&BoardState{
|
||||||
|
|
@ -191,7 +191,7 @@ func TestPlaceSnakes(t *testing.T) {
|
||||||
Height: BoardSizeMedium,
|
Height: BoardSizeMedium,
|
||||||
Snakes: make([]Snake, 9),
|
Snakes: make([]Snake, 9),
|
||||||
},
|
},
|
||||||
errors.New("too many snakes for fixed start positions"),
|
ErrorTooManySnakes,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
&BoardState{
|
&BoardState{
|
||||||
|
|
@ -207,7 +207,7 @@ func TestPlaceSnakes(t *testing.T) {
|
||||||
Height: BoardSizeLarge,
|
Height: BoardSizeLarge,
|
||||||
Snakes: make([]Snake, 9),
|
Snakes: make([]Snake, 9),
|
||||||
},
|
},
|
||||||
errors.New("too many snakes for fixed start positions"),
|
ErrorTooManySnakes,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -488,7 +488,7 @@ func TestCreateNextBoardState(t *testing.T) {
|
||||||
Food: []Point{{0, 0}, {1, 0}},
|
Food: []Point{{0, 0}, {1, 0}},
|
||||||
},
|
},
|
||||||
[]SnakeMove{},
|
[]SnakeMove{},
|
||||||
errors.New("move not provided for snake"),
|
ErrorNoMoveFound,
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -513,7 +513,7 @@ func TestCreateNextBoardState(t *testing.T) {
|
||||||
{ID: "one", Move: MoveUp},
|
{ID: "one", Move: MoveUp},
|
||||||
{ID: "two", Move: MoveDown},
|
{ID: "two", Move: MoveDown},
|
||||||
},
|
},
|
||||||
errors.New("found snake with zero size body"),
|
ErrorSizeZeroBody,
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -940,7 +940,7 @@ func TestMoveSnakesWrongID(t *testing.T) {
|
||||||
|
|
||||||
r := StandardRuleset{}
|
r := StandardRuleset{}
|
||||||
err := r.moveSnakes(b, moves)
|
err := r.moveSnakes(b, moves)
|
||||||
require.Equal(t, errors.New("move not provided for snake"), err)
|
require.Equal(t, ErrorNoMoveFound, err) // TODO: @bvanvugt is this a place where an "==" comparision should be used ?
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMoveSnakesNotEnoughMoves(t *testing.T) {
|
func TestMoveSnakesNotEnoughMoves(t *testing.T) {
|
||||||
|
|
@ -965,7 +965,7 @@ func TestMoveSnakesNotEnoughMoves(t *testing.T) {
|
||||||
|
|
||||||
r := StandardRuleset{}
|
r := StandardRuleset{}
|
||||||
err := r.moveSnakes(b, moves)
|
err := r.moveSnakes(b, moves)
|
||||||
require.Equal(t, errors.New("move not provided for snake"), err)
|
require.Equal(t, ErrorNoMoveFound, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMoveSnakesExtraMovesIgnored(t *testing.T) {
|
func TestMoveSnakesExtraMovesIgnored(t *testing.T) {
|
||||||
|
|
@ -1366,7 +1366,7 @@ func TestMaybeEliminateSnakes(t *testing.T) {
|
||||||
},
|
},
|
||||||
[]string{NotEliminated},
|
[]string{NotEliminated},
|
||||||
[]string{""},
|
[]string{""},
|
||||||
errors.New("snake is length zero"),
|
ErrorZeroLengthSnake,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Single Starvation",
|
"Single Starvation",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue