Implemented randomly dispersing monster rooms.
This commit is contained in:
parent
5895a9f878
commit
9c02b11299
12 changed files with 394 additions and 0 deletions
|
|
@ -0,0 +1,84 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.UIElements;
|
||||
using Random = System.Random;
|
||||
|
||||
namespace DungeonGenerator
|
||||
{
|
||||
public class EvenDisperser
|
||||
{
|
||||
private List<Point> _samples = new List<Point>(){new Point(1,1)};
|
||||
private List<Point> _availablePoints;
|
||||
|
||||
public EvenDisperser(int xLength, int yLength, List<Point> excludedPoints = null)
|
||||
{
|
||||
_availablePoints = GenerateAvailablePoints(xLength, yLength, excludedPoints ?? new List<Point>());
|
||||
}
|
||||
|
||||
private List<Point> GenerateAvailablePoints(int xLength, int yLength, List<Point> excludedPoints)
|
||||
{
|
||||
List<Point> availablePoints = new List<Point>();
|
||||
for (var x = 0; x < xLength; x++)
|
||||
{
|
||||
for (var y = 0; y < yLength; y++)
|
||||
{
|
||||
if (!excludedPoints.Contains(new Point(x, y)))
|
||||
{
|
||||
availablePoints.Add(new Point(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return availablePoints;
|
||||
}
|
||||
|
||||
// Can place point so that the x lengt hand y length go out of bounds to the right and down.
|
||||
public Point GetPoint(int xLength, int yLength)
|
||||
{
|
||||
int numCandidates = 50; // Increasing improves results but greatly effects performance.
|
||||
Random rnd = new Random();
|
||||
int randomIndex = rnd.Next(_availablePoints.Count);
|
||||
Point bestCandidate = new Point(Int32.MaxValue, Int32.MaxValue);
|
||||
int bestDistance = 0;
|
||||
for (var i = 0; i < numCandidates; i++)
|
||||
{
|
||||
var candidate = _availablePoints[randomIndex];
|
||||
var distance = candidate.ManhattanDistance(FindClosest(_samples, candidate));
|
||||
if (distance > bestDistance)
|
||||
{
|
||||
RemoveArea(candidate, xLength, yLength, _availablePoints);
|
||||
bestCandidate = candidate;
|
||||
bestDistance = distance;
|
||||
}
|
||||
}
|
||||
|
||||
_samples.Add(bestCandidate);
|
||||
return bestCandidate;
|
||||
}
|
||||
|
||||
private Point FindClosest(List<Point> options, Point reference)
|
||||
{
|
||||
Point closest = options[0];
|
||||
foreach (var option in options)
|
||||
{
|
||||
if (reference.ManhattanDistance(option) < reference.ManhattanDistance(closest))
|
||||
{
|
||||
closest = option;
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue