public void Initialize(int numRows, int numCols) { if (numRows > MAX_ROWS || numCols > MAX_COLS || numRows < 1 || numCols < 1) { throw new System.ArgumentException("El número de filas o columnas no es correcto para generar el laberinto"); } if (numRows % 2 == 0 || numCols % 2 == 0) { throw new System.ArgumentException("El número de filas y columnas ha de ser impar"); } rows = numRows; cols = numCols; // Calcular celda de inicio startingCellIndex = GetStartingCell(); // Al inicio todas las celdas están bloqueadas for (int i = 0; i < MAX_ROWS; i++) { for (int j = 0; j < MAX_COLS; j++) { maze[i, j] = new MazeCell(MazeCellType.LOCKED, false); } } }
// Añade el vecino con distancia [rowDelta, colDelta] a la lista list, si es del tipo type (null si no importa el tipo) private void AddNeighbourToList(MazeCellIndex cell, int rowDelta, int colDelta, List <MazeCellIndex> list, MazeCellType?type = null) { if (MazeContainsCell(cell.row + rowDelta, cell.col + colDelta) && (type == null || type == maze[cell.row + rowDelta, cell.col + colDelta].type)) { list.Add(new MazeCellIndex(cell.row + rowDelta, cell.col + colDelta)); } }
// Añade los 4 vecinos con distancia de 2 a la lista list, si son del tipo type (null si no importa el tipo) private void AddNeighboursToList(MazeCellIndex cell, List <MazeCellIndex> list, MazeCellType?type = null) { AddNeighbourToList(cell, 2, 0, list, type); // Top AddNeighbourToList(cell, 0, 2, list, type); // Right AddNeighbourToList(cell, -2, 0, list, type); // Bottom AddNeighbourToList(cell, 0, -2, list, type); // Left }
private void SetMazeCell(MazeCellIndex index, MazeCellType type) { maze[index.row, index.col].type = type; // Ejecutar evento if (OnMazeCellTypeChanged != null) { OnMazeCellTypeChanged(index); } }
public void Generate() { cancel = false; // La celda de inicio es startingCellIndex. Se añaden sus vecinos bloqueados al array y se desbloquea. AddNeighboursToList(startingCellIndex, lockedNeighbours, MazeCellType.LOCKED); SetMazeCell(startingCellIndex, MazeCellType.UNLOCKED); while (!cancel && lockedNeighbours.Count > 0) { // Obtener una celda bloqueada al azar MazeCellIndex randomLockedCell = lockedNeighbours[random.Next(lockedNeighbours.Count)]; // Si aún no he visitado la celda bloqueada if (!maze[randomLockedCell.row, randomLockedCell.col].visited) { // La marco como visitada maze[randomLockedCell.row, randomLockedCell.col].visited = true; // Obtener un vecino desbloqueado al azar de la celda bloqueada anterior AddNeighboursToList(randomLockedCell, unlockedNeighbours, MazeCellType.UNLOCKED); MazeCellIndex randomUnlockedCell = unlockedNeighbours[random.Next(unlockedNeighbours.Count)]; unlockedNeighbours.Clear(); // Desbloquear celda intermedia entre las celdas anteriores MazeCellIndex betweenCellIndex = new MazeCellIndex((randomLockedCell.row + randomUnlockedCell.row) / 2, (randomLockedCell.col + randomUnlockedCell.col) / 2); SetMazeCell(betweenCellIndex, MazeCellType.UNLOCKED); // Guardar vecinos bloqueados de randomLockedCell AddNeighboursToList(randomLockedCell, lockedNeighbours, MazeCellType.LOCKED); // No desbloqueo celdas que estén en el borde del laberinto // if (!CellIsAtEdge(randomLockedCell.row, randomLockedCell.col)) { // Desbloquear la celda bloqueada SetMazeCell(randomLockedCell, MazeCellType.UNLOCKED); // } } // Quitar la celda bloqueada del array de bloqueadas lockedNeighbours.Remove(randomLockedCell); } // Vaciar array de bloqueadas (por si se ha cancelado la ejecución) lockedNeighbours.Clear(); }