[Custom Map] Single Player Maze (#81)
* Commit from Stream
We got the maze working decently well!
Started off with exploring the repo a bit and getting used to the Map
stuff
The Maze is working pretty well except the mazes that are generated
aren't actually complete-able yet. They end up creating spaces that are
blocked off from the rest of the map
The maze generation algo is based off 'Recursive division method' mostly
following this Wiki
This looked to always create a 'valid' maze, while mine doesn't so need
to figure out what my bug is, cause I'm pretty sure there is one!
* I think we got maze generation working!
Did a lot, should have commited more lol
Got map generation working where I can see it go frame by frame, and
think we squashed the last few bugs with wall generation and hole
cutting
Now need it to actually make a new maze when you finish this first one
* We can run on a bigger board now, and we place the food randomly on the board after you grab it the first time
* Make sure my health is always 100 so don't have to worry about that lol
* Fix placing of food on maze to NOT be on an existing hazard and after 3 foods make a new maze
* Maze generation works better now and a bit of cleanup
* Committing old code
* Got state saving as Hazards Bits Working well, I think whats up next is making the map grow each level
* Draw maze in the center of the board, the maze grows as you complete levels until it fills the entire board
* Ran go fmt
* Remove my little debugging script that I added
* Revert changes I made initially to the map interface
* Move my copy-pasted printMap function to my map specifically
* Go fmt
* Write some doc comments and fix some weird code artifacts
* A few more comments and one last go fmt
* Cut less holes, this makes the maze more exciting
* Add version to Metadata and go fmt again
* Can collapse this down
* Random food spawns are more fun for sure
* add minimal support for serving a game to the board UI
* We did 3 main things here:
- Fixed the bug where hazards were getting multi-stacked
- Fixed the bug where the food could spawn on top of the snake head
- Fixed the lint errors
* Games aren't infinite now, they end by not spawning a food when you have reached a certain number of turns at the max board size
* Extract some functions to make deciding when the game is over easier
* Get evil mode implemented to force the game to end
* Fix small bugs about where we spawned the food in evil mode
* Have the snake keep growing by adding tail segments to match the current level. We start at two length because 1 lenth snakes look weird on the board since they don't have a neck to orient themselves. Here we also fix a bug where evil mode was trying to place food off the map
* Run go fmt
* Add the missing meta-data pieces
* Support a smaller board without the change of infinite loops and change the name of the maze
* Rename the actual struct and fix the tests to not make extra snakes when the map doesn't support it
* Revert "add minimal support for serving a game to the board UI"
This reverts commit 0ac3592c7669ab1bccd7bd3322adffbef5e911ce.
* add minimal support for serving a game to the board UI
* Cleanup and extract and function to place food so we don't have basically the same body twice. This also will prevent the initial food spawn from being right next to the snake
* Revert "add minimal support for serving a game to the board UI"
This reverts commit c1a3b134213dabf44df56e3ca1e6d30ff8aaa516.
* Fix lint
* 2 length snakes are silly, so lets start with 3 each time
* We start out with 3 length snakes, and a fixed set of map sizes
Co-authored-by: Rob O'Dwyer <odwyerrob@gmail.com>
2022-07-04 13:25:28 -04:00
|
|
|
package maps
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"strconv"
|
|
|
|
|
|
|
|
|
|
"bufio"
|
|
|
|
|
"bytes"
|
|
|
|
|
"log"
|
|
|
|
|
"os"
|
|
|
|
|
|
|
|
|
|
"github.com/BattlesnakeOfficial/rules"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// When this is flipped to `true` TWO things happen
|
2023-02-19 17:12:03 +00:00
|
|
|
// 1. More println style debugging is done
|
|
|
|
|
// 2. We print out the current game board in between each room sub-division,
|
|
|
|
|
// and wait for the CLI User to hit enter to sub-divide the next room. This
|
|
|
|
|
// allows you to see the maze get generated in realtime, which was super useful
|
|
|
|
|
// while debugging issues in the maze generation
|
[Custom Map] Single Player Maze (#81)
* Commit from Stream
We got the maze working decently well!
Started off with exploring the repo a bit and getting used to the Map
stuff
The Maze is working pretty well except the mazes that are generated
aren't actually complete-able yet. They end up creating spaces that are
blocked off from the rest of the map
The maze generation algo is based off 'Recursive division method' mostly
following this Wiki
This looked to always create a 'valid' maze, while mine doesn't so need
to figure out what my bug is, cause I'm pretty sure there is one!
* I think we got maze generation working!
Did a lot, should have commited more lol
Got map generation working where I can see it go frame by frame, and
think we squashed the last few bugs with wall generation and hole
cutting
Now need it to actually make a new maze when you finish this first one
* We can run on a bigger board now, and we place the food randomly on the board after you grab it the first time
* Make sure my health is always 100 so don't have to worry about that lol
* Fix placing of food on maze to NOT be on an existing hazard and after 3 foods make a new maze
* Maze generation works better now and a bit of cleanup
* Committing old code
* Got state saving as Hazards Bits Working well, I think whats up next is making the map grow each level
* Draw maze in the center of the board, the maze grows as you complete levels until it fills the entire board
* Ran go fmt
* Remove my little debugging script that I added
* Revert changes I made initially to the map interface
* Move my copy-pasted printMap function to my map specifically
* Go fmt
* Write some doc comments and fix some weird code artifacts
* A few more comments and one last go fmt
* Cut less holes, this makes the maze more exciting
* Add version to Metadata and go fmt again
* Can collapse this down
* Random food spawns are more fun for sure
* add minimal support for serving a game to the board UI
* We did 3 main things here:
- Fixed the bug where hazards were getting multi-stacked
- Fixed the bug where the food could spawn on top of the snake head
- Fixed the lint errors
* Games aren't infinite now, they end by not spawning a food when you have reached a certain number of turns at the max board size
* Extract some functions to make deciding when the game is over easier
* Get evil mode implemented to force the game to end
* Fix small bugs about where we spawned the food in evil mode
* Have the snake keep growing by adding tail segments to match the current level. We start at two length because 1 lenth snakes look weird on the board since they don't have a neck to orient themselves. Here we also fix a bug where evil mode was trying to place food off the map
* Run go fmt
* Add the missing meta-data pieces
* Support a smaller board without the change of infinite loops and change the name of the maze
* Rename the actual struct and fix the tests to not make extra snakes when the map doesn't support it
* Revert "add minimal support for serving a game to the board UI"
This reverts commit 0ac3592c7669ab1bccd7bd3322adffbef5e911ce.
* add minimal support for serving a game to the board UI
* Cleanup and extract and function to place food so we don't have basically the same body twice. This also will prevent the initial food spawn from being right next to the snake
* Revert "add minimal support for serving a game to the board UI"
This reverts commit c1a3b134213dabf44df56e3ca1e6d30ff8aaa516.
* Fix lint
* 2 length snakes are silly, so lets start with 3 each time
* We start out with 3 length snakes, and a fixed set of map sizes
Co-authored-by: Rob O'Dwyer <odwyerrob@gmail.com>
2022-07-04 13:25:28 -04:00
|
|
|
const DEBUG_MAZE_GENERATION = false
|
|
|
|
|
|
|
|
|
|
const INITIAL_MAZE_SIZE = 7
|
|
|
|
|
|
|
|
|
|
const TURNS_AT_MAX_SIZE = 5
|
|
|
|
|
|
|
|
|
|
const EVIL_MODE_DISTANCE_TO_FOOD = 5
|
|
|
|
|
|
|
|
|
|
const MAX_TRIES = 100
|
|
|
|
|
|
|
|
|
|
type SoloMazeMap struct{}
|
|
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
|
mazeMap := SoloMazeMap{}
|
|
|
|
|
globalRegistry.RegisterMap(mazeMap.ID(), mazeMap)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m SoloMazeMap) ID() string {
|
|
|
|
|
return "solo_maze"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m SoloMazeMap) Meta() Metadata {
|
|
|
|
|
return Metadata{
|
|
|
|
|
Name: "Solo Maze",
|
|
|
|
|
Description: "Solo Maze where you need to find the food",
|
|
|
|
|
Author: "coreyja",
|
|
|
|
|
Version: 1,
|
|
|
|
|
MinPlayers: 1,
|
|
|
|
|
MaxPlayers: 1,
|
|
|
|
|
BoardSizes: FixedSizes(
|
|
|
|
|
Dimensions{7, 7},
|
|
|
|
|
Dimensions{11, 11},
|
|
|
|
|
Dimensions{19, 19},
|
|
|
|
|
Dimensions{19, 21},
|
|
|
|
|
Dimensions{25, 25},
|
|
|
|
|
),
|
2022-08-17 13:03:09 -07:00
|
|
|
Tags: []string{TAG_EXPERIMENTAL, TAG_FOOD_PLACEMENT, TAG_HAZARD_PLACEMENT, TAG_SNAKE_PLACEMENT},
|
[Custom Map] Single Player Maze (#81)
* Commit from Stream
We got the maze working decently well!
Started off with exploring the repo a bit and getting used to the Map
stuff
The Maze is working pretty well except the mazes that are generated
aren't actually complete-able yet. They end up creating spaces that are
blocked off from the rest of the map
The maze generation algo is based off 'Recursive division method' mostly
following this Wiki
This looked to always create a 'valid' maze, while mine doesn't so need
to figure out what my bug is, cause I'm pretty sure there is one!
* I think we got maze generation working!
Did a lot, should have commited more lol
Got map generation working where I can see it go frame by frame, and
think we squashed the last few bugs with wall generation and hole
cutting
Now need it to actually make a new maze when you finish this first one
* We can run on a bigger board now, and we place the food randomly on the board after you grab it the first time
* Make sure my health is always 100 so don't have to worry about that lol
* Fix placing of food on maze to NOT be on an existing hazard and after 3 foods make a new maze
* Maze generation works better now and a bit of cleanup
* Committing old code
* Got state saving as Hazards Bits Working well, I think whats up next is making the map grow each level
* Draw maze in the center of the board, the maze grows as you complete levels until it fills the entire board
* Ran go fmt
* Remove my little debugging script that I added
* Revert changes I made initially to the map interface
* Move my copy-pasted printMap function to my map specifically
* Go fmt
* Write some doc comments and fix some weird code artifacts
* A few more comments and one last go fmt
* Cut less holes, this makes the maze more exciting
* Add version to Metadata and go fmt again
* Can collapse this down
* Random food spawns are more fun for sure
* add minimal support for serving a game to the board UI
* We did 3 main things here:
- Fixed the bug where hazards were getting multi-stacked
- Fixed the bug where the food could spawn on top of the snake head
- Fixed the lint errors
* Games aren't infinite now, they end by not spawning a food when you have reached a certain number of turns at the max board size
* Extract some functions to make deciding when the game is over easier
* Get evil mode implemented to force the game to end
* Fix small bugs about where we spawned the food in evil mode
* Have the snake keep growing by adding tail segments to match the current level. We start at two length because 1 lenth snakes look weird on the board since they don't have a neck to orient themselves. Here we also fix a bug where evil mode was trying to place food off the map
* Run go fmt
* Add the missing meta-data pieces
* Support a smaller board without the change of infinite loops and change the name of the maze
* Rename the actual struct and fix the tests to not make extra snakes when the map doesn't support it
* Revert "add minimal support for serving a game to the board UI"
This reverts commit 0ac3592c7669ab1bccd7bd3322adffbef5e911ce.
* add minimal support for serving a game to the board UI
* Cleanup and extract and function to place food so we don't have basically the same body twice. This also will prevent the initial food spawn from being right next to the snake
* Revert "add minimal support for serving a game to the board UI"
This reverts commit c1a3b134213dabf44df56e3ca1e6d30ff8aaa516.
* Fix lint
* 2 length snakes are silly, so lets start with 3 each time
* We start out with 3 length snakes, and a fixed set of map sizes
Co-authored-by: Rob O'Dwyer <odwyerrob@gmail.com>
2022-07-04 13:25:28 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m SoloMazeMap) SetupBoard(initialBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
|
|
|
|
if len(initialBoardState.Snakes) != 1 {
|
|
|
|
|
return rules.RulesetError("This map requires exactly one snake")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if initialBoardState.Width < INITIAL_MAZE_SIZE || initialBoardState.Height < INITIAL_MAZE_SIZE {
|
|
|
|
|
return rules.RulesetError(
|
|
|
|
|
fmt.Sprintf("This map requires a board size of at least %dx%d", INITIAL_MAZE_SIZE, INITIAL_MAZE_SIZE))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return m.CreateMaze(initialBoardState, settings, editor, 0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func maxBoardSize(boardState *rules.BoardState) int {
|
|
|
|
|
return min(boardState.Width, boardState.Height-2)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func gameNeedsToEndSoon(maxBoardSize int, currentLevel int64) bool {
|
|
|
|
|
return currentLevel-TURNS_AT_MAX_SIZE > int64(maxBoardSize-INITIAL_MAZE_SIZE)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m SoloMazeMap) CreateMaze(initialBoardState *rules.BoardState, settings rules.Settings, editor Editor, currentLevel int64) error {
|
|
|
|
|
rand := settings.GetRand(initialBoardState.Turn)
|
|
|
|
|
|
|
|
|
|
// Make sure the actual maze size can always fit in the CreateBoard
|
|
|
|
|
// This means that when you get to 'max' size each level stops making
|
|
|
|
|
// the maze bigger
|
|
|
|
|
actualBoardSize := INITIAL_MAZE_SIZE + currentLevel
|
|
|
|
|
maxBoardSize := maxBoardSize(initialBoardState)
|
|
|
|
|
|
|
|
|
|
if actualBoardSize > int64(maxBoardSize) {
|
|
|
|
|
actualBoardSize = int64(maxBoardSize)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
me := initialBoardState.Snakes[0]
|
|
|
|
|
|
|
|
|
|
mazeBoardState := rules.NewBoardState(int(actualBoardSize), int(actualBoardSize))
|
|
|
|
|
tempBoardState := initialBoardState.Clone()
|
|
|
|
|
|
|
|
|
|
topRightCorner := rules.Point{X: int(actualBoardSize) - 1, Y: int(actualBoardSize) - 1}
|
|
|
|
|
|
|
|
|
|
editor.ClearHazards()
|
|
|
|
|
|
|
|
|
|
m.WriteBitState(initialBoardState, currentLevel, editor)
|
|
|
|
|
|
|
|
|
|
m.SubdivideRoom(mazeBoardState, rand, rules.Point{X: 0, Y: 0}, topRightCorner, make([]int, 0), make([]int, 0), 0)
|
|
|
|
|
|
|
|
|
|
for _, point := range removeDuplicateValues(mazeBoardState.Hazards) {
|
|
|
|
|
adjusted := m.AdjustPosition(point, int(actualBoardSize), initialBoardState.Height, initialBoardState.Width)
|
|
|
|
|
editor.AddHazard(adjusted)
|
|
|
|
|
tempBoardState.Hazards = append(tempBoardState.Hazards, adjusted)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Since we reserve the bottom row of the board for state,
|
|
|
|
|
// AND we center the maze within the board we know there will
|
|
|
|
|
// always be a `y: -1` that we can put the tail into
|
|
|
|
|
snake_head_position := rules.Point{X: 0, Y: 0}
|
|
|
|
|
snake_tail_position := rules.Point{X: 0, Y: -1}
|
|
|
|
|
|
|
|
|
|
snakeBody := []rules.Point{
|
|
|
|
|
snake_head_position,
|
|
|
|
|
}
|
|
|
|
|
for i := 0; i <= int(currentLevel)+1; i++ {
|
|
|
|
|
snakeBody = append(snakeBody, snake_tail_position)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
adjustedSnakeBody := make([]rules.Point, len(snakeBody))
|
|
|
|
|
for i, point := range snakeBody {
|
|
|
|
|
adjustedSnakeBody[i] = m.AdjustPosition(point, int(actualBoardSize), initialBoardState.Height, initialBoardState.Width)
|
|
|
|
|
}
|
|
|
|
|
editor.PlaceSnake(me.ID, adjustedSnakeBody, 100)
|
|
|
|
|
tempBoardState.Snakes[0].Body = adjustedSnakeBody
|
|
|
|
|
|
|
|
|
|
/// Pick random food spawn point
|
|
|
|
|
m.PlaceFood(tempBoardState, settings, editor, currentLevel)
|
|
|
|
|
|
|
|
|
|
// Fill outside of the board with walls
|
|
|
|
|
xAdjust := int((initialBoardState.Width - int(actualBoardSize)) / 2)
|
|
|
|
|
yAdjust := int((initialBoardState.Height - int(actualBoardSize)) / 2)
|
|
|
|
|
for x := 0; x < initialBoardState.Width; x++ {
|
|
|
|
|
for y := 1; y < initialBoardState.Height; y++ {
|
|
|
|
|
if x < xAdjust || y < yAdjust || x >= xAdjust+int(actualBoardSize) || y >= yAdjust+int(actualBoardSize) {
|
|
|
|
|
editor.AddHazard(rules.Point{X: x, Y: y})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m SoloMazeMap) PlaceFood(boardState *rules.BoardState, settings rules.Settings, editor Editor, currentLevel int64) {
|
|
|
|
|
actualBoardSize := INITIAL_MAZE_SIZE + currentLevel
|
|
|
|
|
maxBoardSize := maxBoardSize(boardState)
|
|
|
|
|
if actualBoardSize > int64(maxBoardSize) {
|
|
|
|
|
actualBoardSize = int64(maxBoardSize)
|
|
|
|
|
}
|
|
|
|
|
meBody := boardState.Snakes[0].Body
|
|
|
|
|
myHead := meBody[0]
|
|
|
|
|
|
|
|
|
|
foodPlaced := false
|
|
|
|
|
tries := 0
|
|
|
|
|
// We want to place a random food, but we also want an escape hatch for if the algo gets stuck in a loop
|
|
|
|
|
// trying to place a food.
|
|
|
|
|
for !foodPlaced && tries < MAX_TRIES {
|
|
|
|
|
tries++
|
|
|
|
|
rand := settings.GetRand(boardState.Turn + tries)
|
|
|
|
|
|
|
|
|
|
foodSpawnPoint := rules.Point{X: rand.Intn(int(actualBoardSize)), Y: rand.Intn(int(actualBoardSize))}
|
|
|
|
|
adjustedFood := m.AdjustPosition(foodSpawnPoint, int(actualBoardSize), boardState.Height, boardState.Width)
|
|
|
|
|
|
|
|
|
|
minDistanceFromFood := min(EVIL_MODE_DISTANCE_TO_FOOD, int(actualBoardSize/2))
|
|
|
|
|
if !containsPoint(boardState.Hazards, adjustedFood) && !containsPoint(meBody, adjustedFood) && manhattanDistance(adjustedFood, myHead) >= minDistanceFromFood {
|
|
|
|
|
editor.AddFood(adjustedFood)
|
|
|
|
|
foodPlaced = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-28 16:49:49 -07:00
|
|
|
func (m SoloMazeMap) PreUpdateBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m SoloMazeMap) PostUpdateBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error {
|
[Custom Map] Single Player Maze (#81)
* Commit from Stream
We got the maze working decently well!
Started off with exploring the repo a bit and getting used to the Map
stuff
The Maze is working pretty well except the mazes that are generated
aren't actually complete-able yet. They end up creating spaces that are
blocked off from the rest of the map
The maze generation algo is based off 'Recursive division method' mostly
following this Wiki
This looked to always create a 'valid' maze, while mine doesn't so need
to figure out what my bug is, cause I'm pretty sure there is one!
* I think we got maze generation working!
Did a lot, should have commited more lol
Got map generation working where I can see it go frame by frame, and
think we squashed the last few bugs with wall generation and hole
cutting
Now need it to actually make a new maze when you finish this first one
* We can run on a bigger board now, and we place the food randomly on the board after you grab it the first time
* Make sure my health is always 100 so don't have to worry about that lol
* Fix placing of food on maze to NOT be on an existing hazard and after 3 foods make a new maze
* Maze generation works better now and a bit of cleanup
* Committing old code
* Got state saving as Hazards Bits Working well, I think whats up next is making the map grow each level
* Draw maze in the center of the board, the maze grows as you complete levels until it fills the entire board
* Ran go fmt
* Remove my little debugging script that I added
* Revert changes I made initially to the map interface
* Move my copy-pasted printMap function to my map specifically
* Go fmt
* Write some doc comments and fix some weird code artifacts
* A few more comments and one last go fmt
* Cut less holes, this makes the maze more exciting
* Add version to Metadata and go fmt again
* Can collapse this down
* Random food spawns are more fun for sure
* add minimal support for serving a game to the board UI
* We did 3 main things here:
- Fixed the bug where hazards were getting multi-stacked
- Fixed the bug where the food could spawn on top of the snake head
- Fixed the lint errors
* Games aren't infinite now, they end by not spawning a food when you have reached a certain number of turns at the max board size
* Extract some functions to make deciding when the game is over easier
* Get evil mode implemented to force the game to end
* Fix small bugs about where we spawned the food in evil mode
* Have the snake keep growing by adding tail segments to match the current level. We start at two length because 1 lenth snakes look weird on the board since they don't have a neck to orient themselves. Here we also fix a bug where evil mode was trying to place food off the map
* Run go fmt
* Add the missing meta-data pieces
* Support a smaller board without the change of infinite loops and change the name of the maze
* Rename the actual struct and fix the tests to not make extra snakes when the map doesn't support it
* Revert "add minimal support for serving a game to the board UI"
This reverts commit 0ac3592c7669ab1bccd7bd3322adffbef5e911ce.
* add minimal support for serving a game to the board UI
* Cleanup and extract and function to place food so we don't have basically the same body twice. This also will prevent the initial food spawn from being right next to the snake
* Revert "add minimal support for serving a game to the board UI"
This reverts commit c1a3b134213dabf44df56e3ca1e6d30ff8aaa516.
* Fix lint
* 2 length snakes are silly, so lets start with 3 each time
* We start out with 3 length snakes, and a fixed set of map sizes
Co-authored-by: Rob O'Dwyer <odwyerrob@gmail.com>
2022-07-04 13:25:28 -04:00
|
|
|
currentLevel, e := m.ReadBitState(lastBoardState)
|
|
|
|
|
if e != nil {
|
|
|
|
|
return e
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(lastBoardState.Food) == 0 {
|
|
|
|
|
currentLevel += 1
|
|
|
|
|
m.WriteBitState(lastBoardState, currentLevel, editor)
|
|
|
|
|
|
|
|
|
|
// This will create a new maze
|
|
|
|
|
return m.CreateMaze(lastBoardState, settings, editor, currentLevel)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
maxBoardSize := maxBoardSize(lastBoardState)
|
|
|
|
|
|
|
|
|
|
food := lastBoardState.Food[0]
|
|
|
|
|
|
|
|
|
|
meBody := lastBoardState.Snakes[0].Body
|
|
|
|
|
myHead := meBody[0]
|
|
|
|
|
|
|
|
|
|
if gameNeedsToEndSoon(maxBoardSize, currentLevel) && manhattanDistance(myHead, food) < EVIL_MODE_DISTANCE_TO_FOOD {
|
|
|
|
|
editor.RemoveFood(food)
|
|
|
|
|
|
|
|
|
|
m.PlaceFood(lastBoardState, settings, editor, currentLevel)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Mostly based off this algorithm from Wikipedia: https://en.wikipedia.org/wiki/Maze_generation_algorithm#Recursive_division_method
|
|
|
|
|
func (m SoloMazeMap) SubdivideRoom(tempBoardState *rules.BoardState, rand rules.Rand, lowPoint rules.Point, highPoint rules.Point, disAllowedHorizontal []int, disAllowedVertical []int, depth int) bool {
|
|
|
|
|
didSubdivide := false
|
|
|
|
|
|
|
|
|
|
if DEBUG_MAZE_GENERATION {
|
|
|
|
|
log.Print("\n\n\n")
|
2023-02-19 17:12:03 +00:00
|
|
|
log.Printf("Subdividing room from %v to %v", lowPoint, highPoint)
|
|
|
|
|
log.Printf("disAllowedVertical %v", disAllowedVertical)
|
|
|
|
|
log.Printf("disAllowedHorizontal %v", disAllowedHorizontal)
|
[Custom Map] Single Player Maze (#81)
* Commit from Stream
We got the maze working decently well!
Started off with exploring the repo a bit and getting used to the Map
stuff
The Maze is working pretty well except the mazes that are generated
aren't actually complete-able yet. They end up creating spaces that are
blocked off from the rest of the map
The maze generation algo is based off 'Recursive division method' mostly
following this Wiki
This looked to always create a 'valid' maze, while mine doesn't so need
to figure out what my bug is, cause I'm pretty sure there is one!
* I think we got maze generation working!
Did a lot, should have commited more lol
Got map generation working where I can see it go frame by frame, and
think we squashed the last few bugs with wall generation and hole
cutting
Now need it to actually make a new maze when you finish this first one
* We can run on a bigger board now, and we place the food randomly on the board after you grab it the first time
* Make sure my health is always 100 so don't have to worry about that lol
* Fix placing of food on maze to NOT be on an existing hazard and after 3 foods make a new maze
* Maze generation works better now and a bit of cleanup
* Committing old code
* Got state saving as Hazards Bits Working well, I think whats up next is making the map grow each level
* Draw maze in the center of the board, the maze grows as you complete levels until it fills the entire board
* Ran go fmt
* Remove my little debugging script that I added
* Revert changes I made initially to the map interface
* Move my copy-pasted printMap function to my map specifically
* Go fmt
* Write some doc comments and fix some weird code artifacts
* A few more comments and one last go fmt
* Cut less holes, this makes the maze more exciting
* Add version to Metadata and go fmt again
* Can collapse this down
* Random food spawns are more fun for sure
* add minimal support for serving a game to the board UI
* We did 3 main things here:
- Fixed the bug where hazards were getting multi-stacked
- Fixed the bug where the food could spawn on top of the snake head
- Fixed the lint errors
* Games aren't infinite now, they end by not spawning a food when you have reached a certain number of turns at the max board size
* Extract some functions to make deciding when the game is over easier
* Get evil mode implemented to force the game to end
* Fix small bugs about where we spawned the food in evil mode
* Have the snake keep growing by adding tail segments to match the current level. We start at two length because 1 lenth snakes look weird on the board since they don't have a neck to orient themselves. Here we also fix a bug where evil mode was trying to place food off the map
* Run go fmt
* Add the missing meta-data pieces
* Support a smaller board without the change of infinite loops and change the name of the maze
* Rename the actual struct and fix the tests to not make extra snakes when the map doesn't support it
* Revert "add minimal support for serving a game to the board UI"
This reverts commit 0ac3592c7669ab1bccd7bd3322adffbef5e911ce.
* add minimal support for serving a game to the board UI
* Cleanup and extract and function to place food so we don't have basically the same body twice. This also will prevent the initial food spawn from being right next to the snake
* Revert "add minimal support for serving a game to the board UI"
This reverts commit c1a3b134213dabf44df56e3ca1e6d30ff8aaa516.
* Fix lint
* 2 length snakes are silly, so lets start with 3 each time
* We start out with 3 length snakes, and a fixed set of map sizes
Co-authored-by: Rob O'Dwyer <odwyerrob@gmail.com>
2022-07-04 13:25:28 -04:00
|
|
|
printMap(tempBoardState)
|
|
|
|
|
fmt.Print("Press 'Enter' to continue...")
|
|
|
|
|
_, e := bufio.NewReader(os.Stdin).ReadBytes('\n')
|
|
|
|
|
if e != nil {
|
|
|
|
|
log.Fatal(e)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
verticalWallPosition := -1
|
|
|
|
|
horizontalWallPosition := -1
|
|
|
|
|
newVerticalWall := make([]rules.Point, 0)
|
|
|
|
|
newHorizontalWall := make([]rules.Point, 0)
|
|
|
|
|
|
|
|
|
|
if highPoint.X-lowPoint.X <= 2 && highPoint.Y-lowPoint.Y <= 2 {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
verticalChoices := make([]int, 0)
|
|
|
|
|
for i := lowPoint.X + 1; i < highPoint.X-1; i++ {
|
|
|
|
|
if !contains(disAllowedVertical, i) {
|
|
|
|
|
verticalChoices = append(verticalChoices, i)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if len(verticalChoices) > 0 {
|
|
|
|
|
verticalWallPosition = verticalChoices[rand.Intn(len(verticalChoices))]
|
|
|
|
|
if DEBUG_MAZE_GENERATION {
|
2023-02-19 17:12:03 +00:00
|
|
|
log.Printf("drawing Vertical Wall at %v\n", verticalWallPosition)
|
[Custom Map] Single Player Maze (#81)
* Commit from Stream
We got the maze working decently well!
Started off with exploring the repo a bit and getting used to the Map
stuff
The Maze is working pretty well except the mazes that are generated
aren't actually complete-able yet. They end up creating spaces that are
blocked off from the rest of the map
The maze generation algo is based off 'Recursive division method' mostly
following this Wiki
This looked to always create a 'valid' maze, while mine doesn't so need
to figure out what my bug is, cause I'm pretty sure there is one!
* I think we got maze generation working!
Did a lot, should have commited more lol
Got map generation working where I can see it go frame by frame, and
think we squashed the last few bugs with wall generation and hole
cutting
Now need it to actually make a new maze when you finish this first one
* We can run on a bigger board now, and we place the food randomly on the board after you grab it the first time
* Make sure my health is always 100 so don't have to worry about that lol
* Fix placing of food on maze to NOT be on an existing hazard and after 3 foods make a new maze
* Maze generation works better now and a bit of cleanup
* Committing old code
* Got state saving as Hazards Bits Working well, I think whats up next is making the map grow each level
* Draw maze in the center of the board, the maze grows as you complete levels until it fills the entire board
* Ran go fmt
* Remove my little debugging script that I added
* Revert changes I made initially to the map interface
* Move my copy-pasted printMap function to my map specifically
* Go fmt
* Write some doc comments and fix some weird code artifacts
* A few more comments and one last go fmt
* Cut less holes, this makes the maze more exciting
* Add version to Metadata and go fmt again
* Can collapse this down
* Random food spawns are more fun for sure
* add minimal support for serving a game to the board UI
* We did 3 main things here:
- Fixed the bug where hazards were getting multi-stacked
- Fixed the bug where the food could spawn on top of the snake head
- Fixed the lint errors
* Games aren't infinite now, they end by not spawning a food when you have reached a certain number of turns at the max board size
* Extract some functions to make deciding when the game is over easier
* Get evil mode implemented to force the game to end
* Fix small bugs about where we spawned the food in evil mode
* Have the snake keep growing by adding tail segments to match the current level. We start at two length because 1 lenth snakes look weird on the board since they don't have a neck to orient themselves. Here we also fix a bug where evil mode was trying to place food off the map
* Run go fmt
* Add the missing meta-data pieces
* Support a smaller board without the change of infinite loops and change the name of the maze
* Rename the actual struct and fix the tests to not make extra snakes when the map doesn't support it
* Revert "add minimal support for serving a game to the board UI"
This reverts commit 0ac3592c7669ab1bccd7bd3322adffbef5e911ce.
* add minimal support for serving a game to the board UI
* Cleanup and extract and function to place food so we don't have basically the same body twice. This also will prevent the initial food spawn from being right next to the snake
* Revert "add minimal support for serving a game to the board UI"
This reverts commit c1a3b134213dabf44df56e3ca1e6d30ff8aaa516.
* Fix lint
* 2 length snakes are silly, so lets start with 3 each time
* We start out with 3 length snakes, and a fixed set of map sizes
Co-authored-by: Rob O'Dwyer <odwyerrob@gmail.com>
2022-07-04 13:25:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for y := lowPoint.Y; y <= highPoint.Y; y++ {
|
|
|
|
|
newVerticalWall = append(newVerticalWall, rules.Point{X: verticalWallPosition, Y: y})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
didSubdivide = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// We can only draw a horizontal wall if there is enough space
|
|
|
|
|
horizontalChoices := make([]int, 0)
|
|
|
|
|
for i := lowPoint.Y + 1; i < highPoint.Y-1; i++ {
|
|
|
|
|
if !contains(disAllowedHorizontal, i) {
|
|
|
|
|
horizontalChoices = append(horizontalChoices, i)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if len(horizontalChoices) > 0 {
|
|
|
|
|
horizontalWallPosition = horizontalChoices[rand.Intn(len(horizontalChoices))]
|
|
|
|
|
if DEBUG_MAZE_GENERATION {
|
2023-02-19 17:12:03 +00:00
|
|
|
log.Printf("drawing horizontal Wall at %v\n", horizontalWallPosition)
|
[Custom Map] Single Player Maze (#81)
* Commit from Stream
We got the maze working decently well!
Started off with exploring the repo a bit and getting used to the Map
stuff
The Maze is working pretty well except the mazes that are generated
aren't actually complete-able yet. They end up creating spaces that are
blocked off from the rest of the map
The maze generation algo is based off 'Recursive division method' mostly
following this Wiki
This looked to always create a 'valid' maze, while mine doesn't so need
to figure out what my bug is, cause I'm pretty sure there is one!
* I think we got maze generation working!
Did a lot, should have commited more lol
Got map generation working where I can see it go frame by frame, and
think we squashed the last few bugs with wall generation and hole
cutting
Now need it to actually make a new maze when you finish this first one
* We can run on a bigger board now, and we place the food randomly on the board after you grab it the first time
* Make sure my health is always 100 so don't have to worry about that lol
* Fix placing of food on maze to NOT be on an existing hazard and after 3 foods make a new maze
* Maze generation works better now and a bit of cleanup
* Committing old code
* Got state saving as Hazards Bits Working well, I think whats up next is making the map grow each level
* Draw maze in the center of the board, the maze grows as you complete levels until it fills the entire board
* Ran go fmt
* Remove my little debugging script that I added
* Revert changes I made initially to the map interface
* Move my copy-pasted printMap function to my map specifically
* Go fmt
* Write some doc comments and fix some weird code artifacts
* A few more comments and one last go fmt
* Cut less holes, this makes the maze more exciting
* Add version to Metadata and go fmt again
* Can collapse this down
* Random food spawns are more fun for sure
* add minimal support for serving a game to the board UI
* We did 3 main things here:
- Fixed the bug where hazards were getting multi-stacked
- Fixed the bug where the food could spawn on top of the snake head
- Fixed the lint errors
* Games aren't infinite now, they end by not spawning a food when you have reached a certain number of turns at the max board size
* Extract some functions to make deciding when the game is over easier
* Get evil mode implemented to force the game to end
* Fix small bugs about where we spawned the food in evil mode
* Have the snake keep growing by adding tail segments to match the current level. We start at two length because 1 lenth snakes look weird on the board since they don't have a neck to orient themselves. Here we also fix a bug where evil mode was trying to place food off the map
* Run go fmt
* Add the missing meta-data pieces
* Support a smaller board without the change of infinite loops and change the name of the maze
* Rename the actual struct and fix the tests to not make extra snakes when the map doesn't support it
* Revert "add minimal support for serving a game to the board UI"
This reverts commit 0ac3592c7669ab1bccd7bd3322adffbef5e911ce.
* add minimal support for serving a game to the board UI
* Cleanup and extract and function to place food so we don't have basically the same body twice. This also will prevent the initial food spawn from being right next to the snake
* Revert "add minimal support for serving a game to the board UI"
This reverts commit c1a3b134213dabf44df56e3ca1e6d30ff8aaa516.
* Fix lint
* 2 length snakes are silly, so lets start with 3 each time
* We start out with 3 length snakes, and a fixed set of map sizes
Co-authored-by: Rob O'Dwyer <odwyerrob@gmail.com>
2022-07-04 13:25:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for x := lowPoint.X; x <= highPoint.X; x++ {
|
|
|
|
|
newHorizontalWall = append(newHorizontalWall, rules.Point{X: x, Y: horizontalWallPosition})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
didSubdivide = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Here we make cuts in the walls
|
|
|
|
|
if len(newVerticalWall) > 1 && len(newHorizontalWall) > 1 {
|
|
|
|
|
if DEBUG_MAZE_GENERATION {
|
|
|
|
|
log.Print("Need to cut with both walls")
|
|
|
|
|
}
|
|
|
|
|
intersectionPoint := rules.Point{X: verticalWallPosition, Y: horizontalWallPosition}
|
|
|
|
|
|
|
|
|
|
newNewVerticalWall, verticalHoles := cutHoles(newVerticalWall, intersectionPoint, rand)
|
|
|
|
|
newVerticalWall = newNewVerticalWall
|
|
|
|
|
|
|
|
|
|
for _, hole := range verticalHoles {
|
|
|
|
|
disAllowedHorizontal = append(disAllowedHorizontal, hole.Y)
|
|
|
|
|
}
|
|
|
|
|
if DEBUG_MAZE_GENERATION {
|
2023-02-19 17:12:03 +00:00
|
|
|
log.Printf("Vertical Cuts are at %v\n", verticalHoles)
|
[Custom Map] Single Player Maze (#81)
* Commit from Stream
We got the maze working decently well!
Started off with exploring the repo a bit and getting used to the Map
stuff
The Maze is working pretty well except the mazes that are generated
aren't actually complete-able yet. They end up creating spaces that are
blocked off from the rest of the map
The maze generation algo is based off 'Recursive division method' mostly
following this Wiki
This looked to always create a 'valid' maze, while mine doesn't so need
to figure out what my bug is, cause I'm pretty sure there is one!
* I think we got maze generation working!
Did a lot, should have commited more lol
Got map generation working where I can see it go frame by frame, and
think we squashed the last few bugs with wall generation and hole
cutting
Now need it to actually make a new maze when you finish this first one
* We can run on a bigger board now, and we place the food randomly on the board after you grab it the first time
* Make sure my health is always 100 so don't have to worry about that lol
* Fix placing of food on maze to NOT be on an existing hazard and after 3 foods make a new maze
* Maze generation works better now and a bit of cleanup
* Committing old code
* Got state saving as Hazards Bits Working well, I think whats up next is making the map grow each level
* Draw maze in the center of the board, the maze grows as you complete levels until it fills the entire board
* Ran go fmt
* Remove my little debugging script that I added
* Revert changes I made initially to the map interface
* Move my copy-pasted printMap function to my map specifically
* Go fmt
* Write some doc comments and fix some weird code artifacts
* A few more comments and one last go fmt
* Cut less holes, this makes the maze more exciting
* Add version to Metadata and go fmt again
* Can collapse this down
* Random food spawns are more fun for sure
* add minimal support for serving a game to the board UI
* We did 3 main things here:
- Fixed the bug where hazards were getting multi-stacked
- Fixed the bug where the food could spawn on top of the snake head
- Fixed the lint errors
* Games aren't infinite now, they end by not spawning a food when you have reached a certain number of turns at the max board size
* Extract some functions to make deciding when the game is over easier
* Get evil mode implemented to force the game to end
* Fix small bugs about where we spawned the food in evil mode
* Have the snake keep growing by adding tail segments to match the current level. We start at two length because 1 lenth snakes look weird on the board since they don't have a neck to orient themselves. Here we also fix a bug where evil mode was trying to place food off the map
* Run go fmt
* Add the missing meta-data pieces
* Support a smaller board without the change of infinite loops and change the name of the maze
* Rename the actual struct and fix the tests to not make extra snakes when the map doesn't support it
* Revert "add minimal support for serving a game to the board UI"
This reverts commit 0ac3592c7669ab1bccd7bd3322adffbef5e911ce.
* add minimal support for serving a game to the board UI
* Cleanup and extract and function to place food so we don't have basically the same body twice. This also will prevent the initial food spawn from being right next to the snake
* Revert "add minimal support for serving a game to the board UI"
This reverts commit c1a3b134213dabf44df56e3ca1e6d30ff8aaa516.
* Fix lint
* 2 length snakes are silly, so lets start with 3 each time
* We start out with 3 length snakes, and a fixed set of map sizes
Co-authored-by: Rob O'Dwyer <odwyerrob@gmail.com>
2022-07-04 13:25:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
newNewHorizontalWall, horizontalHoles := cutHoleSingle(newHorizontalWall, intersectionPoint, rand)
|
|
|
|
|
newHorizontalWall = newNewHorizontalWall
|
|
|
|
|
for _, hole := range horizontalHoles {
|
|
|
|
|
disAllowedVertical = append(disAllowedVertical, hole.X)
|
|
|
|
|
}
|
|
|
|
|
if DEBUG_MAZE_GENERATION {
|
2023-02-19 17:12:03 +00:00
|
|
|
log.Printf("Horizontal Cuts are at %v\n", horizontalHoles)
|
[Custom Map] Single Player Maze (#81)
* Commit from Stream
We got the maze working decently well!
Started off with exploring the repo a bit and getting used to the Map
stuff
The Maze is working pretty well except the mazes that are generated
aren't actually complete-able yet. They end up creating spaces that are
blocked off from the rest of the map
The maze generation algo is based off 'Recursive division method' mostly
following this Wiki
This looked to always create a 'valid' maze, while mine doesn't so need
to figure out what my bug is, cause I'm pretty sure there is one!
* I think we got maze generation working!
Did a lot, should have commited more lol
Got map generation working where I can see it go frame by frame, and
think we squashed the last few bugs with wall generation and hole
cutting
Now need it to actually make a new maze when you finish this first one
* We can run on a bigger board now, and we place the food randomly on the board after you grab it the first time
* Make sure my health is always 100 so don't have to worry about that lol
* Fix placing of food on maze to NOT be on an existing hazard and after 3 foods make a new maze
* Maze generation works better now and a bit of cleanup
* Committing old code
* Got state saving as Hazards Bits Working well, I think whats up next is making the map grow each level
* Draw maze in the center of the board, the maze grows as you complete levels until it fills the entire board
* Ran go fmt
* Remove my little debugging script that I added
* Revert changes I made initially to the map interface
* Move my copy-pasted printMap function to my map specifically
* Go fmt
* Write some doc comments and fix some weird code artifacts
* A few more comments and one last go fmt
* Cut less holes, this makes the maze more exciting
* Add version to Metadata and go fmt again
* Can collapse this down
* Random food spawns are more fun for sure
* add minimal support for serving a game to the board UI
* We did 3 main things here:
- Fixed the bug where hazards were getting multi-stacked
- Fixed the bug where the food could spawn on top of the snake head
- Fixed the lint errors
* Games aren't infinite now, they end by not spawning a food when you have reached a certain number of turns at the max board size
* Extract some functions to make deciding when the game is over easier
* Get evil mode implemented to force the game to end
* Fix small bugs about where we spawned the food in evil mode
* Have the snake keep growing by adding tail segments to match the current level. We start at two length because 1 lenth snakes look weird on the board since they don't have a neck to orient themselves. Here we also fix a bug where evil mode was trying to place food off the map
* Run go fmt
* Add the missing meta-data pieces
* Support a smaller board without the change of infinite loops and change the name of the maze
* Rename the actual struct and fix the tests to not make extra snakes when the map doesn't support it
* Revert "add minimal support for serving a game to the board UI"
This reverts commit 0ac3592c7669ab1bccd7bd3322adffbef5e911ce.
* add minimal support for serving a game to the board UI
* Cleanup and extract and function to place food so we don't have basically the same body twice. This also will prevent the initial food spawn from being right next to the snake
* Revert "add minimal support for serving a game to the board UI"
This reverts commit c1a3b134213dabf44df56e3ca1e6d30ff8aaa516.
* Fix lint
* 2 length snakes are silly, so lets start with 3 each time
* We start out with 3 length snakes, and a fixed set of map sizes
Co-authored-by: Rob O'Dwyer <odwyerrob@gmail.com>
2022-07-04 13:25:28 -04:00
|
|
|
}
|
|
|
|
|
} else if len(newVerticalWall) > 1 {
|
|
|
|
|
if DEBUG_MAZE_GENERATION {
|
|
|
|
|
log.Print("Only a vertical wall needs cut")
|
|
|
|
|
}
|
|
|
|
|
segmentToRemove := rand.Intn(len(newVerticalWall) - 1)
|
|
|
|
|
hole := newVerticalWall[segmentToRemove]
|
|
|
|
|
newVerticalWall = remove(newVerticalWall, segmentToRemove)
|
|
|
|
|
|
|
|
|
|
disAllowedHorizontal = append(disAllowedHorizontal, hole.Y)
|
|
|
|
|
if DEBUG_MAZE_GENERATION {
|
2023-02-19 17:12:03 +00:00
|
|
|
log.Printf("Cuts are at %v from index %v", hole, segmentToRemove)
|
[Custom Map] Single Player Maze (#81)
* Commit from Stream
We got the maze working decently well!
Started off with exploring the repo a bit and getting used to the Map
stuff
The Maze is working pretty well except the mazes that are generated
aren't actually complete-able yet. They end up creating spaces that are
blocked off from the rest of the map
The maze generation algo is based off 'Recursive division method' mostly
following this Wiki
This looked to always create a 'valid' maze, while mine doesn't so need
to figure out what my bug is, cause I'm pretty sure there is one!
* I think we got maze generation working!
Did a lot, should have commited more lol
Got map generation working where I can see it go frame by frame, and
think we squashed the last few bugs with wall generation and hole
cutting
Now need it to actually make a new maze when you finish this first one
* We can run on a bigger board now, and we place the food randomly on the board after you grab it the first time
* Make sure my health is always 100 so don't have to worry about that lol
* Fix placing of food on maze to NOT be on an existing hazard and after 3 foods make a new maze
* Maze generation works better now and a bit of cleanup
* Committing old code
* Got state saving as Hazards Bits Working well, I think whats up next is making the map grow each level
* Draw maze in the center of the board, the maze grows as you complete levels until it fills the entire board
* Ran go fmt
* Remove my little debugging script that I added
* Revert changes I made initially to the map interface
* Move my copy-pasted printMap function to my map specifically
* Go fmt
* Write some doc comments and fix some weird code artifacts
* A few more comments and one last go fmt
* Cut less holes, this makes the maze more exciting
* Add version to Metadata and go fmt again
* Can collapse this down
* Random food spawns are more fun for sure
* add minimal support for serving a game to the board UI
* We did 3 main things here:
- Fixed the bug where hazards were getting multi-stacked
- Fixed the bug where the food could spawn on top of the snake head
- Fixed the lint errors
* Games aren't infinite now, they end by not spawning a food when you have reached a certain number of turns at the max board size
* Extract some functions to make deciding when the game is over easier
* Get evil mode implemented to force the game to end
* Fix small bugs about where we spawned the food in evil mode
* Have the snake keep growing by adding tail segments to match the current level. We start at two length because 1 lenth snakes look weird on the board since they don't have a neck to orient themselves. Here we also fix a bug where evil mode was trying to place food off the map
* Run go fmt
* Add the missing meta-data pieces
* Support a smaller board without the change of infinite loops and change the name of the maze
* Rename the actual struct and fix the tests to not make extra snakes when the map doesn't support it
* Revert "add minimal support for serving a game to the board UI"
This reverts commit 0ac3592c7669ab1bccd7bd3322adffbef5e911ce.
* add minimal support for serving a game to the board UI
* Cleanup and extract and function to place food so we don't have basically the same body twice. This also will prevent the initial food spawn from being right next to the snake
* Revert "add minimal support for serving a game to the board UI"
This reverts commit c1a3b134213dabf44df56e3ca1e6d30ff8aaa516.
* Fix lint
* 2 length snakes are silly, so lets start with 3 each time
* We start out with 3 length snakes, and a fixed set of map sizes
Co-authored-by: Rob O'Dwyer <odwyerrob@gmail.com>
2022-07-04 13:25:28 -04:00
|
|
|
}
|
|
|
|
|
} else if len(newHorizontalWall) > 1 {
|
|
|
|
|
if DEBUG_MAZE_GENERATION {
|
|
|
|
|
log.Print("Only a horizontal wall needs cut")
|
|
|
|
|
}
|
|
|
|
|
segmentToRemove := rand.Intn(len(newHorizontalWall) - 1)
|
|
|
|
|
hole := newHorizontalWall[segmentToRemove]
|
|
|
|
|
newHorizontalWall = remove(newHorizontalWall, segmentToRemove)
|
|
|
|
|
|
|
|
|
|
disAllowedVertical = append(disAllowedVertical, hole.X)
|
|
|
|
|
if DEBUG_MAZE_GENERATION {
|
2023-02-19 17:12:03 +00:00
|
|
|
log.Printf("Cuts are at %v from index %v", hole, segmentToRemove)
|
[Custom Map] Single Player Maze (#81)
* Commit from Stream
We got the maze working decently well!
Started off with exploring the repo a bit and getting used to the Map
stuff
The Maze is working pretty well except the mazes that are generated
aren't actually complete-able yet. They end up creating spaces that are
blocked off from the rest of the map
The maze generation algo is based off 'Recursive division method' mostly
following this Wiki
This looked to always create a 'valid' maze, while mine doesn't so need
to figure out what my bug is, cause I'm pretty sure there is one!
* I think we got maze generation working!
Did a lot, should have commited more lol
Got map generation working where I can see it go frame by frame, and
think we squashed the last few bugs with wall generation and hole
cutting
Now need it to actually make a new maze when you finish this first one
* We can run on a bigger board now, and we place the food randomly on the board after you grab it the first time
* Make sure my health is always 100 so don't have to worry about that lol
* Fix placing of food on maze to NOT be on an existing hazard and after 3 foods make a new maze
* Maze generation works better now and a bit of cleanup
* Committing old code
* Got state saving as Hazards Bits Working well, I think whats up next is making the map grow each level
* Draw maze in the center of the board, the maze grows as you complete levels until it fills the entire board
* Ran go fmt
* Remove my little debugging script that I added
* Revert changes I made initially to the map interface
* Move my copy-pasted printMap function to my map specifically
* Go fmt
* Write some doc comments and fix some weird code artifacts
* A few more comments and one last go fmt
* Cut less holes, this makes the maze more exciting
* Add version to Metadata and go fmt again
* Can collapse this down
* Random food spawns are more fun for sure
* add minimal support for serving a game to the board UI
* We did 3 main things here:
- Fixed the bug where hazards were getting multi-stacked
- Fixed the bug where the food could spawn on top of the snake head
- Fixed the lint errors
* Games aren't infinite now, they end by not spawning a food when you have reached a certain number of turns at the max board size
* Extract some functions to make deciding when the game is over easier
* Get evil mode implemented to force the game to end
* Fix small bugs about where we spawned the food in evil mode
* Have the snake keep growing by adding tail segments to match the current level. We start at two length because 1 lenth snakes look weird on the board since they don't have a neck to orient themselves. Here we also fix a bug where evil mode was trying to place food off the map
* Run go fmt
* Add the missing meta-data pieces
* Support a smaller board without the change of infinite loops and change the name of the maze
* Rename the actual struct and fix the tests to not make extra snakes when the map doesn't support it
* Revert "add minimal support for serving a game to the board UI"
This reverts commit 0ac3592c7669ab1bccd7bd3322adffbef5e911ce.
* add minimal support for serving a game to the board UI
* Cleanup and extract and function to place food so we don't have basically the same body twice. This also will prevent the initial food spawn from being right next to the snake
* Revert "add minimal support for serving a game to the board UI"
This reverts commit c1a3b134213dabf44df56e3ca1e6d30ff8aaa516.
* Fix lint
* 2 length snakes are silly, so lets start with 3 each time
* We start out with 3 length snakes, and a fixed set of map sizes
Co-authored-by: Rob O'Dwyer <odwyerrob@gmail.com>
2022-07-04 13:25:28 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-19 17:12:03 +00:00
|
|
|
tempBoardState.Hazards = append(tempBoardState.Hazards, newVerticalWall...)
|
|
|
|
|
tempBoardState.Hazards = append(tempBoardState.Hazards, newHorizontalWall...)
|
[Custom Map] Single Player Maze (#81)
* Commit from Stream
We got the maze working decently well!
Started off with exploring the repo a bit and getting used to the Map
stuff
The Maze is working pretty well except the mazes that are generated
aren't actually complete-able yet. They end up creating spaces that are
blocked off from the rest of the map
The maze generation algo is based off 'Recursive division method' mostly
following this Wiki
This looked to always create a 'valid' maze, while mine doesn't so need
to figure out what my bug is, cause I'm pretty sure there is one!
* I think we got maze generation working!
Did a lot, should have commited more lol
Got map generation working where I can see it go frame by frame, and
think we squashed the last few bugs with wall generation and hole
cutting
Now need it to actually make a new maze when you finish this first one
* We can run on a bigger board now, and we place the food randomly on the board after you grab it the first time
* Make sure my health is always 100 so don't have to worry about that lol
* Fix placing of food on maze to NOT be on an existing hazard and after 3 foods make a new maze
* Maze generation works better now and a bit of cleanup
* Committing old code
* Got state saving as Hazards Bits Working well, I think whats up next is making the map grow each level
* Draw maze in the center of the board, the maze grows as you complete levels until it fills the entire board
* Ran go fmt
* Remove my little debugging script that I added
* Revert changes I made initially to the map interface
* Move my copy-pasted printMap function to my map specifically
* Go fmt
* Write some doc comments and fix some weird code artifacts
* A few more comments and one last go fmt
* Cut less holes, this makes the maze more exciting
* Add version to Metadata and go fmt again
* Can collapse this down
* Random food spawns are more fun for sure
* add minimal support for serving a game to the board UI
* We did 3 main things here:
- Fixed the bug where hazards were getting multi-stacked
- Fixed the bug where the food could spawn on top of the snake head
- Fixed the lint errors
* Games aren't infinite now, they end by not spawning a food when you have reached a certain number of turns at the max board size
* Extract some functions to make deciding when the game is over easier
* Get evil mode implemented to force the game to end
* Fix small bugs about where we spawned the food in evil mode
* Have the snake keep growing by adding tail segments to match the current level. We start at two length because 1 lenth snakes look weird on the board since they don't have a neck to orient themselves. Here we also fix a bug where evil mode was trying to place food off the map
* Run go fmt
* Add the missing meta-data pieces
* Support a smaller board without the change of infinite loops and change the name of the maze
* Rename the actual struct and fix the tests to not make extra snakes when the map doesn't support it
* Revert "add minimal support for serving a game to the board UI"
This reverts commit 0ac3592c7669ab1bccd7bd3322adffbef5e911ce.
* add minimal support for serving a game to the board UI
* Cleanup and extract and function to place food so we don't have basically the same body twice. This also will prevent the initial food spawn from being right next to the snake
* Revert "add minimal support for serving a game to the board UI"
This reverts commit c1a3b134213dabf44df56e3ca1e6d30ff8aaa516.
* Fix lint
* 2 length snakes are silly, so lets start with 3 each time
* We start out with 3 length snakes, and a fixed set of map sizes
Co-authored-by: Rob O'Dwyer <odwyerrob@gmail.com>
2022-07-04 13:25:28 -04:00
|
|
|
|
|
|
|
|
/// We have both so need 4 sub-rooms
|
|
|
|
|
if verticalWallPosition != -1 && horizontalWallPosition != -1 {
|
|
|
|
|
m.SubdivideRoom(tempBoardState, rand, rules.Point{X: lowPoint.X, Y: lowPoint.Y}, rules.Point{X: verticalWallPosition, Y: horizontalWallPosition}, disAllowedHorizontal, disAllowedVertical, depth+1)
|
|
|
|
|
m.SubdivideRoom(tempBoardState, rand, rules.Point{X: verticalWallPosition + 1, Y: lowPoint.Y}, rules.Point{X: highPoint.X, Y: horizontalWallPosition}, disAllowedHorizontal, disAllowedVertical, depth+1)
|
|
|
|
|
|
|
|
|
|
m.SubdivideRoom(tempBoardState, rand, rules.Point{X: lowPoint.X, Y: horizontalWallPosition + 1}, rules.Point{X: verticalWallPosition, Y: highPoint.Y}, disAllowedHorizontal, disAllowedVertical, depth+1)
|
|
|
|
|
m.SubdivideRoom(tempBoardState, rand, rules.Point{X: verticalWallPosition + 1, Y: horizontalWallPosition + 1}, rules.Point{X: highPoint.X, Y: highPoint.Y}, disAllowedHorizontal, disAllowedVertical, depth+1)
|
|
|
|
|
} else if verticalWallPosition != -1 {
|
|
|
|
|
m.SubdivideRoom(tempBoardState, rand, rules.Point{X: lowPoint.X, Y: lowPoint.Y}, rules.Point{X: verticalWallPosition, Y: highPoint.Y}, disAllowedHorizontal, disAllowedVertical, depth+1)
|
|
|
|
|
m.SubdivideRoom(tempBoardState, rand, rules.Point{X: verticalWallPosition + 1, Y: lowPoint.Y}, rules.Point{X: highPoint.X, Y: highPoint.Y}, disAllowedHorizontal, disAllowedVertical, depth+1)
|
|
|
|
|
} else if horizontalWallPosition != -1 {
|
|
|
|
|
m.SubdivideRoom(tempBoardState, rand, rules.Point{X: lowPoint.X, Y: lowPoint.Y}, rules.Point{X: highPoint.X, Y: horizontalWallPosition}, disAllowedHorizontal, disAllowedVertical, depth+1)
|
|
|
|
|
m.SubdivideRoom(tempBoardState, rand, rules.Point{X: lowPoint.X, Y: horizontalWallPosition + 1}, rules.Point{X: highPoint.X, Y: highPoint.Y}, disAllowedHorizontal, disAllowedVertical, depth+1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return didSubdivide
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////// Maze Helpers ////////
|
|
|
|
|
|
|
|
|
|
func (m SoloMazeMap) AdjustPosition(mazePosition rules.Point, actualBoardSize int, boardHeight int, boardWidth int) rules.Point {
|
|
|
|
|
|
|
|
|
|
xAdjust := int((boardWidth - actualBoardSize) / 2)
|
|
|
|
|
yAdjust := int((boardHeight - actualBoardSize) / 2)
|
|
|
|
|
|
|
|
|
|
if DEBUG_MAZE_GENERATION {
|
2023-02-19 17:12:03 +00:00
|
|
|
fmt.Printf("currentLevel: %v, boardHeight: %v, boardWidth: %v, xAdjust: %v, yAdjust: %v\n", actualBoardSize, boardHeight, boardWidth, xAdjust, yAdjust)
|
[Custom Map] Single Player Maze (#81)
* Commit from Stream
We got the maze working decently well!
Started off with exploring the repo a bit and getting used to the Map
stuff
The Maze is working pretty well except the mazes that are generated
aren't actually complete-able yet. They end up creating spaces that are
blocked off from the rest of the map
The maze generation algo is based off 'Recursive division method' mostly
following this Wiki
This looked to always create a 'valid' maze, while mine doesn't so need
to figure out what my bug is, cause I'm pretty sure there is one!
* I think we got maze generation working!
Did a lot, should have commited more lol
Got map generation working where I can see it go frame by frame, and
think we squashed the last few bugs with wall generation and hole
cutting
Now need it to actually make a new maze when you finish this first one
* We can run on a bigger board now, and we place the food randomly on the board after you grab it the first time
* Make sure my health is always 100 so don't have to worry about that lol
* Fix placing of food on maze to NOT be on an existing hazard and after 3 foods make a new maze
* Maze generation works better now and a bit of cleanup
* Committing old code
* Got state saving as Hazards Bits Working well, I think whats up next is making the map grow each level
* Draw maze in the center of the board, the maze grows as you complete levels until it fills the entire board
* Ran go fmt
* Remove my little debugging script that I added
* Revert changes I made initially to the map interface
* Move my copy-pasted printMap function to my map specifically
* Go fmt
* Write some doc comments and fix some weird code artifacts
* A few more comments and one last go fmt
* Cut less holes, this makes the maze more exciting
* Add version to Metadata and go fmt again
* Can collapse this down
* Random food spawns are more fun for sure
* add minimal support for serving a game to the board UI
* We did 3 main things here:
- Fixed the bug where hazards were getting multi-stacked
- Fixed the bug where the food could spawn on top of the snake head
- Fixed the lint errors
* Games aren't infinite now, they end by not spawning a food when you have reached a certain number of turns at the max board size
* Extract some functions to make deciding when the game is over easier
* Get evil mode implemented to force the game to end
* Fix small bugs about where we spawned the food in evil mode
* Have the snake keep growing by adding tail segments to match the current level. We start at two length because 1 lenth snakes look weird on the board since they don't have a neck to orient themselves. Here we also fix a bug where evil mode was trying to place food off the map
* Run go fmt
* Add the missing meta-data pieces
* Support a smaller board without the change of infinite loops and change the name of the maze
* Rename the actual struct and fix the tests to not make extra snakes when the map doesn't support it
* Revert "add minimal support for serving a game to the board UI"
This reverts commit 0ac3592c7669ab1bccd7bd3322adffbef5e911ce.
* add minimal support for serving a game to the board UI
* Cleanup and extract and function to place food so we don't have basically the same body twice. This also will prevent the initial food spawn from being right next to the snake
* Revert "add minimal support for serving a game to the board UI"
This reverts commit c1a3b134213dabf44df56e3ca1e6d30ff8aaa516.
* Fix lint
* 2 length snakes are silly, so lets start with 3 each time
* We start out with 3 length snakes, and a fixed set of map sizes
Co-authored-by: Rob O'Dwyer <odwyerrob@gmail.com>
2022-07-04 13:25:28 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rules.Point{X: mazePosition.X + xAdjust, Y: mazePosition.Y + yAdjust}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m SoloMazeMap) ReadBitState(boardState *rules.BoardState) (int64, error) {
|
|
|
|
|
row := 0
|
|
|
|
|
width := boardState.Width
|
|
|
|
|
|
|
|
|
|
stringBits := ""
|
|
|
|
|
|
|
|
|
|
for i := 0; i < width; i++ {
|
|
|
|
|
if containsPoint(boardState.Hazards, rules.Point{X: i, Y: row}) {
|
|
|
|
|
stringBits += "1"
|
|
|
|
|
} else {
|
|
|
|
|
stringBits += "0"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return strconv.ParseInt(stringBits, 2, 64)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m SoloMazeMap) WriteBitState(boardState *rules.BoardState, state int64, editor Editor) {
|
|
|
|
|
width := boardState.Width
|
|
|
|
|
|
|
|
|
|
stringBits := strconv.FormatInt(state, 2)
|
|
|
|
|
paddingBits := fmt.Sprintf("%0*s", width, stringBits)
|
|
|
|
|
|
|
|
|
|
for i, c := range paddingBits {
|
|
|
|
|
point := rules.Point{X: i, Y: 0}
|
|
|
|
|
|
|
|
|
|
if c == '1' {
|
|
|
|
|
editor.AddHazard(point)
|
|
|
|
|
} else {
|
|
|
|
|
editor.RemoveHazard(point)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-19 17:12:03 +00:00
|
|
|
// Return value is first the wall that has been cut, the second is the holes we cut out
|
[Custom Map] Single Player Maze (#81)
* Commit from Stream
We got the maze working decently well!
Started off with exploring the repo a bit and getting used to the Map
stuff
The Maze is working pretty well except the mazes that are generated
aren't actually complete-able yet. They end up creating spaces that are
blocked off from the rest of the map
The maze generation algo is based off 'Recursive division method' mostly
following this Wiki
This looked to always create a 'valid' maze, while mine doesn't so need
to figure out what my bug is, cause I'm pretty sure there is one!
* I think we got maze generation working!
Did a lot, should have commited more lol
Got map generation working where I can see it go frame by frame, and
think we squashed the last few bugs with wall generation and hole
cutting
Now need it to actually make a new maze when you finish this first one
* We can run on a bigger board now, and we place the food randomly on the board after you grab it the first time
* Make sure my health is always 100 so don't have to worry about that lol
* Fix placing of food on maze to NOT be on an existing hazard and after 3 foods make a new maze
* Maze generation works better now and a bit of cleanup
* Committing old code
* Got state saving as Hazards Bits Working well, I think whats up next is making the map grow each level
* Draw maze in the center of the board, the maze grows as you complete levels until it fills the entire board
* Ran go fmt
* Remove my little debugging script that I added
* Revert changes I made initially to the map interface
* Move my copy-pasted printMap function to my map specifically
* Go fmt
* Write some doc comments and fix some weird code artifacts
* A few more comments and one last go fmt
* Cut less holes, this makes the maze more exciting
* Add version to Metadata and go fmt again
* Can collapse this down
* Random food spawns are more fun for sure
* add minimal support for serving a game to the board UI
* We did 3 main things here:
- Fixed the bug where hazards were getting multi-stacked
- Fixed the bug where the food could spawn on top of the snake head
- Fixed the lint errors
* Games aren't infinite now, they end by not spawning a food when you have reached a certain number of turns at the max board size
* Extract some functions to make deciding when the game is over easier
* Get evil mode implemented to force the game to end
* Fix small bugs about where we spawned the food in evil mode
* Have the snake keep growing by adding tail segments to match the current level. We start at two length because 1 lenth snakes look weird on the board since they don't have a neck to orient themselves. Here we also fix a bug where evil mode was trying to place food off the map
* Run go fmt
* Add the missing meta-data pieces
* Support a smaller board without the change of infinite loops and change the name of the maze
* Rename the actual struct and fix the tests to not make extra snakes when the map doesn't support it
* Revert "add minimal support for serving a game to the board UI"
This reverts commit 0ac3592c7669ab1bccd7bd3322adffbef5e911ce.
* add minimal support for serving a game to the board UI
* Cleanup and extract and function to place food so we don't have basically the same body twice. This also will prevent the initial food spawn from being right next to the snake
* Revert "add minimal support for serving a game to the board UI"
This reverts commit c1a3b134213dabf44df56e3ca1e6d30ff8aaa516.
* Fix lint
* 2 length snakes are silly, so lets start with 3 each time
* We start out with 3 length snakes, and a fixed set of map sizes
Co-authored-by: Rob O'Dwyer <odwyerrob@gmail.com>
2022-07-04 13:25:28 -04:00
|
|
|
func cutHoles(s []rules.Point, intersection rules.Point, rand rules.Rand) ([]rules.Point, []rules.Point) {
|
|
|
|
|
holes := make([]rules.Point, 0)
|
|
|
|
|
|
|
|
|
|
index := pos(s, intersection)
|
|
|
|
|
|
|
|
|
|
if index != 0 {
|
|
|
|
|
firstSegmentToRemove := rand.Intn(index)
|
|
|
|
|
holes = append(holes, s[firstSegmentToRemove])
|
|
|
|
|
s = remove(s, firstSegmentToRemove)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
index = pos(s, intersection)
|
|
|
|
|
if index != len(s)-1 {
|
|
|
|
|
secondSegmentToRemove := rand.Intn(len(s)-index-1) + index + 1
|
|
|
|
|
|
|
|
|
|
holes = append(holes, s[secondSegmentToRemove])
|
|
|
|
|
s = remove(s, secondSegmentToRemove)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return s, holes
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func cutHoleSingle(s []rules.Point, intersection rules.Point, rand rules.Rand) ([]rules.Point, []rules.Point) {
|
|
|
|
|
holes := make([]rules.Point, 0)
|
|
|
|
|
|
|
|
|
|
index := pos(s, intersection)
|
|
|
|
|
|
|
|
|
|
if index != 0 {
|
|
|
|
|
firstSegmentToRemove := rand.Intn(index)
|
|
|
|
|
holes = append(holes, s[firstSegmentToRemove])
|
|
|
|
|
s = remove(s, firstSegmentToRemove)
|
|
|
|
|
|
|
|
|
|
return s, holes
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if index != len(s)-1 {
|
|
|
|
|
secondSegmentToRemove := rand.Intn(len(s)-index-1) + index + 1
|
|
|
|
|
|
|
|
|
|
holes = append(holes, s[secondSegmentToRemove])
|
|
|
|
|
s = remove(s, secondSegmentToRemove)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return s, holes
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////// Golang Helpers ////////
|
|
|
|
|
|
|
|
|
|
func contains(s []int, e int) bool {
|
|
|
|
|
for _, a := range s {
|
|
|
|
|
if a == e {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func containsPoint(s []rules.Point, e rules.Point) bool {
|
|
|
|
|
for _, a := range s {
|
|
|
|
|
if a.X == e.X && a.Y == e.Y {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func remove(s []rules.Point, i int) []rules.Point {
|
|
|
|
|
s[i] = s[len(s)-1]
|
|
|
|
|
return s[:len(s)-1]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func pos(s []rules.Point, e rules.Point) int {
|
|
|
|
|
for i, a := range s {
|
|
|
|
|
if a == e {
|
|
|
|
|
return i
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return -1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func removeDuplicateValues(hazards []rules.Point) []rules.Point {
|
|
|
|
|
keys := make(map[rules.Point]bool)
|
|
|
|
|
uniqueList := []rules.Point{}
|
|
|
|
|
|
|
|
|
|
for _, entry := range hazards {
|
|
|
|
|
if _, value := keys[entry]; !value {
|
|
|
|
|
keys[entry] = true
|
|
|
|
|
uniqueList = append(uniqueList, entry)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return uniqueList
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func min(a, b int) int {
|
|
|
|
|
if a < b {
|
|
|
|
|
return a
|
|
|
|
|
}
|
|
|
|
|
return b
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func manhattanDistance(a, b rules.Point) int {
|
|
|
|
|
return abs(a.X-b.X) + abs(a.Y-b.Y)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func abs(a int) int {
|
|
|
|
|
if a < 0 {
|
|
|
|
|
return -a
|
|
|
|
|
}
|
|
|
|
|
return a
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//// DEBUGING HELPERS ////
|
|
|
|
|
|
|
|
|
|
// This mostly copy pasted from the CLI which prints out the boardState
|
|
|
|
|
// Copied here to not create a circular dependency
|
|
|
|
|
// Removed some of the color picking logic to simplify things
|
|
|
|
|
func printMap(boardState *rules.BoardState) {
|
|
|
|
|
var o bytes.Buffer
|
|
|
|
|
o.WriteString(fmt.Sprintf("Turn: %v\n", boardState.Turn))
|
|
|
|
|
board := make([][]string, boardState.Width)
|
|
|
|
|
for i := range board {
|
|
|
|
|
board[i] = make([]string, boardState.Height)
|
|
|
|
|
}
|
|
|
|
|
for y := int(0); y < boardState.Height; y++ {
|
|
|
|
|
for x := int(0); x < boardState.Width; x++ {
|
|
|
|
|
board[x][y] = "◦"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for _, oob := range boardState.Hazards {
|
|
|
|
|
board[oob.X][oob.Y] = "░"
|
|
|
|
|
}
|
|
|
|
|
for _, f := range boardState.Food {
|
|
|
|
|
board[f.X][f.Y] = "⚕"
|
|
|
|
|
}
|
|
|
|
|
o.WriteString(fmt.Sprintf("Food ⚕: %v\n", boardState.Food))
|
|
|
|
|
for _, s := range boardState.Snakes {
|
|
|
|
|
for _, b := range s.Body {
|
|
|
|
|
if b.X >= 0 && b.X < boardState.Width && b.Y >= 0 && b.Y < boardState.Height {
|
|
|
|
|
board[b.X][b.Y] = string("*")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for y := boardState.Height - 1; y >= 0; y-- {
|
|
|
|
|
for x := int(0); x < boardState.Width; x++ {
|
|
|
|
|
o.WriteString(board[x][y])
|
|
|
|
|
}
|
|
|
|
|
o.WriteString("\n")
|
|
|
|
|
}
|
|
|
|
|
log.Print(o.String())
|
|
|
|
|
}
|