public async void GenerateMaze(MazeCell startCell = null, Random randomGenerator = null) { var rnd = randomGenerator ?? new Random(); //Random Generation Start Point attempt if first cell is not set; var firstCell = startCell ?? CompleteMaze[rnd.Next(SizeX), rnd.Next(SizeY), rnd.Next(SizeZ)]; firstCell.Info = "Start"; firstCell.Visited = true; var movementList = new List <MazeCell> { firstCell }; //TEST - making UP/Down ways much less to appear (attempt at least) :P var floorChanceInit = SizeX * SizeY * SizeZ / 50 > 0 ? SizeX * SizeY * SizeZ / 50 : 1; var floorChance = floorChanceInit; var floorSwitch = 1; do { var index = GetNextCellIndexToMoveFrom(movementList, rnd); var currentCell = movementList[index]; var dir = GetNextMove(rnd, floorChance, currentCell, out var nextMazeCell); if (nextMazeCell == null) { TryToUnstuck(movementList, currentCell, index); } else { RemoveCellsWithNoPossibleMoves(movementList); if (dir == MoveDirection.Up || dir == MoveDirection.Down) { floorSwitch++; floorChance *= floorSwitch; } else { if (floorChance > 100) { floorChance = (int)Math.Sqrt(floorChance); } else if (floorChance > floorChanceInit * 2) { floorChance = floorChance - 1 > 0 ? floorChance - 1 : 3; } } AdjustWallsAndLadders(dir, currentCell, nextMazeCell); ProceedCell(nextMazeCell, currentCell.DistanceFromStart + 1, movementList); } currentCell.Update(); if (NextCellDelay > 0) { await Task.Delay(NextCellDelay); } } while (movementList.Count > 0); MazeGenerated?.Invoke(this, EventArgs.Empty); }
private static void AdjustWallsAndLadders(MoveDirection dir, MazeCell currentCell, MazeCell nextMazeCell) { switch (dir) { case MoveDirection.Top: currentCell.WTop = false; nextMazeCell.WBot = false; break; case MoveDirection.Right: currentCell.WRight = false; nextMazeCell.WLeft = false; break; case MoveDirection.Bottom: currentCell.WBot = false; nextMazeCell.WTop = false; break; case MoveDirection.Left: currentCell.WLeft = false; nextMazeCell.WRight = false; break; case MoveDirection.Up: currentCell.Up = true; nextMazeCell.Down = true; break; case MoveDirection.Down: currentCell.Down = true; nextMazeCell.Up = true; break; } }
private static void RemoveCellFromListAndMarkAsDone(MazeCell cellToCheck, ICollection <MazeCell> mList) { cellToCheck.Finished = true; cellToCheck.Update(); mList.Remove(cellToCheck); }
private MoveDirection GetNextMove(Random rnd, int floorChance, MazeCell currentCell, out MazeCell nextMazeCell) { var possibleMoves = Enumerable.Range(0, 5).OrderBy(x => rnd.Next()).Take(5); MoveDirection dir = 0; nextMazeCell = null; foreach (var item in possibleMoves) { dir = GetNextMoveDirection(item, rnd, floorChance); if (dir == MoveDirection.None) { continue; } var nextCoords = currentCell.GetCoords().AdjustCoords(dir); if (nextCoords.ValidateCoordinates(SizeX, SizeY, SizeZ)) { if (TryGetNextCellToMove(nextCoords, currentCell, out nextMazeCell)) { break; } } } return(dir); }