Fixed rooms being created where they would collide with an unavailable point on the map.
This commit is contained in:
parent
d091a7f745
commit
5f2be1333b
3 changed files with 36 additions and 31 deletions
|
|
@ -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(
|
|
||||||
RoomType.Monster,
|
|
||||||
SIDE_LENGTH_OF_MONSTER,
|
SIDE_LENGTH_OF_MONSTER,
|
||||||
SIDE_LENGTH_OF_MONSTER,
|
SIDE_LENGTH_OF_MONSTER,
|
||||||
newSpot));
|
RoomType.Monster));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue