private string SearchForEligibleDirectionFromCell( MazeCell inputCell, Dictionary <string, MazeCell> mazeCellsVisited ) { List <string> shuffledDirections = Functions.ShuffleStringList(MazeCell.directions); foreach (string direction in shuffledDirections) { var nCell = inputCell.GetNeighborMazeCell(direction); if (nCell != null) { string nCellPos = this.GetFormattedPosition(nCell.position_X, nCell.position_Y); var wall = inputCell.GetMazeWall(direction); if (wall == null) { Debug.Log("wall not found.."); } bool neighborCellIsEligible = ( !mazeCellsVisited.ContainsKey(nCellPos) && wall.isActive ); if (neighborCellIsEligible) { return(direction); } } } return(null); }
private Maze ApplyDepthFirstBacktrackingToMaze(Maze maze) { var backtrackMem = new Stack(); var mazeCellsVisited = new Dictionary <string, MazeCell>(); // select random cell to start and memorize MazeCell currentMazeCell = this.SelectRandomMazeCell(maze); MazeCell initialMazeCell = currentMazeCell; do { // mark current maze cell as visited string currPos = this.GetFormattedPosition( currentMazeCell.position_X, currentMazeCell.position_Y ); if (!mazeCellsVisited.ContainsKey(currPos)) { mazeCellsVisited.Add(currPos, currentMazeCell); } // check for eligible direction string eligibleDirection = this.SearchForEligibleDirectionFromCell( currentMazeCell, mazeCellsVisited ); if (eligibleDirection != null) { // per the direction, remove the wall, memorize current maze cell, // and move to neighbor maze cell var nCell = currentMazeCell.GetNeighborMazeCell(eligibleDirection); var wall = currentMazeCell.GetMazeWall(eligibleDirection); wall.isActive = false; backtrackMem.Push(currentMazeCell); currentMazeCell = nCell; } else { // backtrack one cell and try again in next loop currentMazeCell = (MazeCell)backtrackMem.Pop(); } } while(currentMazeCell != initialMazeCell); return(maze); }
// IMPLEMENTATION METHODS private Maze GenerateInitializedMaze(int width, int height) { var positionToMazeCell = new Dictionary <string, MazeCell>(); var positionToMazeCellWall = new Dictionary <string, MazeWall>(); // keep track of the last maze cell MazeCell lastMazeCell = null; // for each position instantiate maze cells and // point to previous maze cell to create linked list for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { var mazeCell = new MazeCell(j, i); if (lastMazeCell != null) { mazeCell.nextMazeCell = lastMazeCell; } lastMazeCell = mazeCell; // add to position lookup dict positionToMazeCell.Add( GetFormattedPosition(mazeCell.position_X, mazeCell.position_Y), mazeCell ); } } // for every maze cell in the linked list set all the neighbor cells MazeCell currentMazeCell = lastMazeCell; MazeCell previousMazeCell = null; while (currentMazeCell != null) { foreach (string direction in MazeCell.directions) { MazeCell nCell = this.GetMazeCellNeighborCellFromLookupDict( positionToMazeCell, currentMazeCell, direction ); MazeWall sharedWall = null; if (nCell != null) { currentMazeCell.SetNeighborMazeCell(direction, nCell); sharedWall = nCell.GetMazeWall(MazeCell.GetOppositeDirection(direction)); } if (sharedWall != null) { currentMazeCell.SetWall(direction, sharedWall); } else { float xOffset = 0; float yOffset = 0; if (direction == MazeCell.NORTH) { yOffset = 0.5f; } else if (direction == MazeCell.SOUTH) { yOffset = -0.5f; } else if (direction == MazeCell.EAST) { xOffset = 0.5f; } else if (direction == MazeCell.WEST) { xOffset = -0.5f; } bool isOutwall = ( (direction == MazeCell.NORTH && currentMazeCell.position_Y == height - 1) || (direction == MazeCell.SOUTH && currentMazeCell.position_Y == 0) || (direction == MazeCell.EAST && currentMazeCell.position_X == 0) || (direction == MazeCell.WEST && currentMazeCell.position_X == width - 1) ); bool isHorizontal = direction == MazeCell.NORTH || direction == MazeCell.SOUTH; var mazeWall = new MazeWall( currentMazeCell.position_X + xOffset, currentMazeCell.position_Y + yOffset, true, isOutwall, isHorizontal ); currentMazeCell.SetWall(direction, mazeWall); positionToMazeCellWall.Add( this.GetFormattedPosition( mazeWall.position_X, mazeWall.position_Y ), mazeWall ); } } previousMazeCell = currentMazeCell; currentMazeCell = currentMazeCell.nextMazeCell; } var maze = new Maze( width, height, positionToMazeCell, lastMazeCell, positionToMazeCellWall ); // this.TestValidateMaze(maze); return(maze); }