/// <summary> /// constructor of maze with byte array /// </summary> /// <param name="uncompressed">array byte uncompressed</param> public Maze3d(byte[] uncompressed) : base(uncompressed) { maze3d = new ArrayList(); m_startPosition = new Position(uncompressed[0], uncompressed[1], uncompressed[2]); m_goalPosition = new Position(uncompressed[3], uncompressed[4], uncompressed[5]); m_mx = uncompressed[6] / 2 + 1; m_my = uncompressed[7] / 2 + 1; m_mz = uncompressed[8]; int i = 9; for (int layer = 0; layer < m_mz; layer++) { Maze2d maze2D = new Maze2d(m_mx, m_my, layer); if (layer == 0) { maze2D.setStartPosition(m_startPosition); } if (layer == m_mz - 1) { maze2D.setGoalPosition(m_goalPosition); } for (int row = 0; row < m_mx * 2 - 1; row++) { for (int column = 0; column < m_my * 2 - 1; column++) { maze2D.MAZE2d[row, column] = uncompressed[i]; i++; } } maze3d.Add(maze2D); } }
/// <summary> /// build a maze2d that we can solve - break walls to get to the goal position /// </summary> /// <param name="maze"></param> /// <returns>maze2d</returns> /// ////IMaze maze in function public void generateMaze2d(Maze2d maze2d) { int randomWallLocation; Position currentWall; Position pMaze; Position startPosition = new Position(0, 0, 0); positionsInMaze = new ArrayList(); ArrayList neighborWallsList = new ArrayList(); maze2d.setGoalPosition(); Position goalPosition = maze2d.getGoalPosition(); neighborWallsList.AddRange(maze2d.getOptionsToMove(goalPosition)); // add all the neighbors to neighborsWallList positionsInMaze.Add(goalPosition); // add the goalPosition to List while (neighborWallsList.Count != 0) // while there is positions in neighborsWallsPOsitions { randomWallLocation = ran.Next(0, neighborWallsList.Count - 1); // random and get 1 of the walls in the List currentWall = ((Position)neighborWallsList[randomWallLocation]); pMaze = getUnvisitedWallNeighborCell(currentWall); // get all the UnvisitedNeighbors of the current wall if (pMaze != null) { startPosition.setPosition(pMaze); // cheange the Position maze2d.setMazeWallsCell(currentWall.X, currentWall.Y); // change the cell to 0 - we visited it if (!isPositionExist(pMaze, positionsInMaze)) { positionsInMaze.Add(pMaze); // add it to positionInMAze - all the position we have visited } neighborWallsList.AddRange(filterExistNeighbors(neighborWallsList, maze2d.getOptionsToMove(pMaze))); } neighborWallsList.RemoveAt(randomWallLocation); // remove the current wall from the neighborWallsList } maze2d.setStartPosition(startPosition); // change the startPosition }
/// <summary> /// build the 3d maze, according to the size of the maze. it calls to maze2d that build /// for every layer maze2d. /// </summary> /// <param name="x">dim X of the maze</param> /// <param name="y">dim Y of the maze</param> /// <param name="z">dim Z of the maze</param> /// <returns>maze 3d</returns> public override Maze generate(int x, int y, int z) { MyMaze3dGenerator g = new MyMaze3dGenerator(); x = x / 2 + 1; y = y / 2 + 1; Maze3d maze3d = new Maze3d(x, y, z); for (int layer = 0; layer < maze3d.MZ; layer++) { Maze2d maze2d = new Maze2d(x, y, layer); g.generateMaze2d(maze2d); maze3d.MAZE3dArray.Add(maze2d); // maze3d.finalGoalPosition(maze2d.getStartPosition()); // maze3d.getGoalPosition().Z = maze3d.MZ - 1; if (layer == 0) { maze3d.setStartPosition(maze2d.getStartPosition()); } if (layer == maze3d.MZ - 1) { maze3d.finalGoalPosition(maze2d.getGoalPosition()); maze3d.getGoalPosition().Z = maze3d.MZ - 1; } } return(maze3d); }
/// <summary> /// move to the next cell, from the current wall /// </summary> /// <param name="p">the current position you in</param> /// <param name="maze">get the 2d Maze</param> /// <returns>return the cell after movment</returns> public Position MoveTONextPosition(Position p, Maze2d maze) { int count = 0; Random ran = new Random(); int num_position; Position pToMove = new Position(0, 0, 0); ArrayList positions = new ArrayList(); Position up = new Position(0, 0, 0); Position down = new Position(0, 0, 0); Position right = new Position(0, 0, 0); bool setDown = false; bool setUp = false; bool setRight = false; if (p.X + 1 < maze.MX * 2 - 1) { down.setPosition(new Position(p.X + 1, p.Y, p.Z)); // move to the down cell setDown = true; } if (p.X - 1 >= 0) { up.setPosition(new Position(p.X - 1, p.Y, p.Z)); // move to the up cell setUp = true; } if (p.Y + 1 < maze.MY * 2 - 1) { right.setPosition(new Position(p.X, p.Y + 1, p.Z)); // move to the right cell setRight = true; } if (setUp && checkIfFatherNotEqals(p, up)) // check if we went up and not visited before, and add it to list { positions.Add(up); } if (setDown && checkIfFatherNotEqals(p, down)) { positions.Add(down); } if (setRight && checkIfFatherNotEqals(p, right)) // add it to optionToMove { positions.Add(right); } count = positions.Count; num_position = ran.Next(0, count - 1); pToMove.setPosition((Position)positions[num_position]); pToMove.setFatherPosition(p); return(pToMove); }
/// <summary> /// print the maze2d for each layer in maze3d /// </summary> /// <param name="maze2d">return maze2d</param> public void printMaze2d(Maze2d maze2d) { string wall = "█"; string path = " "; string start = "S"; string end = "E"; for (int row = 0; row < MX * 2 - 1; row++) { for (int column = 0; column < MY * 2 - 1; column++) { if (maze2d.MAZE2d[row, column] == 1) { Console.BackgroundColor = ConsoleColor.White; //// Console.Write(" "); //// //Console.Write("{0}", wall); } else { if (row == maze2d.getStartPosition().X&& column == maze2d.getStartPosition().Y&& maze2d.MZ == 0) { Console.BackgroundColor = ConsoleColor.DarkGreen;//// Console.Write(" {0}", start); } else { if (row == maze2d.getGoalPosition().X&& column == maze2d.getGoalPosition().Y&& maze2d.MZ == MZ - 1) { Console.BackgroundColor = ConsoleColor.DarkGreen;//// Console.Write(" {0}", end); } else { Console.BackgroundColor = ConsoleColor.DarkRed;//// Console.Write(" {0}", path); } } } } Console.WriteLine(); } Console.BackgroundColor = ConsoleColor.Black; Console.WriteLine(); }
/// <summary> /// build the maze 2d in a simple way, /// always start from the left side and have options to move (up,down,right), the goalPosition is in the right side /// </summary> /// <param name="x">dim X of the maze2d</param> /// <param name="y">dim Y of the maze2d</param> /// <param name="z">dim Z of the maze2d</param> /// <returns>a generated 2dMaze</returns> public override Maze generate(int x, int y, int z) { Position currentWall; Position startPosition = new Position(0, 0, 0); Maze2d maze2d = new Maze2d(x, y, z); maze2d.setGoalPosition(); Position goalPosition = maze2d.getGoalPosition(); startPosition.setPosition(goalPosition); while (startPosition.Y != maze2d.MY * 2 - 2) { currentWall = ((Position)MoveTONextPosition(startPosition, maze2d)); //get the wall to break currentWall.setFatherPosition(startPosition); maze2d.setMazeWallsCell(currentWall.X, currentWall.Y); //break the wall startPosition.setPosition(MoveToNextCell(startPosition, currentWall)); //get the prev position and the wall and move to the next cell } maze2d.setStartPosition(startPosition); breakMoreWalls(maze2d); return(maze2d); }
/// <summary> /// randomic function that break more walls /// </summary> /// <param name="maze2d">maze2d of walls</param> public void breakMoreWalls(Maze2d maze2d) { int numOfWallsToBreak; int dim_x_size = maze2d.MX; int dim_y_size = maze2d.MY; int size_all = dim_x_size * dim_y_size; numOfWallsToBreak = Convert.ToInt32(0.4 * size_all); // get How many walls to Break int x; int y; Random ran = new Random(); while (numOfWallsToBreak != 0) { x = ran.Next(0, dim_x_size * 2 - 1); y = ran.Next(0, dim_y_size * 2 - 1); if (maze2d.getWallsCell(x, y) == 1) { maze2d.setMazeWallsCell(x, y); // break the walls numOfWallsToBreak--; // size-- } } }