Files
BABA_YAGA/Assets/Scripts/GameSetup/Maze/PrimsAlgorithm.cs

107 lines
3.7 KiB
C#
Raw Normal View History

2026-04-21 23:28:49 +07:00
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Hallucinate.GameSetup.Maze
{
public class PrimsAlgorithm : IMazeAlgorithm
{
private const int InitialX = 2;
private const int InitialZ = 2;
private const int MaxIterations = 10000;
private const int TargetCorridorNeighbours = 1;
public void Generate(MazeGrid grid)
{
int x = InitialX;
int z = InitialZ;
grid.SetCell(x, z, MazeCellType.Corridor);
List<MapLocation> walls = GetNeighbouringWalls(grid, x, z);
int iterations = 0;
while (walls.Count > 0 && iterations < MaxIterations)
{
int rIndex = Random.Range(0, walls.Count);
MapLocation w = walls[rIndex];
walls.RemoveAt(rIndex);
if (grid.CountSquareNeighbours(w.x, w.z, MazeCellType.Corridor) == TargetCorridorNeighbours)
{
grid.SetCell(w.x, w.z, MazeCellType.Corridor);
2026-04-22 00:29:09 +07:00
foreach (var nw in GetNeighbouringWalls(grid, w.x, w.z))
{
if (!walls.Contains(nw)) walls.Add(nw);
}
2026-04-21 23:28:49 +07:00
}
iterations++;
}
}
public IEnumerator GenerateStepByStep(MazeGrid grid, float interval)
{
int x = InitialX;
int z = InitialZ;
grid.SetCell(x, z, MazeCellType.Corridor);
yield return new WaitForSeconds(interval);
List<MapLocation> walls = GetNeighbouringWalls(grid, x, z);
foreach(var w in walls) grid.SetCell(w.x, w.z, MazeCellType.Processing);
int iterations = 0;
while (walls.Count > 0 && iterations < MaxIterations)
{
int rIndex = Random.Range(0, walls.Count);
MapLocation w = walls[rIndex];
walls.RemoveAt(rIndex);
if (grid.CountSquareNeighbours(w.x, w.z, MazeCellType.Corridor) == TargetCorridorNeighbours)
{
grid.SetCell(w.x, w.z, MazeCellType.Corridor);
if (interval > 0) yield return new WaitForSeconds(interval);
2026-04-22 00:29:09 +07:00
foreach (var nw in GetNeighbouringWalls(grid, w.x, w.z))
2026-04-21 23:28:49 +07:00
{
if (grid.GetCell(nw.x, nw.z) == MazeCellType.Wall)
{
grid.SetCell(nw.x, nw.z, MazeCellType.Processing);
walls.Add(nw);
}
}
}
else
{
2026-04-22 00:29:09 +07:00
// If it's no longer a candidate, turn it back to Wall
grid.SetCell(w.x, w.z, MazeCellType.Wall);
2026-04-21 23:28:49 +07:00
}
iterations++;
}
}
private List<MapLocation> GetNeighbouringWalls(MazeGrid grid, int x, int z)
{
List<MapLocation> neighbours = new List<MapLocation>();
foreach (var dir in MapLocation.Directions)
{
int nx = x + dir.x;
2026-04-22 00:29:09 +07:00
int nz = z + dir.z;
// Correction
nx = x + dir.x;
nz = z + dir.z;
if (grid.IsInBounds(nx, nz))
2026-04-21 23:28:49 +07:00
{
2026-04-22 00:29:09 +07:00
MazeCellType type = grid.GetCell(nx, nz);
if (type == MazeCellType.Wall || type == MazeCellType.Processing)
{
neighbours.Add(new MapLocation(nx, nz));
}
2026-04-21 23:28:49 +07:00
}
}
return neighbours;
}
}
}