PuzzleGame/DungeonMapGenerator/DungeonMapGenerator/Room.cs

163 lines
No EOL
4.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace DungeonMapGenerator
{
public enum RoomSide
{
Top,
Bottom,
Left,
Right
}
[JsonConverter(typeof(StringEnumConverter))]
public enum RoomType
{
Normal,
Entrance,
Monster,
Boss
}
public class Room
{
private static int _nextId = 1;
public RoomType TypeOfRoom { get; set; }
public int Height { get; set; }
public int Width { get; set; }
public Point PositionOfTopLeft { get; set; }
public int Id { get; set; }
[JsonProperty("AdjacentRoomIds")]
private HashSet<int> _adjacentRoomIds = new HashSet<int>();
private readonly Dictionary<RoomSide, List<Room>> _adjacentRoomsBySide = new Dictionary<RoomSide, List<Room>>();
public Room()
{
}
public Room(RoomType roomType, int width, int height, Point positionOfTopLeft)
{
Id = _nextId++;
TypeOfRoom = roomType;
Width = width;
Height = height;
PositionOfTopLeft = positionOfTopLeft;
}
public void AddAdjacentRoomId(int id)
{
_adjacentRoomIds.Add(id);
}
public HashSet<int> GetAdjacentRoomIds()
{
return new HashSet<int>(_adjacentRoomIds);
}
public List<Point> GetPointsInRoom()
{
List<Point> points = new List<Point>();
for (int i = 0; i < Width; i++)
{
for (int j = 0; j < Height; j++)
{
points.Add(new Point(PositionOfTopLeft.X + i, PositionOfTopLeft.Y + j));
}
}
return points;
}
public bool ContainsPoint(Point point)
{
return GetPointsInRoom().Any(p => p.Equals(point));
}
public int GetDistanceToRoom(Room other)
{
Point centerOfRoom = GetCenterOfRoom();
Point centerOfOther = other.GetCenterOfRoom();
return centerOfRoom.ManhattanDistance(centerOfOther);
}
public Point GetCenterOfRoom()
{
return new Point(PositionOfTopLeft.X + Width / 2, PositionOfTopLeft.Y + Height / 2);
}
public void AddAdjacentRoomBySide(Room room, RoomSide side)
{
if (!_adjacentRoomsBySide.ContainsKey(side))
{
_adjacentRoomsBySide[side] = new List<Room>();
}
// Prevent duplicates
if (!_adjacentRoomsBySide[side].Contains(room))
{
_adjacentRoomsBySide[side].Add(room);
room.AddAdjacentRoomBySide(this, GetOppositeSide(side)); // Ensure bidirectional linkage
}
}
public IEnumerable<Room> GetAdjacentRooms()
{
return _adjacentRoomsBySide.Values.SelectMany(roomList => roomList);
}
public Dictionary<RoomSide, List<Room>> GetAdjacentRoomsDict()
{
return new Dictionary<RoomSide, List<Room>>(_adjacentRoomsBySide);
}
public List<(Point, RoomSide)> GetAdjacentPoints()
{
var adjacentPoints = new List<(Point, RoomSide)>();
int x = PositionOfTopLeft.X;
int y = PositionOfTopLeft.Y;
int width = Width;
int height = Height;
// Add points to the left and right of the room
for (int i = 0; i < height; i++)
{
adjacentPoints.Add((new Point(x - 1, y + i), RoomSide.Left));
adjacentPoints.Add((new Point(x + width, y + i), RoomSide.Right));
}
// Add points above and below the room
for (int i = 0; i < width; i++)
{
adjacentPoints.Add((new Point(x + i, y - 1), RoomSide.Top));
adjacentPoints.Add((new Point(x + i, y + height), RoomSide.Bottom));
}
return adjacentPoints;
}
// Helper method to get the opposite side
private RoomSide GetOppositeSide(RoomSide side)
{
switch (side)
{
case RoomSide.Top:
return RoomSide.Bottom;
case RoomSide.Bottom:
return RoomSide.Top;
case RoomSide.Left:
return RoomSide.Right;
case RoomSide.Right:
return RoomSide.Left;
default:
throw new ArgumentException("Invalid RoomSide", nameof(side));
}
}
}
}