Add new constants for standard ruleset errors, resolves #5 (#24)

* Convert errors to constant error interfaces.
This commit is contained in:
md-hexdrive 2020-12-11 12:50:52 -05:00 committed by GitHub
parent f0f2ff5961
commit 2cbf8884bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 26 deletions

View file

@ -37,3 +37,7 @@ type Ruleset interface {
CreateNextBoardState(prevState *BoardState, moves []SnakeMove) (*BoardState, error)
IsGameOver(state *BoardState) (bool, error)
}
type RulesetError string
func (err RulesetError) Error() string { return string(err) }

View file

@ -1,7 +1,7 @@
package rules
import (
"errors"
//"errors"
"math/rand"
"sort"
)
@ -28,6 +28,14 @@ const (
EliminatedByOutOfBounds = "wall-collision"
// 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) {
@ -80,7 +88,7 @@ func (r *StandardRuleset) placeSnakesFixed(b *BoardState) error {
// Sanity check
if len(b.Snakes) > len(startPoints) {
return errors.New("too many snakes for fixed start positions")
return ErrorTooManySnakes
}
// Randomly order them
@ -103,7 +111,7 @@ func (r *StandardRuleset) placeSnakesRandomly(b *BoardState) error {
for i := 0; i < len(b.Snakes); i++ {
unoccupiedPoints := r.getEvenUnoccupiedPoints(b)
if len(unoccupiedPoints) <= 0 {
return errors.New("not enough space to place snake")
return ErrorNoRoomForSnake
}
p := unoccupiedPoints[rand.Intn(len(unoccupiedPoints))]
for j := 0; j < SnakeStartSize; j++ {
@ -147,7 +155,7 @@ func (r *StandardRuleset) placeFoodFixed(b *BoardState) error {
}
if len(availableFoodLocations) <= 0 {
return errors.New("not enough space to place food")
return ErrorNoRoomForFood
}
// Select randomly from available locations
@ -166,7 +174,7 @@ func (r *StandardRuleset) placeFoodFixed(b *BoardState) error {
}
}
if isCenterOccupied {
return errors.New("not enough space to place food")
return ErrorNoRoomForFood
}
b.Food = append(b.Food, centerCoord)
@ -255,7 +263,7 @@ func (r *StandardRuleset) moveSnakes(b *BoardState, moves []SnakeMove) error {
}
if len(snake.Body) == 0 {
return errors.New("found snake with zero size body")
return ErrorSizeZeroBody
}
moveFound := false
for _, move := range moves {
@ -265,7 +273,7 @@ func (r *StandardRuleset) moveSnakes(b *BoardState, moves []SnakeMove) error {
}
}
if !moveFound {
return errors.New("move not provided for snake")
return ErrorNoMoveFound
}
}
@ -346,7 +354,7 @@ func (r *StandardRuleset) maybeEliminateSnakes(b *BoardState) error {
continue
}
if len(snake.Body) <= 0 {
return errors.New("snake is length zero")
return ErrorZeroLengthSnake
}
if r.snakeIsOutOfHealth(snake) {
@ -374,7 +382,7 @@ func (r *StandardRuleset) maybeEliminateSnakes(b *BoardState) error {
continue
}
if len(snake.Body) <= 0 {
return errors.New("snake is length zero")
return ErrorZeroLengthSnake
}
// Check for self-collisions first

View file

@ -1,7 +1,7 @@
package rules
import (
"errors"
//"errors"
"math"
"math/rand"
"testing"
@ -49,8 +49,8 @@ func TestCreateInitialBoardState(t *testing.T) {
{2, 2, []string{"one"}, 1, nil},
{9, 8, []string{"one"}, 1, nil},
{2, 2, []string{"one", "two"}, 0, nil},
{1, 1, []string{"one", "two"}, 2, errors.New("not enough space to place snake")},
{1, 2, []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, ErrorNoRoomForSnake},
{BoardSizeSmall, BoardSizeSmall, []string{"one", "two"}, 3, nil},
}
@ -95,7 +95,7 @@ func TestPlaceSnakes(t *testing.T) {
Height: 1,
Snakes: make([]Snake, 2),
},
errors.New("not enough space to place snake"),
ErrorNoRoomForSnake,
},
{
&BoardState{
@ -103,7 +103,7 @@ func TestPlaceSnakes(t *testing.T) {
Height: 1,
Snakes: make([]Snake, 2),
},
errors.New("not enough space to place snake"),
ErrorNoRoomForSnake,
},
{
&BoardState{
@ -111,7 +111,7 @@ func TestPlaceSnakes(t *testing.T) {
Height: 2,
Snakes: make([]Snake, 2),
},
errors.New("not enough space to place snake"),
ErrorNoRoomForSnake,
},
{
&BoardState{
@ -135,7 +135,7 @@ func TestPlaceSnakes(t *testing.T) {
Height: 5,
Snakes: make([]Snake, 49),
},
errors.New("not enough space to place snake"),
ErrorNoRoomForSnake,
},
{
&BoardState{
@ -143,7 +143,7 @@ func TestPlaceSnakes(t *testing.T) {
Height: 10,
Snakes: make([]Snake, 50),
},
errors.New("not enough space to place snake"),
ErrorNoRoomForSnake,
},
{
&BoardState{
@ -151,7 +151,7 @@ func TestPlaceSnakes(t *testing.T) {
Height: 2,
Snakes: make([]Snake, 51),
},
errors.New("not enough space to place snake"),
ErrorNoRoomForSnake,
},
{
&BoardState{
@ -175,7 +175,7 @@ func TestPlaceSnakes(t *testing.T) {
Height: BoardSizeSmall,
Snakes: make([]Snake, 9),
},
errors.New("too many snakes for fixed start positions"),
ErrorTooManySnakes,
},
{
&BoardState{
@ -191,7 +191,7 @@ func TestPlaceSnakes(t *testing.T) {
Height: BoardSizeMedium,
Snakes: make([]Snake, 9),
},
errors.New("too many snakes for fixed start positions"),
ErrorTooManySnakes,
},
{
&BoardState{
@ -207,7 +207,7 @@ func TestPlaceSnakes(t *testing.T) {
Height: BoardSizeLarge,
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}},
},
[]SnakeMove{},
errors.New("move not provided for snake"),
ErrorNoMoveFound,
nil,
},
{
@ -513,7 +513,7 @@ func TestCreateNextBoardState(t *testing.T) {
{ID: "one", Move: MoveUp},
{ID: "two", Move: MoveDown},
},
errors.New("found snake with zero size body"),
ErrorSizeZeroBody,
nil,
},
{
@ -940,7 +940,7 @@ func TestMoveSnakesWrongID(t *testing.T) {
r := StandardRuleset{}
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) {
@ -965,7 +965,7 @@ func TestMoveSnakesNotEnoughMoves(t *testing.T) {
r := StandardRuleset{}
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) {
@ -1366,7 +1366,7 @@ func TestMaybeEliminateSnakes(t *testing.T) {
},
[]string{NotEliminated},
[]string{""},
errors.New("snake is length zero"),
ErrorZeroLengthSnake,
},
{
"Single Starvation",