Skip to content

Commit

Permalink
Rivers and Bridges map refactor (#103)
Browse files Browse the repository at this point in the history
* Separated out rivers and bridges into its own file with three map variants

* fixing tags

* removed extra 4 starting positions from the medium map since it only supports 8 players

* update GetUnoccupiedPoints to consider hazards with a flag

* use new utility method to fine unoccupied points and enforce map sizes

* changed up casting to make IsAllowable() more usable
  • Loading branch information
chris-bsnake authored Aug 19, 2022
1 parent 7d769b0 commit f82cfe5
Show file tree
Hide file tree
Showing 10 changed files with 484 additions and 347 deletions.
18 changes: 14 additions & 4 deletions board.go
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ func PlaceFoodFixed(rand Rand, b *BoardState) error {

// Finally, always place 1 food in center of board for dramatic purposes
isCenterOccupied := true
unoccupiedPoints := GetUnoccupiedPoints(b, true)
unoccupiedPoints := GetUnoccupiedPoints(b, true, false)
for _, point := range unoccupiedPoints {
if point == centerCoord {
isCenterOccupied = false
Expand All @@ -450,7 +450,7 @@ func PlaceFoodFixed(rand Rand, b *BoardState) error {
// PlaceFoodRandomly adds up to n new food to the board in random unoccupied squares
func PlaceFoodRandomly(rand Rand, b *BoardState, n int) error {
for i := 0; i < n; i++ {
unoccupiedPoints := GetUnoccupiedPoints(b, false)
unoccupiedPoints := GetUnoccupiedPoints(b, false, false)
if len(unoccupiedPoints) > 0 {
newFood := unoccupiedPoints[rand.Intn(len(unoccupiedPoints))]
b.Food = append(b.Food, newFood)
Expand All @@ -468,7 +468,7 @@ func absInt(n int) int {

func GetEvenUnoccupiedPoints(b *BoardState) []Point {
// Start by getting unoccupied points
unoccupiedPoints := GetUnoccupiedPoints(b, true)
unoccupiedPoints := GetUnoccupiedPoints(b, true, false)

// Create a new array to hold points that are even
evenUnoccupiedPoints := []Point{}
Expand All @@ -494,14 +494,15 @@ func removeCenterCoord(b *BoardState, points []Point) []Point {
return noCenterPoints
}

func GetUnoccupiedPoints(b *BoardState, includePossibleMoves bool) []Point {
func GetUnoccupiedPoints(b *BoardState, includePossibleMoves bool, includeHazards bool) []Point {
pointIsOccupied := map[int]map[int]bool{}
for _, p := range b.Food {
if _, xExists := pointIsOccupied[p.X]; !xExists {
pointIsOccupied[p.X] = map[int]bool{}
}
pointIsOccupied[p.X][p.Y] = true
}

for _, snake := range b.Snakes {
if snake.EliminatedCause != NotEliminated {
continue
Expand Down Expand Up @@ -529,6 +530,15 @@ func GetUnoccupiedPoints(b *BoardState, includePossibleMoves bool) []Point {
}
}

if includeHazards {
for _, p := range b.Hazards {
if _, xExists := pointIsOccupied[p.X]; !xExists {
pointIsOccupied[p.X] = map[int]bool{}
}
pointIsOccupied[p.X][p.Y] = true
}
}

unoccupiedPoints := []Point{}
for x := 0; x < b.Width; x++ {
for y := 0; y < b.Height; y++ {
Expand Down
33 changes: 31 additions & 2 deletions board_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ func TestPlaceSnakesDefault(t *testing.T) {

for _, test := range tests {
t.Run(fmt.Sprint(test.BoardState.Width, test.BoardState.Height, len(test.SnakeIDs)), func(t *testing.T) {
require.Equal(t, test.BoardState.Width*test.BoardState.Height, len(GetUnoccupiedPoints(test.BoardState, true)))
require.Equal(t, test.BoardState.Width*test.BoardState.Height, len(GetUnoccupiedPoints(test.BoardState, true, false)))
err := PlaceSnakesAutomatically(MaxRand, test.BoardState, test.SnakeIDs)
require.Equal(t, test.Err, err, "Snakes: %d", len(test.BoardState.Snakes))
if err == nil {
Expand Down Expand Up @@ -769,10 +769,39 @@ func TestGetUnoccupiedPoints(t *testing.T) {
},
[]Point{{2, 1}},
},
{
&BoardState{
Height: 1,
Width: 1,
Hazards: []Point{{0, 0}},
},
[]Point{},
},
{
&BoardState{
Height: 2,
Width: 2,
Hazards: []Point{{1, 1}},
},
[]Point{{0, 0}, {0, 1}, {1, 0}},
},
{
&BoardState{
Height: 2,
Width: 3,
Food: []Point{{1, 1}, {2, 0}},
Snakes: []Snake{
{Body: []Point{{0, 0}, {1, 0}, {1, 1}}},
{Body: []Point{{0, 1}}},
},
Hazards: []Point{{0, 0}, {1, 0}},
},
[]Point{{2, 1}},
},
}

for _, test := range tests {
unoccupiedPoints := GetUnoccupiedPoints(test.Board, true)
unoccupiedPoints := GetUnoccupiedPoints(test.Board, true, true)
require.Equal(t, len(test.Expected), len(unoccupiedPoints))
for i, e := range test.Expected {
require.Equal(t, e, unoccupiedPoints[i])
Expand Down
14 changes: 14 additions & 0 deletions maps/game_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ func (d sizes) IsUnlimited() bool {
return len(d) == 1 && d[0].Width == 0
}

func (d sizes) IsAllowable(Width int, Height int) bool {
if d.IsUnlimited() {
return true
}

for _, size := range d {
if size.Width == uint(Width) && size.Height == uint(Height) {
return true
}
}

return false
}

// AnySize creates sizes for a board that has no fixed sizes (supports unlimited sizes).
func AnySize() sizes {
return sizes{Dimensions{Width: 0, Height: 0}}
Expand Down
Loading

0 comments on commit f82cfe5

Please sign in to comment.