Fixed rooms being created where they would collide with an unavailable point on the map.

This commit is contained in:
Max 2025-02-05 15:49:10 +01:00
parent d091a7f745
commit 5f2be1333b
3 changed files with 36 additions and 31 deletions

View file

@ -29,14 +29,13 @@ namespace DungeonGenerator
EvenDisperser disperser = new EvenDisperser(_xLength, _yLength, _entrancePoints); //TODO calculate L and W from length EvenDisperser disperser = new EvenDisperser(_xLength, _yLength, _entrancePoints); //TODO calculate L and W from length
int numberOfMonsterRooms = 7; // TODO: Calculate from ratio int numberOfMonsterRooms = 7; // TODO: Calculate from ratio
for (var i = 0; i < numberOfMonsterRooms; i ++) for (var i = 0; i < numberOfMonsterRooms; i ++)
{ {
Point newSpot = disperser.GetPoint(SIDE_LENGTH_OF_MONSTER, SIDE_LENGTH_OF_MONSTER); _monsterRooms.Add(disperser.GenerateAndPlaceRoom(
_monsterRooms.Add(new Room( SIDE_LENGTH_OF_MONSTER,
RoomType.Monster,
SIDE_LENGTH_OF_MONSTER, SIDE_LENGTH_OF_MONSTER,
SIDE_LENGTH_OF_MONSTER, RoomType.Monster));
newSpot));
} }
} }

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using UnityEngine.UIElements; using UnityEngine.UIElements;
using Random = System.Random; using Random = System.Random;
@ -7,17 +8,21 @@ namespace DungeonGenerator
{ {
public class EvenDisperser public class EvenDisperser
{ {
private List<Point> _samples = new List<Point>(){new Point(1,1)}; private List<Room> _samples = new List<Room>(){new Room(
private List<Point> _availablePoints; RoomType.Normal,
1,
1,
new Point(1000, 1000))};
private HashSet<Point> _availablePoints;
public EvenDisperser(int xLength, int yLength, List<Point> excludedPoints = null) public EvenDisperser(int xLength, int yLength, List<Point> excludedPoints = null)
{ {
_availablePoints = GenerateAvailablePoints(xLength, yLength, excludedPoints ?? new List<Point>()); _availablePoints = GenerateAvailablePoints(xLength, yLength, excludedPoints ?? new List<Point>());
} }
private List<Point> GenerateAvailablePoints(int xLength, int yLength, List<Point> excludedPoints) private HashSet<Point> GenerateAvailablePoints(int xLength, int yLength, List<Point> excludedPoints)
{ {
List<Point> availablePoints = new List<Point>(); HashSet<Point> availablePoints = new HashSet<Point>();
for (var x = 0; x < xLength; x++) for (var x = 0; x < xLength; x++)
{ {
for (var y = 0; y < yLength; y++) for (var y = 0; y < yLength; y++)
@ -32,21 +37,21 @@ namespace DungeonGenerator
return availablePoints; return availablePoints;
} }
// Can place point so that the x lengt hand y length go out of bounds to the right and down. public Room GenerateAndPlaceRoom(int xLength, int yLength, RoomType roomType)
public Point GetPoint(int xLength, int yLength)
{ {
int numCandidates = 100; // Increasing improves results but greatly effects performance. int numCandidates = 100; // Increasing improves results but greatly effects performance.
Random rnd = new Random(); Random rnd = new Random();
int randomIndex = rnd.Next(0, _availablePoints.Count); Room bestCandidate = new Room(roomType, xLength, yLength, new Point(Int32.MaxValue, Int32.MaxValue));
Point bestCandidate = new Point(Int32.MaxValue, Int32.MaxValue);
int bestDistance = 0; int bestDistance = 0;
for (var i = 0; i < numCandidates; i++) for (var i = 0; i < numCandidates; i++)
{ {
var candidate = _availablePoints[randomIndex]; var candidate = new Room(
var distance = candidate.ManhattanDistance(FindClosest(_samples, candidate)); roomType, xLength, yLength, _availablePoints.ToList()[rnd.Next(0, _availablePoints.Count)]);
if (distance > bestDistance) var distance = candidate.GetDistanceToRoom(FindClosestRoom(_samples, candidate));
if (distance > bestDistance
&& candidate.GetPointsInRoom().All(room => _availablePoints.Contains(room)))
{ {
RemoveArea(candidate, xLength, yLength, _availablePoints); _availablePoints.ExceptWith(candidate.GetPointsInRoom());
bestCandidate = candidate; bestCandidate = candidate;
bestDistance = distance; bestDistance = distance;
} }
@ -56,12 +61,12 @@ namespace DungeonGenerator
return bestCandidate; return bestCandidate;
} }
private Point FindClosest(List<Point> options, Point reference) private Room FindClosestRoom(List<Room> options, Room reference)
{ {
Point closest = options[0]; Room closest = options[0];
foreach (var option in options) foreach (var option in options)
{ {
if (reference.ManhattanDistance(option) < reference.ManhattanDistance(closest)) if (reference.GetDistanceToRoom(option) < reference.GetDistanceToRoom(closest))
{ {
closest = option; closest = option;
} }
@ -69,16 +74,5 @@ namespace DungeonGenerator
return closest; return closest;
} }
private void RemoveArea(Point topLeft, int xLength, int yLength, List<Point> availablePoints)
{
for (var x = topLeft.X; x < topLeft.X + xLength; x++)
{
for (var y = topLeft.Y; y < topLeft.Y + yLength; y++)
{
availablePoints.Remove(new Point(x, y));
}
}
}
} }
} }

View file

@ -37,5 +37,17 @@ namespace DungeonGenerator
return points; return points;
} }
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);
}
} }
} }