public IEnumerable<Location> GetRoute(Location source, Location destination, MazeObject[,] maze) { int rows = maze.GetLength(0); int cols = maze.GetLength(1); bool[,] visited = new bool[rows, cols]; Queue<SimpleTreeNode<Location>> treeNodesQueue = new Queue<SimpleTreeNode<Location>>(); SimpleTreeNode<Location> root = new SimpleTreeNode<Location>(source); treeNodesQueue.Enqueue(root); visited[source.Row, source.Col] = true; while (treeNodesQueue.Count > 0) { SimpleTreeNode<Location> node = treeNodesQueue.Dequeue(); if (node.Value == destination) { // traverse the tree bottom-up to get the shortest path IEnumerable<Location> route = GetAllPredecessors(node); return route; } SimpleTreeNode<Location>[] childNodes = new SimpleTreeNode<Location>[] { new SimpleTreeNode<Location>(new Location(node.Value.Row, node.Value.Col - 1)), // left new SimpleTreeNode<Location>(new Location(node.Value.Row, node.Value.Col + 1)), // right new SimpleTreeNode<Location>(new Location(node.Value.Row - 1, node.Value.Col)), // up new SimpleTreeNode<Location>(new Location(node.Value.Row + 1, node.Value.Col)) // down }; node.Children.AddRange(childNodes); foreach (SimpleTreeNode<Location> child in childNodes) { if (child.Value.Row >= 0 && child.Value.Row < rows && child.Value.Col >= 0 && child.Value.Col < cols && !(maze[child.Value.Row, child.Value.Col].Type == MazeObjectType.Brick) && !visited[child.Value.Row, child.Value.Col]) { node.Children.Add(child); treeNodesQueue.Enqueue(child); visited[child.Value.Row, child.Value.Col] = true; } } } return new List<Location>(); }
private void InitMaze() { ulong[] rows = new ulong[]{ 1099511627775, // row 1 549755813889, // row 2 755578613749, // row 3 722259322901, // row 4 737307960261, // row 5 599861673969, // row 6 962209021959, // row 7 206154235892, // row 8 137573203972, // row 9 1013276651479, // row 10 34527683408, // row 11 1076594124895, // row 12 45801975632, // row 13 1007874646359, // row 14 146767002692, // row 15 173946175764, // row 16 1025418198391, // row 17 551905394945, // row 18 803158884189, // row 19 695784702021, // row 20 754835258869, // row 21 549757911041, // row 22 1099511627775 // row 23 }; for (int rowIndex = 0; rowIndex < MAZE_ROWS; rowIndex++) { for (int colIndex = 0; colIndex < MAZE_COLS; colIndex++) { maze[rowIndex, MAZE_COLS - 1 - colIndex] = new MazeObject(MazeObjectType.EmptyCell); ulong mask = (ulong)1 << colIndex; if ((rows[rowIndex] & mask) != (ulong)0) { // the bricks maze[rowIndex, MAZE_COLS - 1 - colIndex] = new MazeObject(MazeObjectType.Brick); Draw(rowIndex, MAZE_COLS - 1 - colIndex, '#', ConsoleColor.Blue); if (rowIndex == 9 && colIndex == 22) { // the monster pen door maze[rowIndex, MAZE_COLS - 1 - colIndex] = new MazeObject(MazeObjectType.PenDoor); Draw(rowIndex, MAZE_COLS - 1 - colIndex, '=', ConsoleColor.Magenta); } } else if (rowIndex >= 8 && rowIndex <= 15 && colIndex <= 26 && colIndex >= 16 || (rowIndex == 7 || rowIndex == 8 || rowIndex == 14 || rowIndex == 15) && (colIndex >= MAZE_COLS - 2 || colIndex <= 1) || (rowIndex == 10 || rowIndex == 12) && (colIndex >= MAZE_COLS - 4 || colIndex <= 3)) { // these will remain empty cells continue; } else if ((rowIndex == 2 || rowIndex == 20) && (colIndex == 1 || colIndex == 38)) { // the power pellets (energizers) maze[rowIndex, MAZE_COLS - 1 - colIndex] = new MazeObject(MazeObjectType.PowerPellet, 50); Draw(rowIndex, MAZE_COLS - 1 - colIndex, '$', ConsoleColor.White); } else { // the pellets maze[rowIndex, MAZE_COLS - 1 - colIndex] = new MazeObject(MazeObjectType.Pellet, 10); Draw(rowIndex, MAZE_COLS - 1 - colIndex, '.', ConsoleColor.Yellow); } } } Console.CursorVisible = false; }
private void MakeCellEmpty(int row, int col) { maze[row, col] = new MazeObject(MazeObjectType.EmptyCell); Draw(row, col, (char)32, ConsoleColor.Black); }
public void CalcRoute(Location destination, MazeObject[,] maze) { this.route = this.strategy.GetRoute(this.Location, destination, maze); this.enumerator = this.route.GetEnumerator(); }