//Create a new Depth-First maze with the given bias. //Valid biases are: //"H": Prefer horizontal paths over vertical //"V": Prefer vertical paths over horizontal //"X": Choose cell furthest from goal. This will create a long winding path from start to finish. //"O": Chose path closest to goal. This will create a direct path to treasure and the rest will be a disconnected component. Goal being to bait icarus into taking the wrong path and having to backtrack. //"", or any other value: Default, no bias. Always picka a random neighbor. func DepthFirst(width, height int, bias string) *mazelib.Maze { m := mazelib.FullMaze(width, height) x, y := m.End() //search treasure -> icarus so treasure is usually in a dead end. startCoord := mazelib.Coordinate{x, y} visited := map[mazelib.Coordinate]bool{} visited[startCoord] = true current := []mazelib.Coordinate{startCoord} goalX, goalY := m.Start() for len(current) > 0 { possible := []possibility{} tip := current[len(current)-1] leftCoord := mazelib.Coordinate{tip.X - 1, tip.Y} if tip.X > 0 && !visited[leftCoord] { possible = append(possible, possibility{"left", leftCoord}) } rightCoord := mazelib.Coordinate{tip.X + 1, tip.Y} if tip.X < width-1 && !visited[rightCoord] { possible = append(possible, possibility{"right", rightCoord}) } upCoord := mazelib.Coordinate{tip.X, tip.Y - 1} if tip.Y > 0 && !visited[upCoord] { possible = append(possible, possibility{"up", upCoord}) } downCoord := mazelib.Coordinate{tip.X, tip.Y + 1} if tip.Y < height-1 && !visited[downCoord] { possible = append(possible, possibility{"down", downCoord}) } if len(possible) == 0 { current = current[:len(current)-1] continue } dir := randomDir(possible, tip.X, tip.Y, goalX, goalY, bias) newCoord := digInto(dir, tip, m) visited[newCoord] = true current = append(current, newCoord) } // Bias O is a direct path to treasure. Remove all other walls from start // so that everything not on the path will be connected, and likely fully explored before backtracking // to the right route. Also makes choosing correct path less likely. if bias == "O" { if goalX > 0 { digInto("left", mazelib.Coordinate{goalX, goalY}, m) } if goalX < width-1 { digInto("right", mazelib.Coordinate{goalX, goalY}, m) } if goalY > 0 { digInto("up", mazelib.Coordinate{goalX, goalY}, m) } if goalY < height-1 { digInto("down", mazelib.Coordinate{goalX, goalY}, m) } } return m }
// Creates a maze with all walls // Good starting point for subtractive algorithms func FullMaze() *mazelib.Maze { ySize := viper.GetInt("height") xSize := viper.GetInt("width") return mazelib.FullMaze(xSize, ySize) }