168 lines
5.4 KiB
C#
168 lines
5.4 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace Hallucinate.GameSetup.Maze
|
|
{
|
|
/// <summary>
|
|
/// Central controller for the Maze system.
|
|
/// Manages algorithm selection, debug speed, and regeneration.
|
|
/// </summary>
|
|
public class MazeManager : MonoBehaviour
|
|
{
|
|
public enum AlgorithmType { Recursive, Wilsons, Prims, Crawler }
|
|
|
|
[Header("System Settings")]
|
|
public MazeGrid[] mazes;
|
|
public float floorHeight = 3.5f;
|
|
public int connectionsPerFloor = 2;
|
|
[SerializeField] private AlgorithmType selectedAlgorithm;
|
|
[SerializeField] private int width = 30;
|
|
[SerializeField] private int depth = 30;
|
|
|
|
[Header("Debug Settings")]
|
|
[SerializeField] private bool debugMode = true;
|
|
[Range(0.001f, 0.5f)]
|
|
[SerializeField] private float visualizationInterval = 0.05f;
|
|
|
|
[Header("References")]
|
|
[SerializeField] private MazeRenderer mazeRenderer;
|
|
[SerializeField] private Transform mazeContainer;
|
|
|
|
[Header("Corridor Setting")]
|
|
public GameObject straightManHoleLadder;
|
|
public GameObject straightManHoleUp;
|
|
public GameObject deadendManHoleLadder;
|
|
public GameObject deadendManHoleUp;
|
|
|
|
|
|
|
|
private MazeGrid _grid;
|
|
private Coroutine _generationCoroutine;
|
|
|
|
private void Start()
|
|
{
|
|
Regenerate();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (Input.GetKeyDown(KeyCode.R))
|
|
{
|
|
Regenerate();
|
|
}
|
|
}
|
|
|
|
[ContextMenu("Regenerate")]
|
|
public void Regenerate()
|
|
{
|
|
if (_generationCoroutine != null)
|
|
{
|
|
StopCoroutine(_generationCoroutine);
|
|
}
|
|
|
|
mazeRenderer.Clear();
|
|
|
|
// Step 1: Initialize all maze floors
|
|
for (int i = 0; i < mazes.Length; i++)
|
|
{
|
|
mazes[i] = new MazeGrid(width, depth);
|
|
mazes[i].Level = i;
|
|
|
|
// Generate each floor using the selected algorithm
|
|
IMazeAlgorithm algorithmForFloor = GetAlgorithm(selectedAlgorithm);
|
|
algorithmForFloor.Generate(mazes[i]);
|
|
}
|
|
|
|
// Step 2: Create connections between adjacent floors
|
|
for (int i = 0; i < mazes.Length - 1; i++)
|
|
{
|
|
MazeGrid currentFloor = mazes[i];
|
|
MazeGrid nextFloor = mazes[i + 1];
|
|
|
|
List<Vector2Int> possibleConnections = new List<Vector2Int>();
|
|
|
|
for (int z = 0; z < depth; z++)
|
|
{
|
|
for (int x = 0; x < width; x++)
|
|
{
|
|
// Check if both floors have a corridor at this position
|
|
bool isCurrentFloorPath = currentFloor.GetCell(x, z) == MazeCellType.Corridor;
|
|
bool isNextFloorPath = nextFloor.GetCell(x, z) == MazeCellType.Corridor;
|
|
|
|
if (isCurrentFloorPath && isNextFloorPath)
|
|
{
|
|
possibleConnections.Add(new Vector2Int(x, z));
|
|
}
|
|
}
|
|
}
|
|
|
|
ShuffleList(possibleConnections);
|
|
|
|
int connectionsMade = 0;
|
|
foreach (Vector2Int pos in possibleConnections)
|
|
{
|
|
if (connectionsMade >= connectionsPerFloor) break;
|
|
|
|
int x = pos.x;
|
|
int z = pos.y;
|
|
|
|
// Set stair cells
|
|
currentFloor.SetCell(x, z, MazeCellType.StairUp);
|
|
nextFloor.SetCell(x, z, MazeCellType.StairDown);
|
|
|
|
connectionsMade++;
|
|
}
|
|
}
|
|
|
|
// Step 3: Render all floors
|
|
if (mazes.Length > 0)
|
|
{
|
|
for (int i = 0; i < mazes.Length; i++)
|
|
{
|
|
mazeRenderer.Initialize(mazes[i], mazeContainer, i == 0);
|
|
}
|
|
_grid = mazes[0];
|
|
}
|
|
else
|
|
{
|
|
_grid = new MazeGrid(width, depth);
|
|
mazeRenderer.Initialize(_grid, mazeContainer);
|
|
|
|
IMazeAlgorithm algorithm = GetAlgorithm(selectedAlgorithm);
|
|
|
|
if (debugMode)
|
|
{
|
|
_generationCoroutine = StartCoroutine(algorithm.GenerateStepByStep(_grid, visualizationInterval));
|
|
}
|
|
else
|
|
{
|
|
algorithm.Generate(_grid);
|
|
}
|
|
}
|
|
}
|
|
private void ShuffleList<T>(List<T> list)
|
|
{
|
|
for (int i = 0; i < list.Count; i++)
|
|
{
|
|
T temp = list[i];
|
|
int randomIndex = Random.Range(i, list.Count);
|
|
list[i] = list[randomIndex];
|
|
list[randomIndex] = temp;
|
|
}
|
|
}
|
|
|
|
private IMazeAlgorithm GetAlgorithm(AlgorithmType type)
|
|
{
|
|
return type switch
|
|
{
|
|
AlgorithmType.Recursive => new RecursiveAlgorithm(),
|
|
AlgorithmType.Wilsons => new WilsonsAlgorithm(),
|
|
AlgorithmType.Prims => new PrimsAlgorithm(),
|
|
AlgorithmType.Crawler => new CrawlerAlgorithm(),
|
|
_ => new RecursiveAlgorithm()
|
|
};
|
|
}
|
|
}
|
|
}
|