/// <summary> /// genarate 2d maze /// </summary> /// <param name="x"> x size</param> /// <param name="y"> y size</param> /// <param name="z"> z size</param> /// <returns> maze</returns> public override Maze generate(int x, int y, int z) { if (x <= 2 || y <= 2) { throw new NotSupportedException("cant genarate maze this size"); } byte[,] myMaze = new byte[x, y]; Position start = new Position(0, 0); Position end = new Position(x - 1, y - 1); Position current = new Position(0, 0); fillArray(myMaze); //fill array with walls makePass(myMaze, current); //makes a passage in a given position while (!current.Equals(end)) { getNextPosition(x, y, current); makePass(myMaze, current); Thread.Sleep(1); } myMaze[end.X, end.Y] = End; myMaze[start.X, start.Y] = Start; Maze maze = new Maze2d(start, end, myMaze); return(maze); }
/// <summary> /// Generate a simple 2D maze. /// </summary> /// <param name="mazesizes">Get the sizes of the maze</param> /// <returns>Returns a maze with a solution.</returns> /// <remarks>first we fill the maze with 1s and 2s. Pick a random start position in column 0, calls to buildApath and after that /// fills randomly the maze with walls.</remarks> public override AMaze generate(ArrayList mazesizes) { Maze2d maze2d = new Maze2d(mazesizes); int start = Util.GetRandom(1, maze2d.maze2d.GetLength(0) - 1); for (int row = 0; row < maze2d.maze2d.GetLength(0); row++) { for (int column = 0; column < maze2d.maze2d.GetLength(1); column++) { if (row == 0 || column == 0 || row == maze2d.maze2d.GetLength(0) - 1 || column == maze2d.maze2d.GetLength(1) - 1) { maze2d.maze2d[row, column] = 2; } else { maze2d.maze2d[row, column] = 1; } } } maze2d.start = new Position(start, 0); maze2d.maze2d[start, 0] = 0; maze2d.maze2d[start, 1] = 0; buildApath(start, 1, maze2d); for (int row = 0; row < maze2d.maze2d.GetLength(0); row++) { for (int column = 0; column < maze2d.maze2d.GetLength(1); column++) { if (maze2d.maze2d[row, column] == 1) { maze2d.maze2d[row, column] = Util.GetRandom(0, 2); } } } return((AMaze)maze2d); }
public override Maze generate(int x, int y, int z) { Maze2d[] mazeMap = new Maze2d[z]; for (int i = 0; i < z; i++) { mazeMap[i] = make2dMaze(x, y); } }
/// <summary> /// genarate 2d maze by recursive division algorithm /// </summary> /// <param name="x"> width </param> /// <param name="y"> length </param> /// <returns> 2d maze</returns> private Maze2d make2dMaze(int x, int y) { byte[,] myMaze = new byte[x, y]; recursiveDivision(myMaze, 0, y, 0, x); fillArrayFrame(myMaze); Maze2d maze = new Maze2d(myMaze); return(maze); }
/// <summary> /// The class constructor. /// </summary> /// <param name="sizes">The sizes of the maze. We build a new array according to the sizes given: /// the first node of the Arraylist is the number of the rows in the maze, the second node is the number of the columns /// and the third node is the number of the floors (except the 1 floor - which all consists of walls, and the last that consists from one /// except the end).</param> public Maze3d(ArrayList sizes) : base(sizes) { ArrayList news = new ArrayList(); news.Add(sizes[0]); news.Add(sizes[1]); maze3d = new Maze2d[(int)sizes[2] + 2]; for (int i = 0; i < maze3d.Length; i++) { maze3d[i] = new Maze2d(news); } }
/// <summary> /// Build a path from the start to a cell in the last column. /// </summary> /// <param name="row">The row where the maze starts.</param> /// <param name="column">The column where the maze starts.</param> /// <param name="maze2d">The maze in which we build the path.</param> /// <remarks>recursive function that builds a path. when we get to the last column, the function stops. We pick randomly direction 0-up, /// 1-right, 2-down or 3-left where the proper cell is 1 (in a while until a proper dircetion is chosen), put in the currnet cell (maze2d[row, column]) 0 and call to buildApath /// with the parameters we got from the direction that was chosen. If there is no where to go (all around the current cell is 0 or 2) we will go to the rhight.(</remarks> private void buildApath(int row, int column, Maze2d maze2d) { bool flag = true; if (row <= 0 || column <= 0 || row >= maze2d.maze2d.GetLength(0) - 1 || column >= maze2d.maze2d.GetLength(1)) { return; } else if (column == maze2d.maze2d.GetLength(1) - 1) { maze2d.maze2d[row, column] = 0; maze2d.end = new Position(row, column); return; } else { maze2d.maze2d[row, column] = 0; } while (flag) { int dir = Util.GetRandom(0, 4); if (dir == 0 && maze2d.maze2d[row - 1, column] != 2 && maze2d.maze2d[row - 1, column] != 0) { flag = false; buildApath(row - 1, column, maze2d); } else if (dir == 1 && maze2d.maze2d[row, column + 1] != 0) { flag = false; buildApath(row, column + 1, maze2d); } else if (dir == 2 && maze2d.maze2d[row + 1, column] != 2 && maze2d.maze2d[row + 1, column] != 0) { flag = false; buildApath(row + 1, column, maze2d); } else if (dir == 3 && maze2d.maze2d[row, column - 1] != 2 && maze2d.maze2d[row, column - 1] != 0) { flag = false; buildApath(row, column - 1, maze2d); } else if ((maze2d.maze2d[row + 1, column] == 0 || maze2d.maze2d[row + 1, column] == 2) && (maze2d.maze2d[row - 1, column] == 0 || maze2d.maze2d[row - 1, column] == 2) && (maze2d.maze2d[row, column + 1] == 0 || maze2d.maze2d[row, column + 1] == 2) && (maze2d.maze2d[row, column - 1] == 0 || maze2d.maze2d[row, column - 1] == 2)) { flag = false; buildApath(row, column + 1, maze2d); } } }
/// <summary> /// fill the given surface and leave a one point pass /// </summary> /// <param name="x"> width </param> /// <param name="y"> length </param> /// <param name="point"> point to leave passage</param> /// <param name="state"> whether the point is start or end </param> /// <returns> 2d maze </returns> private Maze2d fillSurface(int x, int y, Position point, byte state) { byte[,] myMaze = new byte[x, y]; for (int i = 0; i < myMaze.GetLength(0); i++) { for (int j = 0; j < myMaze.GetLength(1); j++) { myMaze[i, j] = Wall; } } myMaze[point.X, point.Y] = state; Maze2d maze = new Maze2d(myMaze); return(maze); }
/// <summary> /// Generate a 2D maze using Prim's algorithm. /// </summary> /// <param name="mazesizes">Get the sizes of the maze</param> /// <returns>Returns a maze with a solution.</returns> /// <remarks>1. A Grid consists of a 2 dimensional array of cells. A Cell has 2 states: Blocked or Passage. /// Start with a Grid full of Cells in state Blocked. /// 2. Pick a random Cell, set it to state Passage and Compute its frontier cells. /// A frontier cell of a Cell is a cell with distance 2 in state Blocked and within the grid. /// 3. While the list of frontier cells is not empty: /// 3.1. Pick a random frontier cell from the list of frontier cells. /// 3.2. Let neighbors(frontierCell) = All cells in distance 2 in state Passage. /// Pick a random neighbor and connect the frontier cell with the neighbor by setting the cell in-between to state Passage. /// Compute the frontier cells of the chosen frontier cell and add them to the frontier list. /// Remove the chosen frontier cell from the list of frontier cells.</remarks> private AMaze generate2d(ArrayList mazesizes) { Maze2d maze2d = new Maze2d(mazesizes); for (int row = 0; row < maze2d.maze2d.GetLength(0); row++) { for (int column = 0; column < maze2d.maze2d.GetLength(1); column++) { if (row == 0 || column == 0 || row == maze2d.maze2d.GetLength(0) - 1 || column == maze2d.maze2d.GetLength(1) - 1) { maze2d.maze2d[row, column] = 2; } else { maze2d.maze2d[row, column] = 1; } } } int rowtostart = Util.GetRandom(1, maze2d.maze2d.GetLength(0) - 1); int position; ArrayList n = new ArrayList(); n.Add(new Position(rowtostart, 1, 0)); maze2d.start = new Position(rowtostart, 0, 1); maze2d.maze2d[rowtostart, 1] = 0; getFrontier(new Position(rowtostart, 1, 0), maze2d.maze2d, n); while (n.Count > 0) { position = Util.GetRandom(0, n.Count); Position t = (Position)n[position]; ArrayList nei = new ArrayList(); getNeighbors(t, maze2d.maze2d, nei); if (nei.Count > 0) { Position neig = (Position)nei[Util.GetRandom(0, nei.Count)]; maze2d.maze2d[neig.x, neig.y] = 0; maze2d.maze2d[t.x, t.y] = 0; } getFrontier(t, maze2d.maze2d, n); n.RemoveAt(position); if (n.Count == 0) { maze2d.maze2d[t.x, t.y] = 4; } } return(maze2d); }
/// <summary> /// this constractor will recive an array of byte and transform them into a 3d array (decompress) /// </summary> /// <param name="todecompress"></param> public Maze3d(byte[] todecompress) : base(new ArrayList(3)) { sizes.Add(Convert.ToInt32(todecompress[0])); sizes.Add(Convert.ToInt32(todecompress[1])); sizes.Add(Convert.ToInt32(todecompress[2])); int count = 3; ArrayList news = new ArrayList(); news.Add(sizes[0]); news.Add(sizes[1]); maze3d = new Maze2d[(int)sizes[2]]; for (int i = 0; i < maze3d.Length; i++) { maze3d[i] = new Maze2d(news); } for (int i = 0; i < maze3d.Length; i++) { for (int j = 0; j < (int)sizes[1]; j++) { for (int k = 0; k < (int)sizes[0]; k++) { this.maze3d[i].maze2d[j, k] = Convert.ToInt32(todecompress[count]); if (maze3d[i].maze2d[j, k] == 3) { start = new Position(j, k, i); } if (maze3d[i].maze2d[j, k] == 4 && i == (maze3d.Length) - 1) { end = new Position(j, k, i); } if ((j == (int)sizes[0] - 1 || j == 0 || k == (int)sizes[1] - 1 || k == 0) && maze3d[i].maze2d[j, k] != 0) { maze3d[i].maze2d[j, k] = 2; } count++; } } } // Print(); }
/// <summary> /// check if mazes are equal /// </summary> /// <param name="maze">maze to compre to</param> /// <returns>true if the mazes are equel</returns> public override bool equals(Maze maze) { if (maze is Maze2d) { Maze2d maze2d = (Maze2d)maze; if (maze2d.mazeMap.GetLength(0) == mazeMap.GetLength(0) && maze2d.mazeMap.GetLength(1) == mazeMap.GetLength(1)) { for (int i = 0; i < mazeMap.GetLength(0); i++) { for (int j = 0; j < mazeMap.GetLength(1); j++) { if (mazeMap[i, j] != maze2d.mazeMap[i, j]) { return(false); } } } return(true); } } return(false); }
public override AMaze generate(int[] boardSize) { if (boardSize.Length < 2) { //error Console.WriteLine("Illegal size "); } int height = boardSize[0]; int width = boardSize[1]; Random rnd = new Random(); Position2D start = new Position2D(rnd.Next(1, height - 1), 0); maze = new int[height, width]; generateFrame(); maze[start.Row, start.Col] = 5; maze[start.Row, start.Col + 1] = 2; generatePath(start.Col + 1, start.Row); generateWalls(); Maze2d maze2d = new Maze2d(maze, start, end); return(maze2d); }
/// <summary> /// genarate maze with given size /// </summary> /// <param name="x"> widht </param> /// <param name="y"> length </param> /// <param name="z"> depth </param> /// <returns> maze</returns> public override Maze generate(int x, int y, int z) { if (x <= 2 || y <= 2 || z <= 2) { throw new NotSupportedException("cant genarate maze this size"); } Position start = randomPosition(x, y, 0); Thread.Sleep(4); Position end = randomPosition(x, y, z - 1); Maze2d[] mazeMap = new Maze2d[z]; mazeMap[0] = fillSurface(x, y, start, Start); mazeMap[z - 1] = fillSurface(x, y, end, End); for (int i = 1; i < z - 1; i++) { mazeMap[i] = make2dMaze(x, y); } Maze maze = new Maze3d(start, end, mazeMap); return(maze); }
/// <summary> /// build an 3d maze from compressed byte array /// </summary> /// <param name="bytes"> compressed byte array </param> public Maze3d(byte[] bytes) : base(new Position(), new Position()) { int x = bytes[0]; int y = bytes[1]; int z = bytes[2]; mazeMap = new Maze2d[z]; int currentIndex = 3; for (int i = 0; i < z; i++) { byte[] bytesFor2d = new byte[x * y]; for (int j = 0; j < bytesFor2d.Length; j++, currentIndex++) { bytesFor2d[j] = bytes[currentIndex]; } mazeMap[i] = new Maze2d(x, y, bytesFor2d); } start = mazeMap[0].getStartPosition(); start.Z = 0; end = mazeMap[z - 1].getGoalPosition(); end.Z = z - 1; }