using UnityEngine;
using System.Collections.Generic;
using System.Linq;
///
/// Holds all data for a generated maze
/// This is the core representation that can be used for rendering, pathfinding, and AI
///
public class MazeData
{
public int Width { get; private set; }
public int Height { get; private set; }
public MazeTile[,] Tiles { get; private set; }
public List Rooms { get; private set; } = new();
public List StartPoints { get; private set; } = new();
public List ExitPoints { get; private set; } = new();
private int nextRoomId = 0;
public MazeData(int width, int height)
{
Width = width;
Height = height;
Tiles = new MazeTile[width, height];
// Initialize all tiles as walls
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
Tiles[x, y] = new MazeTile(x, y);
}
}
}
///
/// Sets a tile at the given position
///
public void SetTile(int x, int y, MazeTile tile)
{
if (IsInBounds(x, y))
{
Tiles[x, y] = tile;
}
}
///
/// Gets a tile at the given position
///
public MazeTile GetTile(int x, int y)
{
if (IsInBounds(x, y))
{
return Tiles[x, y];
}
return null;
}
///
/// Checks if coordinates are within maze bounds
///
public bool IsInBounds(int x, int y)
{
return x >= 0 && x < Width && y >= 0 && y < Height;
}
///
/// Checks if a tile is walkable
///
public bool IsWalkable(int x, int y)
{
var tile = GetTile(x, y);
return tile != null && tile.IsWalkable();
}
///
/// Fills a rectangular area with floor tiles and assigns to a room
///
public int FillRoom(int minX, int minY, int maxX, int maxY, int roomId, MazeTile.TerrainType terrain = MazeTile.TerrainType.Normal)
{
int changedTiles = 0;
for (int x = minX; x <= maxX; x++)
{
for (int y = minY; y <= maxY; y++)
{
if (IsInBounds(x, y))
{
var tile = GetTile(x, y);
if (tile.Type != MazeTile.TileType.Floor)
{
changedTiles++;
}
tile.Type = MazeTile.TileType.Floor;
tile.Terrain = terrain;
tile.RoomId = roomId;
}
}
}
return changedTiles;
}
///
/// Creates floor tiles along a path (for hallways/corridors)
///
public int DrawPath(List path, int hallwayWidth, int roomId = -1)
{
int changedTiles = 0;
foreach (var point in path)
{
for (int dx = -hallwayWidth / 2; dx <= hallwayWidth / 2; dx++)
{
for (int dy = -hallwayWidth / 2; dy <= hallwayWidth / 2; dy++)
{
int x = point.x + dx;
int y = point.y + dy;
if (IsInBounds(x, y))
{
var tile = GetTile(x, y);
if (tile.Type != MazeTile.TileType.Floor) // Don't overwrite existing floors
{
changedTiles++;
tile.Type = MazeTile.TileType.Floor;
tile.Terrain = MazeTile.TerrainType.Normal;
if (tile.RoomId == -1)
{
tile.RoomId = roomId;
}
}
}
}
}
}
return changedTiles;
}
///
/// Adds a room to the maze
///
public MazeRoom AddRoom(int minX, int minY, int maxX, int maxY, MazeRoom.RoomType roomType = MazeRoom.RoomType.Normal)
{
var room = new MazeRoom(nextRoomId++, minX, minY, maxX, maxY, roomType);
Rooms.Add(room);
return room;
}
///
/// Gets all rooms of a specific type
///
public List GetRoomsByType(MazeRoom.RoomType type)
{
return Rooms.Where(r => r.Type == type).ToList();
}
///
/// Gets the room at a specific tile position
///
public MazeRoom GetRoomAtTile(int x, int y)
{
var tile = GetTile(x, y);
if (tile != null && tile.RoomId >= 0)
{
return Rooms.FirstOrDefault(r => r.Id == tile.RoomId);
}
return null;
}
///
/// Adds a start point
///
public void AddStartPoint(Vector2Int point)
{
if (IsWalkable(point.x, point.y))
{
StartPoints.Add(point);
}
}
///
/// Adds an exit point
///
public void AddExitPoint(Vector2Int point)
{
if (IsWalkable(point.x, point.y))
{
ExitPoints.Add(point);
}
}
///
/// Gets all adjacent walkable tiles
///
public List GetAdjacentWalkable(int x, int y)
{
var adjacent = new List();
Vector2Int[] directions = new[]
{
new Vector2Int(x + 1, y),
new Vector2Int(x - 1, y),
new Vector2Int(x, y + 1),
new Vector2Int(x, y - 1),
};
foreach (var dir in directions)
{
if (IsWalkable(dir.x, dir.y))
{
adjacent.Add(dir);
}
}
return adjacent;
}
///
/// Gets statistics about the maze
///
public string GetStatistics()
{
int floorTiles = 0;
int wallTiles = 0;
for (int x = 0; x < Width; x++)
{
for (int y = 0; y < Height; y++)
{
if (GetTile(x, y).IsWalkable())
floorTiles++;
else
wallTiles++;
}
}
return $"Maze Statistics:\n" +
$" Size: {Width}x{Height}\n" +
$" Rooms: {Rooms.Count}\n" +
$" Floor Tiles: {floorTiles}\n" +
$" Wall Tiles: {wallTiles}\n" +
$" Start Points: {StartPoints.Count}\n" +
$" Exit Points: {ExitPoints.Count}";
}
}