DEV-1703: Avoid spawning food on hazards for islands and bridges map (#112)
* move PlaceFoodFixed and PlaceSnakesInQuadrants to maps package * don't spawn food on hazards in islands/rivers and bridges maps
This commit is contained in:
parent
35e5a53005
commit
e6e36ce46f
5 changed files with 184 additions and 114 deletions
63
board.go
63
board.go
|
|
@ -189,11 +189,11 @@ func PlaceManySnakesDistributed(rand Rand, b *BoardState, snakeIDs []string) err
|
||||||
hOffset := quadHSpace / 3
|
hOffset := quadHSpace / 3
|
||||||
vOffset := quadVSpace / 3
|
vOffset := quadVSpace / 3
|
||||||
|
|
||||||
quads := make([]randomPositionBucket, 4)
|
quads := make([]RandomPositionBucket, 4)
|
||||||
|
|
||||||
// quad 1
|
// quad 1
|
||||||
quads[0] = randomPositionBucket{}
|
quads[0] = RandomPositionBucket{}
|
||||||
quads[0].fill(
|
quads[0].Fill(
|
||||||
Point{X: hOffset, Y: vOffset},
|
Point{X: hOffset, Y: vOffset},
|
||||||
Point{X: quadHSpace - hOffset, Y: vOffset},
|
Point{X: quadHSpace - hOffset, Y: vOffset},
|
||||||
Point{X: hOffset, Y: quadVSpace - vOffset},
|
Point{X: hOffset, Y: quadVSpace - vOffset},
|
||||||
|
|
@ -201,27 +201,27 @@ func PlaceManySnakesDistributed(rand Rand, b *BoardState, snakeIDs []string) err
|
||||||
)
|
)
|
||||||
|
|
||||||
// quad 2
|
// quad 2
|
||||||
quads[1] = randomPositionBucket{}
|
quads[1] = RandomPositionBucket{}
|
||||||
for _, p := range quads[0].positions {
|
for _, p := range quads[0].positions {
|
||||||
quads[1].fill(Point{X: b.Width - p.X - 1, Y: p.Y})
|
quads[1].Fill(Point{X: b.Width - p.X - 1, Y: p.Y})
|
||||||
}
|
}
|
||||||
|
|
||||||
// quad 3
|
// quad 3
|
||||||
quads[2] = randomPositionBucket{}
|
quads[2] = RandomPositionBucket{}
|
||||||
for _, p := range quads[0].positions {
|
for _, p := range quads[0].positions {
|
||||||
quads[2].fill(Point{X: p.X, Y: b.Height - p.Y - 1})
|
quads[2].Fill(Point{X: p.X, Y: b.Height - p.Y - 1})
|
||||||
}
|
}
|
||||||
|
|
||||||
// quad 4
|
// quad 4
|
||||||
quads[3] = randomPositionBucket{}
|
quads[3] = RandomPositionBucket{}
|
||||||
for _, p := range quads[0].positions {
|
for _, p := range quads[0].positions {
|
||||||
quads[3].fill(Point{X: b.Width - p.X - 1, Y: b.Height - p.Y - 1})
|
quads[3].Fill(Point{X: b.Width - p.X - 1, Y: b.Height - p.Y - 1})
|
||||||
}
|
}
|
||||||
|
|
||||||
currentQuad := rand.Intn(4) // randomly pick a quadrant to start from
|
currentQuad := rand.Intn(4) // randomly pick a quadrant to start from
|
||||||
// evenly distribute snakes across quadrants, randomly, by rotating through the quadrants
|
// evenly distribute snakes across quadrants, randomly, by rotating through the quadrants
|
||||||
for i := 0; i < len(b.Snakes); i++ {
|
for i := 0; i < len(b.Snakes); i++ {
|
||||||
p, err := quads[currentQuad].take(rand)
|
p, err := quads[currentQuad].Take(rand)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -235,51 +235,15 @@ func PlaceManySnakesDistributed(rand Rand, b *BoardState, snakeIDs []string) err
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func PlaceSnakesInQuadrants(rand Rand, b *BoardState, quadrants [][]Point) error {
|
type RandomPositionBucket struct {
|
||||||
|
|
||||||
if len(quadrants) != 4 {
|
|
||||||
return RulesetError("invalid start point configuration - not divided into quadrants")
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure all quadrants have the same number of positions
|
|
||||||
for i := 1; i < 4; i++ {
|
|
||||||
if len(quadrants[i]) != len(quadrants[0]) {
|
|
||||||
return RulesetError("invalid start point configuration - quadrants aren't even")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
quads := make([]randomPositionBucket, 4)
|
|
||||||
for i := 0; i < 4; i++ {
|
|
||||||
quads[i].fill(quadrants[i]...)
|
|
||||||
}
|
|
||||||
|
|
||||||
currentQuad := rand.Intn(4) // randomly pick a quadrant to start from
|
|
||||||
|
|
||||||
// evenly distribute snakes across quadrants, randomly, by rotating through the quadrants
|
|
||||||
for i := 0; i < len(b.Snakes); i++ {
|
|
||||||
p, err := quads[currentQuad].take(rand)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for j := 0; j < SnakeStartSize; j++ {
|
|
||||||
b.Snakes[i].Body = append(b.Snakes[i].Body, p)
|
|
||||||
}
|
|
||||||
|
|
||||||
currentQuad = (currentQuad + 1) % 4
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type randomPositionBucket struct {
|
|
||||||
positions []Point
|
positions []Point
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rpb *randomPositionBucket) fill(p ...Point) {
|
func (rpb *RandomPositionBucket) Fill(p ...Point) {
|
||||||
rpb.positions = append(rpb.positions, p...)
|
rpb.positions = append(rpb.positions, p...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rpb *randomPositionBucket) take(rand Rand) (Point, error) {
|
func (rpb *RandomPositionBucket) Take(rand Rand) (Point, error) {
|
||||||
if len(rpb.positions) == 0 {
|
if len(rpb.positions) == 0 {
|
||||||
return Point{}, RulesetError("no more positions available")
|
return Point{}, RulesetError("no more positions available")
|
||||||
}
|
}
|
||||||
|
|
@ -359,6 +323,7 @@ func PlaceFoodAutomatically(rand Rand, b *BoardState) error {
|
||||||
return PlaceFoodRandomly(rand, b, len(b.Snakes))
|
return PlaceFoodRandomly(rand, b, len(b.Snakes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: will be replaced by maps.PlaceFoodFixed
|
||||||
func PlaceFoodFixed(rand Rand, b *BoardState) error {
|
func PlaceFoodFixed(rand Rand, b *BoardState) error {
|
||||||
centerCoord := Point{(b.Width - 1) / 2, (b.Height - 1) / 2}
|
centerCoord := Point{(b.Width - 1) / 2, (b.Height - 1) / 2}
|
||||||
|
|
||||||
|
|
|
||||||
109
maps/helpers.go
109
maps/helpers.go
|
|
@ -177,3 +177,112 @@ func isOnBoard(w, h, x, y int) bool {
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func PlaceSnakesInQuadrants(rand rules.Rand, editor Editor, snakes []rules.Snake, quadrants [][]rules.Point) error {
|
||||||
|
if len(quadrants) != 4 {
|
||||||
|
return rules.RulesetError("invalid start point configuration - not divided into quadrants")
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure all quadrants have the same number of positions
|
||||||
|
for i := 1; i < 4; i++ {
|
||||||
|
if len(quadrants[i]) != len(quadrants[0]) {
|
||||||
|
return rules.RulesetError("invalid start point configuration - quadrants aren't even")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quads := make([]rules.RandomPositionBucket, 4)
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
quads[i].Fill(quadrants[i]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
currentQuad := rand.Intn(4) // randomly pick a quadrant to start from
|
||||||
|
|
||||||
|
// evenly distribute snakes across quadrants, randomly, by rotating through the quadrants
|
||||||
|
for _, snake := range snakes {
|
||||||
|
p, err := quads[currentQuad].Take(rand)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.PlaceSnake(snake.ID, []rules.Point{p, p, p}, rules.SnakeMaxHealth)
|
||||||
|
|
||||||
|
currentQuad = (currentQuad + 1) % 4
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func PlaceFoodFixed(rand rules.Rand, initialBoardState *rules.BoardState, editor Editor) error {
|
||||||
|
width, height := initialBoardState.Width, initialBoardState.Height
|
||||||
|
centerCoord := rules.Point{X: (width - 1) / 2, Y: (height - 1) / 2}
|
||||||
|
|
||||||
|
isSmallBoard := width*height < rules.BoardSizeMedium*rules.BoardSizeMedium
|
||||||
|
|
||||||
|
// Up to 4 snakes can be placed such that food is nearby on small boards.
|
||||||
|
// Otherwise, we skip this and only try to place food in the center.
|
||||||
|
snakeBodies := editor.SnakeBodies()
|
||||||
|
if len(snakeBodies) <= 4 || !isSmallBoard {
|
||||||
|
// Place 1 food within exactly 2 moves of each snake, but never towards the center or in a corner
|
||||||
|
for _, snakeBody := range snakeBodies {
|
||||||
|
snakeHead := snakeBody[0]
|
||||||
|
possibleFoodLocations := []rules.Point{
|
||||||
|
{X: snakeHead.X - 1, Y: snakeHead.Y - 1},
|
||||||
|
{X: snakeHead.X - 1, Y: snakeHead.Y + 1},
|
||||||
|
{X: snakeHead.X + 1, Y: snakeHead.Y - 1},
|
||||||
|
{X: snakeHead.X + 1, Y: snakeHead.Y + 1},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove any invalid/unwanted positions
|
||||||
|
availableFoodLocations := []rules.Point{}
|
||||||
|
for _, p := range possibleFoodLocations {
|
||||||
|
|
||||||
|
// Don't place in the center
|
||||||
|
if centerCoord == p {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore points already occupied by food or hazards
|
||||||
|
if editor.IsOccupied(p, true, true, true) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Food must be further than snake from center on at least one axis
|
||||||
|
isAwayFromCenter := false
|
||||||
|
if p.X < snakeHead.X && snakeHead.X < centerCoord.X {
|
||||||
|
isAwayFromCenter = true
|
||||||
|
} else if centerCoord.X < snakeHead.X && snakeHead.X < p.X {
|
||||||
|
isAwayFromCenter = true
|
||||||
|
} else if p.Y < snakeHead.Y && snakeHead.Y < centerCoord.Y {
|
||||||
|
isAwayFromCenter = true
|
||||||
|
} else if centerCoord.Y < snakeHead.Y && snakeHead.Y < p.Y {
|
||||||
|
isAwayFromCenter = true
|
||||||
|
}
|
||||||
|
if !isAwayFromCenter {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't spawn food in corners
|
||||||
|
if (p.X == 0 || p.X == (width-1)) && (p.Y == 0 || p.Y == (height-1)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
availableFoodLocations = append(availableFoodLocations, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(availableFoodLocations) <= 0 {
|
||||||
|
return rules.ErrorNoRoomForFood
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select randomly from available locations
|
||||||
|
placedFood := availableFoodLocations[rand.Intn(len(availableFoodLocations))]
|
||||||
|
editor.AddFood(placedFood)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, try to place 1 food in center of board for dramatic purposes
|
||||||
|
if !editor.IsOccupied(centerCoord, true, true, true) {
|
||||||
|
editor.AddFood(centerCoord)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -115,3 +115,33 @@ func TestUpdateBoard(t *testing.T) {
|
||||||
require.Equal(t, []rules.Point{{X: 3, Y: 4}, {X: 3, Y: 5}, {X: 2, Y: 2}}, boardState.Hazards)
|
require.Equal(t, []rules.Point{{X: 3, Y: 4}, {X: 3, Y: 5}, {X: 2, Y: 2}}, boardState.Hazards)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPlaceFoodFixed(t *testing.T) {
|
||||||
|
initialBoardState := rules.NewBoardState(rules.BoardSizeMedium, rules.BoardSizeMedium)
|
||||||
|
editor := maps.NewBoardStateEditor(initialBoardState.Clone())
|
||||||
|
|
||||||
|
editor.PlaceSnake("1", []rules.Point{{X: 1, Y: 1}}, 100)
|
||||||
|
editor.PlaceSnake("2", []rules.Point{{X: 9, Y: 1}}, 100)
|
||||||
|
editor.PlaceSnake("3", []rules.Point{{X: 4, Y: 9}}, 100)
|
||||||
|
editor.PlaceSnake("4", []rules.Point{{X: 6, Y: 6}}, 100)
|
||||||
|
|
||||||
|
// Hazards everywhere except for the expected food placements
|
||||||
|
for x := 0; x < initialBoardState.Width; x++ {
|
||||||
|
for y := 0; y < initialBoardState.Height; y++ {
|
||||||
|
editor.AddHazard(rules.Point{X: x, Y: y})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
editor.RemoveHazard(rules.Point{X: 0, Y: 2})
|
||||||
|
editor.RemoveHazard(rules.Point{X: 8, Y: 0})
|
||||||
|
editor.RemoveHazard(rules.Point{X: 3, Y: 10})
|
||||||
|
editor.RemoveHazard(rules.Point{X: 7, Y: 7})
|
||||||
|
|
||||||
|
err := maps.PlaceFoodFixed(rules.MaxRand, initialBoardState, editor)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
food := editor.Food()
|
||||||
|
require.Contains(t, food, rules.Point{X: 0, Y: 2})
|
||||||
|
require.Contains(t, food, rules.Point{X: 8, Y: 0})
|
||||||
|
require.Contains(t, food, rules.Point{X: 3, Y: 10})
|
||||||
|
require.Contains(t, food, rules.Point{X: 7, Y: 7})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,59 +12,23 @@ func init() {
|
||||||
globalRegistry.RegisterMap("hz_islands_bridges_lg", IslandsAndBridgesLargeHazardsMap{})
|
globalRegistry.RegisterMap("hz_islands_bridges_lg", IslandsAndBridgesLargeHazardsMap{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupRiverAndBridgesBoard(startingPositions [][]rules.Point, hazards []rules.Point, lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
func setupRiverAndBridgesBoard(startingPositions [][]rules.Point, hazards []rules.Point, initialBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
||||||
width := lastBoardState.Width
|
|
||||||
height := lastBoardState.Height
|
|
||||||
|
|
||||||
numSnakes := len(lastBoardState.Snakes)
|
|
||||||
if numSnakes == 0 {
|
|
||||||
return rules.RulesetError("too few snakes - at least one snake must be present")
|
|
||||||
}
|
|
||||||
|
|
||||||
rand := settings.GetRand(0)
|
rand := settings.GetRand(0)
|
||||||
|
|
||||||
snakeIDs := make([]string, 0, len(lastBoardState.Snakes))
|
err := PlaceSnakesInQuadrants(rand, editor, initialBoardState.Snakes, startingPositions)
|
||||||
for _, snake := range lastBoardState.Snakes {
|
|
||||||
snakeIDs = append(snakeIDs, snake.ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
tempBoardState := rules.NewBoardState(width, height)
|
|
||||||
tempBoardState.Snakes = make([]rules.Snake, len(snakeIDs))
|
|
||||||
|
|
||||||
for i := 0; i < len(snakeIDs); i++ {
|
|
||||||
tempBoardState.Snakes[i] = rules.Snake{
|
|
||||||
ID: snakeIDs[i],
|
|
||||||
Health: rules.SnakeMaxHealth,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err := rules.PlaceSnakesInQuadrants(rand, tempBoardState, startingPositions)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = rules.PlaceFoodFixed(rand, tempBoardState)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy food from temp board state
|
|
||||||
for _, f := range tempBoardState.Food {
|
|
||||||
// skip the center food
|
|
||||||
if f.X == lastBoardState.Width/2 && f.Y == lastBoardState.Height/2 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
editor.AddFood(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy snakes from temp board state
|
|
||||||
for _, snake := range tempBoardState.Snakes {
|
|
||||||
editor.PlaceSnake(snake.ID, snake.Body, snake.Health)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, p := range hazards {
|
for _, p := range hazards {
|
||||||
editor.AddHazard(p)
|
editor.AddHazard(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = PlaceFoodFixed(rand, initialBoardState, editor)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,12 +64,11 @@ Each river has one or two 1-square "bridges" over them`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m RiverAndBridgesMediumHazardsMap) SetupBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
func (m RiverAndBridgesMediumHazardsMap) SetupBoard(initialBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
||||||
if !m.Meta().BoardSizes.IsAllowable(lastBoardState.Width, lastBoardState.Height) {
|
if err := m.Meta().Validate(initialBoardState); err != nil {
|
||||||
return rules.RulesetError("This map can only be played on a 11x11 board")
|
return err
|
||||||
}
|
}
|
||||||
|
return setupRiverAndBridgesBoard(riversAndBridgesMediumStartPositions, riversAndBridgesMediumHazards, initialBoardState, settings, editor)
|
||||||
return setupRiverAndBridgesBoard(riversAndBridgesMediumStartPositions, riversAndBridgesMediumHazards, lastBoardState, settings, editor)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m RiverAndBridgesMediumHazardsMap) UpdateBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
func (m RiverAndBridgesMediumHazardsMap) UpdateBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
||||||
|
|
@ -171,12 +134,12 @@ Each river has one or two 1-square "bridges" over them`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m RiverAndBridgesLargeHazardsMap) SetupBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
func (m RiverAndBridgesLargeHazardsMap) SetupBoard(initialBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
||||||
if !m.Meta().BoardSizes.IsAllowable(lastBoardState.Width, lastBoardState.Height) {
|
if err := m.Meta().Validate(initialBoardState); err != nil {
|
||||||
return rules.RulesetError("This map can only be played on a 19x19 board")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return setupRiverAndBridgesBoard(riversAndBridgesLargeStartPositions, riversAndBridgesLargeHazards, lastBoardState, settings, editor)
|
return setupRiverAndBridgesBoard(riversAndBridgesLargeStartPositions, riversAndBridgesLargeHazards, initialBoardState, settings, editor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m RiverAndBridgesLargeHazardsMap) UpdateBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
func (m RiverAndBridgesLargeHazardsMap) UpdateBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
||||||
|
|
@ -270,12 +233,12 @@ Each river has one or two 1-square "bridges" over them`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m RiverAndBridgesExtraLargeHazardsMap) SetupBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
func (m RiverAndBridgesExtraLargeHazardsMap) SetupBoard(initialBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
||||||
if !m.Meta().BoardSizes.IsAllowable(lastBoardState.Width, lastBoardState.Height) {
|
if err := m.Meta().Validate(initialBoardState); err != nil {
|
||||||
return rules.RulesetError("This map can only be played on a 25x25 board")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return setupRiverAndBridgesBoard(riversAndBridgesExtraLargeStartPositions, riversAndBridgesExtraLargeHazards, lastBoardState, settings, editor)
|
return setupRiverAndBridgesBoard(riversAndBridgesExtraLargeStartPositions, riversAndBridgesExtraLargeHazards, initialBoardState, settings, editor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m RiverAndBridgesExtraLargeHazardsMap) UpdateBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
func (m RiverAndBridgesExtraLargeHazardsMap) UpdateBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
||||||
|
|
@ -384,12 +347,12 @@ func (m IslandsAndBridgesMediumHazardsMap) Meta() Metadata {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m IslandsAndBridgesMediumHazardsMap) SetupBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
func (m IslandsAndBridgesMediumHazardsMap) SetupBoard(initialBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
||||||
if !m.Meta().BoardSizes.IsAllowable(lastBoardState.Width, lastBoardState.Height) {
|
if err := m.Meta().Validate(initialBoardState); err != nil {
|
||||||
return rules.RulesetError("This map can only be played on a 11x11 board")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return setupRiverAndBridgesBoard(islandsAndBridgesMediumStartPositions, islandsAndBridgesMediumHazards, lastBoardState, settings, editor)
|
return setupRiverAndBridgesBoard(islandsAndBridgesMediumStartPositions, islandsAndBridgesMediumHazards, initialBoardState, settings, editor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m IslandsAndBridgesMediumHazardsMap) UpdateBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
func (m IslandsAndBridgesMediumHazardsMap) UpdateBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
||||||
|
|
@ -470,12 +433,12 @@ func (m IslandsAndBridgesLargeHazardsMap) Meta() Metadata {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m IslandsAndBridgesLargeHazardsMap) SetupBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
func (m IslandsAndBridgesLargeHazardsMap) SetupBoard(initialBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
||||||
if !m.Meta().BoardSizes.IsAllowable(lastBoardState.Width, lastBoardState.Height) {
|
if err := m.Meta().Validate(initialBoardState); err != nil {
|
||||||
return rules.RulesetError("This map can only be played on a 19x19 board")
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return setupRiverAndBridgesBoard(islandsAndBridgesLargeStartPositions, islandsAndBridgesLargeHazards, lastBoardState, settings, editor)
|
return setupRiverAndBridgesBoard(islandsAndBridgesLargeStartPositions, islandsAndBridgesLargeHazards, initialBoardState, settings, editor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m IslandsAndBridgesLargeHazardsMap) UpdateBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
func (m IslandsAndBridgesLargeHazardsMap) UpdateBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRiversAndBridgetsHazardsMap(t *testing.T) {
|
func TestRiversAndBridgesHazardsMap(t *testing.T) {
|
||||||
// check error handling
|
// check error handling
|
||||||
m := maps.RiverAndBridgesMediumHazardsMap{}
|
m := maps.RiverAndBridgesMediumHazardsMap{}
|
||||||
settings := rules.Settings{}
|
settings := rules.Settings{}
|
||||||
|
|
@ -40,5 +40,8 @@ func TestRiversAndBridgetsHazardsMap(t *testing.T) {
|
||||||
err = test.Map.SetupBoard(state, settings, editor)
|
err = test.Map.SetupBoard(state, settings, editor)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEmpty(t, state.Hazards)
|
require.NotEmpty(t, state.Hazards)
|
||||||
|
require.Len(t, state.Food, 1)
|
||||||
|
food := state.Food[0]
|
||||||
|
require.NotContains(t, state.Hazards, food)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue