| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- using UnityEngine;
- using System.Collections.Generic;
- using System.Linq;
- /// <summary>
- /// Holds all data for a generated maze
- /// This is the core representation that can be used for rendering, pathfinding, and AI
- /// </summary>
- public class MazeData
- {
- public int Width { get; private set; }
- public int Height { get; private set; }
- public MazeTile[,] Tiles { get; private set; }
- public List<MazeRoom> Rooms { get; private set; } = new();
- public List<Vector2Int> StartPoints { get; private set; } = new();
- public List<Vector2Int> 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);
- }
- }
- }
- /// <summary>
- /// Sets a tile at the given position
- /// </summary>
- public void SetTile(int x, int y, MazeTile tile)
- {
- if (IsInBounds(x, y))
- {
- Tiles[x, y] = tile;
- }
- }
- /// <summary>
- /// Gets a tile at the given position
- /// </summary>
- public MazeTile GetTile(int x, int y)
- {
- if (IsInBounds(x, y))
- {
- return Tiles[x, y];
- }
- return null;
- }
- /// <summary>
- /// Checks if coordinates are within maze bounds
- /// </summary>
- public bool IsInBounds(int x, int y)
- {
- return x >= 0 && x < Width && y >= 0 && y < Height;
- }
- /// <summary>
- /// Checks if a tile is walkable
- /// </summary>
- public bool IsWalkable(int x, int y)
- {
- var tile = GetTile(x, y);
- return tile != null && tile.IsWalkable();
- }
- /// <summary>
- /// Fills a rectangular area with floor tiles and assigns to a room
- /// </summary>
- 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;
- }
- /// <summary>
- /// Creates floor tiles along a path (for hallways/corridors)
- /// </summary>
- public int DrawPath(List<Vector2Int> 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;
- }
- /// <summary>
- /// Adds a room to the maze
- /// </summary>
- 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;
- }
- /// <summary>
- /// Gets all rooms of a specific type
- /// </summary>
- public List<MazeRoom> GetRoomsByType(MazeRoom.RoomType type)
- {
- return Rooms.Where(r => r.Type == type).ToList();
- }
- /// <summary>
- /// Gets the room at a specific tile position
- /// </summary>
- 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;
- }
- /// <summary>
- /// Adds a start point
- /// </summary>
- public void AddStartPoint(Vector2Int point)
- {
- if (IsWalkable(point.x, point.y))
- {
- StartPoints.Add(point);
- }
- }
- /// <summary>
- /// Adds an exit point
- /// </summary>
- public void AddExitPoint(Vector2Int point)
- {
- if (IsWalkable(point.x, point.y))
- {
- ExitPoints.Add(point);
- }
- }
- /// <summary>
- /// Gets all adjacent walkable tiles
- /// </summary>
- public List<Vector2Int> GetAdjacentWalkable(int x, int y)
- {
- var adjacent = new List<Vector2Int>();
- 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;
- }
- /// <summary>
- /// Gets statistics about the maze
- /// </summary>
- 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}";
- }
- }
|