163 lines
No EOL
4.7 KiB
C#
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));
|
|
}
|
|
}
|
|
}
|
|
} |