PuzzleGame/DungeonMapGenerator/DungeonMapGenerator/DungeonMap.cs

229 lines
No EOL
7.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
namespace DungeonMapGenerator
{
public class DungeonMap
{
[JsonProperty("Width")]
public int Width;
[JsonProperty("Height")]
public int Height;
[JsonProperty("MonsterRooms")]
private List<Room> _monsterRooms = new List<Room>();
[JsonProperty("EntranceRooms")]
private List<Room> _entranceRooms = new List<Room>();
[JsonProperty("NormalRooms")]
private List<Room> _normalRooms = new List<Room>();
[JsonProperty("BossRoom")]
private Room _bossRoom;
private HashSet<Point> _unoccupiedPoints = new HashSet<Point>();
private HashSet<Point> _occupiedPoints = new HashSet<Point>();
public DungeonMap(){ }
public DungeonMap(int width, int height)
{
this.Width = width;
Height = height;
_unoccupiedPoints.AddRange(Enumerable.Range(0, this.Width)
.SelectMany(x => Enumerable.Range(0, Height)
.Select(y => new Point(x,y))));
}
public Dictionary<Point, int> GetPointRoomIdMapping()
{
var pointRoomMap = new Dictionary<Point, int>();
foreach (var room in GetAllRooms())
{
foreach (var point in room.GetPointsInRoom())
{
pointRoomMap[point] = room.Id;
}
}
return pointRoomMap;
}
public List<Room> GetAllRooms()
{
List<Room> allRooms = new List<Room>();
allRooms.AddRange(_monsterRooms);
allRooms.AddRange(_normalRooms);
allRooms.AddRange(_entranceRooms);
allRooms.Add(_bossRoom);
return allRooms;
}
public void AddRoom(Room room)
{
switch (room.TypeOfRoom)
{
case RoomType.Monster:
_monsterRooms.Add(room);
break;
case RoomType.Entrance:
_entranceRooms.Add(room);
break;
case RoomType.Normal:
_normalRooms.Add(room);
break;
case RoomType.Boss:
_bossRoom = room;
break;
default:
return;
}
AddPointsToOccupied(room.GetPointsInRoom());
}
public void AddRooms(List<Room> rooms)
{
if (rooms.Count == 0) return;
switch (rooms[0].TypeOfRoom)
{
case RoomType.Monster:
_monsterRooms.AddRange(rooms);
break;
case RoomType.Entrance:
_entranceRooms.AddRange(rooms);
break;
case RoomType.Normal:
_normalRooms.AddRange(rooms);
break;
default:
return;
}
AddPointsToOccupied(rooms.SelectMany(room => room.GetPointsInRoom()).ToList());
}
public List<Room> GetMonsterRooms()
{
return _monsterRooms;
}
public Room GetBossRoom()
{
return _bossRoom;
}
public List<Room> GetEntranceRooms()
{
return _entranceRooms;
}
public List<Room> GetNormalRooms()
{
return _normalRooms;
}
public HashSet<Point> GetUnoccupiedPoints()
{
return new HashSet<Point>(_unoccupiedPoints);
}
public HashSet<Point> GetOccupiedPoints()
{
return new HashSet<Point>(_occupiedPoints);
}
public string GetMapAsString()
{
List<Point> monsterRoomPoints = _monsterRooms.SelectMany(room => room.GetPointsInRoom()).ToList();
List<Point> entranceRoomPoints = _entranceRooms.SelectMany(room => room.GetPointsInRoom()).ToList();
List<Point> normalRoomPoints = _normalRooms.SelectMany(room => room.GetPointsInRoom()).ToList();
char[,] mapMatrix = new Char[Width, Height];
for (int x = 0; x < Width; x++)
{
for (int y = 0; y < Height; y++)
{
Point point = new Point(x, y);
if (entranceRoomPoints.Contains(point))
{
mapMatrix[x, y] = '*';
}
else if (monsterRoomPoints.Contains(point))
{
mapMatrix[x, y] = 'X';
}
else if (_bossRoom.GetPointsInRoom().Contains(point))
{
mapMatrix[x, y] = 'B';
}
else if (normalRoomPoints.Contains(point))
{
mapMatrix[x, y] = 'N';
}
else
{
mapMatrix[x, y] = '-';
}
}
}
StringBuilder sb = new StringBuilder();
for (int j = 0; j < mapMatrix.GetLength(1); j++)
{
for (int i = 0; i < mapMatrix.GetLength(0); i++)
{
sb.Append(mapMatrix[i, j] + " ");
}
sb.Append(Environment.NewLine);
}
return $"{DateTime.Now}{Environment.NewLine}" +
$"X Length: {Width}{Environment.NewLine}" +
$"Y Length: {Height}{Environment.NewLine}" +
$"Monster Rooms: {_monsterRooms.Count}{Environment.NewLine}" +
sb.ToString();
}
private void AddPointsToOccupied(List<Point> points)
{
_occupiedPoints.AddRange(points);
_unoccupiedPoints.ExceptWith(points);
}
private void RemovePointsFromOccupied(List<Point> points)
{
_occupiedPoints.ExceptWith(points);
_unoccupiedPoints.AddRange(points);
}
// Node rooms are the rooms placed around each monster room and the boss room.
public List<Room> GetNodeRooms()
{
List<Room> nodeRooms = new List<Room>();
nodeRooms.AddRange(_monsterRooms.SelectMany(room => room.GetAdjacentRooms()));
nodeRooms.AddRange(_bossRoom.GetAdjacentRooms());
return nodeRooms;
}
public Dictionary<RoomSide, List<Room>> GetNodesWithSides()
{
Dictionary<RoomSide, List<Room>> nodesWithSides = new Dictionary<RoomSide, List<Room>>();
foreach (Room room in _monsterRooms)
{
foreach (var kvp in room.GetAdjacentRoomsDict())
{
if (!nodesWithSides.ContainsKey(kvp.Key))
{
nodesWithSides[kvp.Key] = new List<Room>(kvp.Value);
}
else
{
nodesWithSides[kvp.Key].AddRange(kvp.Value);
}
}
}
return nodesWithSides;
}
}
}