/// <summary> /// Restarts this instance. /// </summary> internal void Restart() { this.playerPosition = new MazePosition(this.Start); this.hint = this.solutionPath[2]; this.hintIndex = 2; this.hintIndex = 0; }
public GenerateAnswer(SolveAnswer answer) { this.name = answer.Name; this.maze = answer.Maze.Replace('2', '0'); this.start = answer.Start; this.end = answer.End; }
/// <summary> /// Positions the between the MazePositions pos1 and pos2. /// </summary> /// <param name="pos1">The pos1 the first MazePosition.</param> /// <param name="pos2">The pos2 the second MazePosition.</param> /// <returns>the MazePosition between</returns> internal static MazePosition PositionBetween(MazePosition pos1 , MazePosition pos2) { int row = pos1.row; int col = pos1.colomn; if (pos2.row > pos1.row) { row++; } else if (pos2.row < pos1.row) { row--; } if (pos2.colomn > pos1.colomn) { col++; } else if (pos2.colomn < pos1.colomn) { col--; } return(new MazePosition(row, col)); }
/// <summary> /// Changes the door state between first and second. /// </summary> /// <param name="first">The first MazePosition.</param> /// <param name="second">The second MazePosition.</param> /// <param name="state">The door state to be set.</param> public void ChangeDoorStateBetween(MazePosition first, MazePosition second, DoorState state) { int doorRow = first.Row; if (second.Row < first.Row) { doorRow = first.Row - 1; } else if (second.Row > first.Row) { doorRow = first.Row + 1; } int doorCol = first.Colomn; if (second.Colomn < first.Colomn) { doorCol = first.Colomn - 1; } else if (second.Colomn > first.Colomn) { doorCol = first.Colomn + 1; } if (state == DoorState.Opened) { this.mazeMatrix[doorRow, doorCol] = PASS; } else { this.mazeMatrix[doorRow, doorCol] = WALL; } }
// MazeGenerator (Constructor) public MazeGenerator(int size_X, int size_Z) { sizeX = size_X; sizeZ = size_Z; cells = new MazeCell[sizeX, sizeZ]; // Init all cells for (int x = 0; x < sizeX; x++) { for (int z = 0; z < sizeZ; z++) { cells[x, z] = new MazeCell(); } } // Create stack (amount of all cells) stack = new MazePosition[sizeX * sizeZ]; // Set a random position for the first cell int startX = Random.Range(0, sizeX); int startZ = Random.Range(0, sizeZ); // Put first cell in stack stack[0] = new MazePosition(startX, startZ); positionInStack = 0; // First cell is visited cells[startX, startZ].visited = true; }
// Method to generate the maze public void generate() { /* The algorithm always go back if there is no neighbours found. * So the algorithm will be executed until we are at the beginning of the stack again (so if there is no cell unvisited anymore) */ while (positionInStack >= 0) { // Get the coordinates of the current cell int x = stack[positionInStack].x; int z = stack[positionInStack].z; // Check neighbours int[] possibleNeighbours = checkNeighbours(stack[positionInStack]); if (possibleNeighbours.Length > 0) // There are unvisited neighbours { // Take a random possible neighbour (wall) int wall = possibleNeighbours[Random.Range(0, possibleNeighbours.Length)]; // Set the wall to false (make it a passage) cells[x, z].walls[wall] = false; // Identify the new coordinates of the new cell if (wall == 2) { x--; } else if (wall == 1) { x++; } else if (wall == 3) { z--; } else if (wall == 0) { z++; } // Set the new cell to visited cells[x, z].visited = true; // Make the opposite wall also a passage cells[x, z].walls[3 - wall] = false; // Put the new cell in the stack with its position positionInStack++; stack[positionInStack] = new MazePosition(x, z); } else // Found no neigbours { // Go back to the previous cell in stack positionInStack--; // Look for neighbours in the previous cell again } } }
/// <summary> /// Initializes a new instance of the <see cref="SinglePlayerMaze"/> class. /// </summary> /// <param name="answer">The answer.</param> /// <param name="rows">The rows.</param> /// <param name="cols">The cols.</param> public SinglePlayerMaze(GenerateAnswer answer, int rows, int cols) { this.answer = answer; this.cols = cols; this.rows = rows; // place the player at the start of the maze this.playerPosition = new MazePosition(this.answer.Start); this.hint = new MazePosition(this.answer.Start); }
/// <summary> /// Changes the end position. /// </summary> /// <param name="position">The new End position.</param> /// <returns> /// true if successfuly changed the position /// </returns> public bool ChangeEndPosition(MazePosition position) { if (position.Row == 0 || position.Row == this.height - 1 || position.Colomn == 0 || position.Colomn == this.width - 1) { this.endPosition = position; return(true); } return(false); }
/// <summary> /// Initializes a new instance of the <see cref="MultiPlayerMaze"/> class. /// </summary> /// <param name="answer">The answer.</param> /// <param name="rows">The rows.</param> /// <param name="cols">The columns.</param> /// <param name="server">The server.</param> public MultiPlayerMaze(MultiplayerAnswer answer, int rows, int cols, IServer server) { this.server = server; this.answer = answer; this.cols = cols; this.rows = rows; this.playerPosition = new MazePosition(this.answer.You.Start); this.opponenetPosition = new MazePosition(this.answer.Other.Start); this.hint = new MazePosition(this.answer.You.Start); }
/// <summary> /// Restarts the maze. /// </summary> public void Restart() { if (this.singlePlayerMaze != null) { this.singlePlayerMaze.Restart(); this.MazeName = this.singlePlayerMaze.Name; this.MazeString = this.singlePlayerMaze.Maze; this.PlayerPosition = this.singlePlayerMaze.PlayerPosition; this.showHint = false; this.Hint = null; this.WonGame = false; } }
// Method to check possible neighbours private int[] checkNeighbours(MazePosition currentPosition) { // List of possible neighbours List <int> result = new List <int>(); // Position of cell int x = currentPosition.x; int z = currentPosition.z; // Check wall +z if (z + 1 < sizeZ) // Check if its still in the maze size { if (cells[x, z + 1].visited == false) { result.Add(0); // Add wall to possible neighbours } } // Check wall +x if (x + 1 < sizeX) // Check if its still in the maze size { if (cells[x + 1, z].visited == false) { result.Add(1); // Add wall to possible neighbours } } // Check wall -x if (x - 1 >= 0) // Check if its still in the maze size { if (cells[x - 1, z].visited == false) { result.Add(2); // Add wall to possible neighbours } } // Check wall -z if (z - 1 >= 0) // Check if its still in the maze size { if (cells[x, z - 1].visited == false) { result.Add(3); // Add wall to possible neighbours } } // Return of neighbours return(result.ToArray()); }
public void FindShortestPathInMaze() { //S: start, E: end, X: wall char[][] maze = new[] { new char[] { 'X', 'S', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' }, new char[] { 'X', ' ', ' ', ' ', ' ', 'X', 'X', ' ', 'X', 'X' }, new char[] { 'X', ' ', 'X', ' ', ' ', ' ', 'X', ' ', ' ', ' ' }, new char[] { 'X', ' ', ' ', ' ', ' ', ' ', 'X', ' ', 'X', ' ' }, new char[] { 'X', 'X', 'X', ' ', 'X', ' ', 'X', ' ', 'X', ' ' }, new char[] { 'X', ' ', ' ', ' ', 'X', ' ', ' ', ' ', 'X', ' ' }, new char[] { 'X', ' ', 'X', 'X', 'X', ' ', 'X', 'X', 'X', ' ' }, new char[] { 'X', ' ', ' ', ' ', ' ', ' ', ' ', 'X', 'X', 'X' }, new char[] { 'X', 'X', 'X', 'X', 'X', 'X', 'E', 'X', 'X', 'X' }, }; var start = new MazePosition(1, 0); var end = new MazePosition(6, 8); var max = new MazePosition(9, 8); var path = Maze.FindFirstShortestPathBreadthFirst(start, end, maze, max); Assert.AreEqual(path.Count, 13); //S: start, E: end, X: wall maze = new[] { new char[] { 'X', 'S', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' }, new char[] { 'X', ' ', ' ', ' ', ' ', 'X', 'X', ' ', 'X', 'X' }, new char[] { 'X', ' ', 'X', ' ', ' ', ' ', 'X', ' ', ' ', ' ' }, new char[] { 'X', ' ', ' ', ' ', ' ', ' ', 'X', ' ', 'X', ' ' }, new char[] { 'X', 'X', 'X', ' ', 'X', ' ', 'X', ' ', 'X', ' ' }, new char[] { 'X', ' ', ' ', ' ', 'X', ' ', ' ', ' ', 'X', ' ' }, new char[] { 'X', ' ', 'X', 'X', 'X', 'X', 'X', 'X', 'X', ' ' }, new char[] { 'X', ' ', ' ', ' ', ' ', ' ', ' ', 'X', 'X', 'X' }, new char[] { 'X', 'X', 'X', 'X', 'X', 'X', 'E', 'X', 'X', 'X' }, }; start = new MazePosition(1, 0); end = new MazePosition(6, 8); max = new MazePosition(9, 8); path = Maze.FindFirstShortestPathBreadthFirst(start, end, maze, max); Assert.AreEqual(path.Count, 17); }
/// <summary> /// Gets the available positions from. /// </summary> /// <param name="pos">The position to move from.</param> /// <returns>the positions available</returns> public override List <MazePosition> GetAvailablePositionsFrom(MazePosition pos) { List <MazePosition> result = new List <MazePosition>(); if (this.mazeMatrix[pos.Row, pos.Colomn] == WALL) { return(result); } // upper cell if (pos.Row > 0) { if (this.mazeMatrix[pos.Row - 1, pos.Colomn] == PASS) { result.Add(new MazePosition(pos.Row - 2, pos.Colomn)); } } // lower cell if (pos.Row < this.height - 1) { if (this.mazeMatrix[pos.Row + 1, pos.Colomn] == PASS) { result.Add(new MazePosition(pos.Row + 2, pos.Colomn)); } } // right cell if (pos.Colomn < this.width - 1) { if (this.mazeMatrix[pos.Row, pos.Colomn + 1] == PASS) { result.Add(new MazePosition(pos.Row, pos.Colomn + 2)); } } // left cell if (pos.Colomn > 0) { if (this.mazeMatrix[pos.Row, pos.Colomn - 1] == PASS) { result.Add(new MazePosition(pos.Row, pos.Colomn - 2)); } } return(result); }
/// <summary> /// Solutions to string. /// </summary> /// <returns> /// the maze string with the solution on it /// </returns> public override string SolutionToString() { StringBuilder sb = new StringBuilder(this.ToString()); for (int i = 0; i < this.solution.Count - 1; i++) { sb.Replace(PASS, SOLPATH, this.solution[i].Row * (1 + this.width) + this.solution[i].Colomn, 1); sb.Replace(PASS, SOLPATH, this.solution[i + 1].Row * (1 + this.width) + this.solution[i + 1].Colomn, 1); MazePosition door = MazePosition.PositionBetween(this.solution[i], this.solution[i + 1]); sb.Replace(PASS, SOLPATH, door.Row * (1 + this.width) + door.Colomn, 1); } sb.Replace(SOLPATH, '*', this.startPosition.Row * (1 + this.width) + this.startPosition.Colomn, 1); sb.Replace(SOLPATH, '#', this.endPosition.Row * (1 + this.width) + this.endPosition.Colomn, 1); return(sb.ToString()); }
/// <summary> /// Moves the specified move. /// </summary> /// <param name="move">The move.</param> /// <returns></returns> public bool Move(Move move) { bool moved = false; switch (move) { case Model.Move.Up: if (this.playerPosition.Row > 0) { if (this.Maze[(this.playerPosition.Row - 1) * (this.cols * 2 - 1) + this.playerPosition.Col] == '0') { // move the player one cell up this.PlayerPosition.Row -= 2; moved = true; } } break; case Model.Move.Down: if (this.playerPosition.Row < this.rows * 2 - 2) { if (this.Maze[(this.playerPosition.Row + 1) * (this.cols * 2 - 1) + this.playerPosition.Col] == '0') { // move the player one cell down this.PlayerPosition.Row += 2; moved = true; } } break; case Model.Move.Right: if (this.playerPosition.Col < this.cols * 2 - 2) { if (this.Maze[this.playerPosition.Row * (this.cols * 2 - 1) + this.playerPosition.Col + 1] == '0') { // move the player one cell right this.PlayerPosition.Col += 2; moved = true; } } break; case Model.Move.Left: if (this.playerPosition.Col > 0) { if (this.Maze[this.playerPosition.Row * (this.cols * 2 - 1) + this.playerPosition.Col - 1] == '0') { // move the player one cell left this.PlayerPosition.Col -= 2; moved = true; } } break; } bool onSolution = false; // change the new hint according to the new player position for (int i = 0; i < this.solutionPath.Count; i++) { if (this.playerPosition.Row == this.solutionPath[i].Row && this.playerPosition.Col == this.solutionPath[i].Col) { this.Hint = this.solutionPath[i + 2]; onSolution = true; this.hintIndex = i; break; } } if (!onSolution) { this.Hint = this.solutionPath[this.hintIndex]; } return(moved); }
/// <summary> /// Moves the player and updates the server. /// </summary> /// <param name="move">The move.</param> /// <returns></returns> public bool Move(Move move) { bool moved = false; string direction = "play " + Enum.GetName(typeof(Move), move).ToLower(); switch (move) { case Model.Move.Up: if (this.playerPosition.Row > 0) { if (this.PlayerMaze[(this.playerPosition.Row - 1) * (this.cols * 2 - 1) + this.playerPosition.Col] == '0') { // move the player upwards and update the server. this.PlayerPosition.Row -= 2; moved = true; this.server.SendRequest(direction); } } break; case Model.Move.Down: if (this.playerPosition.Row < this.rows * 2 - 2) { if (this.PlayerMaze[(this.playerPosition.Row + 1) * (this.cols * 2 - 1) + this.playerPosition.Col] == '0') { // move the player downwards and update the server. this.PlayerPosition.Row += 2; moved = true; this.server.SendRequest(direction); } } break; case Model.Move.Right: if (this.playerPosition.Col < this.cols * 2 - 2) { if (this.PlayerMaze[this.playerPosition.Row * (this.cols * 2 - 1) + this.playerPosition.Col + 1] == '0') { // move the player to the right and update the server. this.PlayerPosition.Col += 2; moved = true; this.server.SendRequest(direction); } } break; case Model.Move.Left: if (this.playerPosition.Col > 0) { if (this.PlayerMaze[this.playerPosition.Row * (this.cols * 2 - 1) + this.playerPosition.Col - 1] == '0') { // move the player to the left and update the server. this.PlayerPosition.Col -= 2; moved = true; this.server.SendRequest(direction); } } break; } bool onSolution = false; // change the new hint according to the new player position for (int i = 0; i < this.solutionPath.Count; i++) { if (this.playerPosition.Row == this.solutionPath[i].Row && this.playerPosition.Col == this.solutionPath[i].Col) { this.Hint = this.solutionPath[i + 2]; onSolution = true; this.hintIndex = i; break; } } if (!onSolution) { this.Hint = this.solutionPath[this.hintIndex]; } return(moved); }
public MazePosition(MazePosition pos) { this.row = pos.row; this.col = pos.col; }