78 lines
No EOL
2.7 KiB
C#
78 lines
No EOL
2.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine.UIElements;
|
|
using Random = System.Random;
|
|
|
|
namespace DungeonGenerator
|
|
{
|
|
public class EvenDisperser
|
|
{
|
|
private List<Room> _samples = new List<Room>(){new Room(
|
|
RoomType.Normal,
|
|
1,
|
|
1,
|
|
new Point(1000, 1000))};
|
|
private HashSet<Point> _availablePoints;
|
|
|
|
public EvenDisperser(int xLength, int yLength, HashSet<Point> availablePoints)
|
|
{
|
|
_availablePoints = availablePoints;
|
|
}
|
|
|
|
private HashSet<Point> GenerateAvailablePoints(int xLength, int yLength, List<Point> excludedPoints)
|
|
{
|
|
HashSet<Point> availablePoints = new HashSet<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;
|
|
}
|
|
|
|
public Room GenerateAndPlaceRoom(int xLength, int yLength, RoomType roomType)
|
|
{
|
|
int numCandidates = 100; // Increasing improves results but greatly effects performance.
|
|
Random rnd = new Random();
|
|
Room bestCandidate = new Room(roomType, xLength, yLength, new Point(Int32.MaxValue, Int32.MaxValue));
|
|
int bestDistance = 0;
|
|
for (var i = 0; i < numCandidates; i++)
|
|
{
|
|
var candidate = new Room(
|
|
roomType, xLength, yLength, _availablePoints.ToList()[rnd.Next(0, _availablePoints.Count)]);
|
|
var distance = candidate.GetDistanceToRoom(FindClosestRoom(_samples, candidate));
|
|
if (distance > bestDistance
|
|
&& candidate.GetPointsInRoom().All(room => _availablePoints.Contains(room)))
|
|
{
|
|
_availablePoints.ExceptWith(candidate.GetPointsInRoom());
|
|
bestCandidate = candidate;
|
|
bestDistance = distance;
|
|
}
|
|
}
|
|
|
|
_samples.Add(bestCandidate);
|
|
return bestCandidate;
|
|
}
|
|
|
|
private Room FindClosestRoom(List<Room> options, Room reference)
|
|
{
|
|
Room closest = options[0];
|
|
foreach (var option in options)
|
|
{
|
|
if (reference.GetDistanceToRoom(option) < reference.GetDistanceToRoom(closest))
|
|
{
|
|
closest = option;
|
|
}
|
|
}
|
|
|
|
return closest;
|
|
}
|
|
}
|
|
} |