2026-04-21 23:28:49 +07:00
|
|
|
using System.Collections;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using Hallucinate.GameSetup.Maze.Extensions;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
namespace Hallucinate.GameSetup.Maze
|
|
|
|
|
{
|
|
|
|
|
public class RecursiveAlgorithm : IMazeAlgorithm
|
|
|
|
|
{
|
|
|
|
|
private const int StartX = 5;
|
|
|
|
|
private const int StartZ = 5;
|
|
|
|
|
private const int DeadEndNeighbourThreshold = 2;
|
|
|
|
|
|
|
|
|
|
private readonly List<MapLocation> _directions = MapLocation.Directions;
|
|
|
|
|
|
|
|
|
|
public void Generate(MazeGrid grid)
|
|
|
|
|
{
|
|
|
|
|
GenerateRecursive(grid, StartX, StartZ);
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-26 00:21:29 +07:00
|
|
|
public IEnumerator GenerateStepByStep(MazeGrid grid, int cellsPerFrame)
|
2026-04-21 23:28:49 +07:00
|
|
|
{
|
2026-06-26 00:21:29 +07:00
|
|
|
yield return GenerateRecursiveStepByStep(grid, StartX, StartZ, cellsPerFrame);
|
2026-04-21 23:28:49 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void GenerateRecursive(MazeGrid grid, int x, int z)
|
|
|
|
|
{
|
|
|
|
|
if (grid.CountSquareNeighbours(x, z, MazeCellType.Corridor) >= DeadEndNeighbourThreshold) return;
|
|
|
|
|
|
|
|
|
|
grid.SetCell(x, z, MazeCellType.Corridor);
|
|
|
|
|
|
|
|
|
|
List<MapLocation> shuffledDirs = new List<MapLocation>(_directions);
|
|
|
|
|
shuffledDirs.Shuffle();
|
|
|
|
|
|
|
|
|
|
foreach (var dir in shuffledDirs)
|
|
|
|
|
{
|
|
|
|
|
int nx = x + dir.x;
|
|
|
|
|
int nz = z + dir.z;
|
|
|
|
|
if (grid.IsInBounds(nx, nz))
|
|
|
|
|
{
|
|
|
|
|
GenerateRecursive(grid, nx, nz);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-26 00:21:29 +07:00
|
|
|
private IEnumerator GenerateRecursiveStepByStep(MazeGrid grid, int x, int z, int cellsPerFrame)
|
2026-04-21 23:28:49 +07:00
|
|
|
{
|
|
|
|
|
if (grid.CountSquareNeighbours(x, z, MazeCellType.Corridor) >= DeadEndNeighbourThreshold) yield break;
|
|
|
|
|
|
|
|
|
|
grid.SetCell(x, z, MazeCellType.Processing);
|
2026-06-26 00:21:29 +07:00
|
|
|
MazeManager.cellsProcessedThisFrame++;
|
|
|
|
|
if (MazeManager.cellsProcessedThisFrame >= cellsPerFrame)
|
|
|
|
|
{
|
|
|
|
|
MazeManager.cellsProcessedThisFrame = 0;
|
|
|
|
|
yield return null;
|
|
|
|
|
}
|
2026-04-21 23:28:49 +07:00
|
|
|
|
|
|
|
|
grid.SetCell(x, z, MazeCellType.Corridor);
|
|
|
|
|
|
|
|
|
|
List<MapLocation> shuffledDirs = new List<MapLocation>(_directions);
|
|
|
|
|
shuffledDirs.Shuffle();
|
|
|
|
|
|
|
|
|
|
foreach (var dir in shuffledDirs)
|
|
|
|
|
{
|
|
|
|
|
int nx = x + dir.x;
|
|
|
|
|
int nz = z + dir.z;
|
|
|
|
|
if (grid.IsInBounds(nx, nz))
|
|
|
|
|
{
|
2026-06-26 00:21:29 +07:00
|
|
|
yield return GenerateRecursiveStepByStep(grid, nx, nz, cellsPerFrame);
|
2026-04-21 23:28:49 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|