UNFINISHED Implemented procedural dice generation. Way too hard
This commit is contained in:
parent
ea1ca7a0cd
commit
03f0f7859e
43 changed files with 13909 additions and 57 deletions
|
|
@ -15,6 +15,7 @@ class Program
|
|||
|
||||
// Call the method you want to run
|
||||
DungeonMap map = generator.GenerateDungeon(25, .5f);
|
||||
DungeonLockPopulator.PopulateLocksOfDungeon(map);
|
||||
DungeonMapSerializer.SerializeToFile(map, SAVED_DUNGEONS_PATH, DUNGEON_NAME );
|
||||
|
||||
// Print the map to the console (assuming it returns a string or something printable)
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -23,8 +23,17 @@
|
|||
}
|
||||
},
|
||||
"System.Numerics.Vectors/4.6.0": {},
|
||||
"DiceProbabilities/1.0.0": {
|
||||
"runtime": {
|
||||
"DiceProbabilities.dll": {
|
||||
"assemblyVersion": "1.0.0",
|
||||
"fileVersion": "1.0.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"DungeonMapGenerator/1.0.0": {
|
||||
"dependencies": {
|
||||
"DiceProbabilities": "1.0.0",
|
||||
"Newtonsoft.Json": "13.0.3",
|
||||
"System.Numerics.Vectors": "4.6.0"
|
||||
},
|
||||
|
|
@ -57,6 +66,11 @@
|
|||
"path": "system.numerics.vectors/4.6.0",
|
||||
"hashPath": "system.numerics.vectors.4.6.0.nupkg.sha512"
|
||||
},
|
||||
"DiceProbabilities/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"DungeonMapGenerator/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -49,15 +49,14 @@ namespace DungeonMapGenerator
|
|||
|
||||
private void ConnectAllAdjacentRooms(DungeonMap dungeon)
|
||||
{
|
||||
Dictionary<Point, int> pointRoomMapping = dungeon.GetPointRoomIdMapping();
|
||||
Dictionary<Point, Room> pointRoomMapping = dungeon.GetPointRoomIdMapping();
|
||||
foreach (var room in dungeon.GetAllRooms())
|
||||
{
|
||||
foreach ((Point p, RoomSide side) in room.GetAdjacentPoints())
|
||||
{
|
||||
if (pointRoomMapping.ContainsKey(p))
|
||||
{
|
||||
int idForRoomPointIsIn = pointRoomMapping[p];
|
||||
room.AddAdjacentRoomId(idForRoomPointIsIn);
|
||||
room.AddAdjacentRoom(pointRoomMapping[p]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
130
DungeonMapGenerator/DungeonMapGenerator/DungeonLockPopulator.cs
Normal file
130
DungeonMapGenerator/DungeonMapGenerator/DungeonLockPopulator.cs
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using DiceProbabilities;
|
||||
|
||||
namespace DungeonMapGenerator
|
||||
{
|
||||
public static class DungeonLockPopulator
|
||||
{
|
||||
private const float ACCEPTABLE_ERROR = .1319f;
|
||||
public static void PopulateLocksOfDungeon(DungeonMap dungeon)
|
||||
{
|
||||
Random random = new Random();
|
||||
float desiredSuccessChance = .80f;
|
||||
|
||||
List<Room> currentRooms = dungeon.GetEntranceRooms();
|
||||
HashSet<Room> seenRooms = new HashSet<Room>(currentRooms);
|
||||
|
||||
// Set entrance room locks to 2 - 12
|
||||
Shuffle(currentRooms);
|
||||
int entranceRoomLock = 1;
|
||||
foreach (Room entranceRoom in currentRooms)
|
||||
{
|
||||
entranceRoom.Lock = new Lock((entranceRoomLock + 1.ToString()));
|
||||
}
|
||||
|
||||
while (currentRooms.Count > 0)
|
||||
{
|
||||
List<Room> locklessRooms = new List<Room>();
|
||||
List<Room> adjacentRooms = new List<Room>();
|
||||
|
||||
// Get all adjacent rooms that haven't been locked at
|
||||
foreach (Room room in currentRooms.ToList())
|
||||
{
|
||||
foreach (Room adjacentRoom in room.GetAdjacentRooms())
|
||||
{
|
||||
if (!seenRooms.Contains(adjacentRoom))
|
||||
{
|
||||
adjacentRooms.Add(adjacentRoom);
|
||||
seenRooms.Add(adjacentRoom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the odds of locks already set.
|
||||
foreach (Room adjacentRoom in adjacentRooms.ToList())
|
||||
{
|
||||
List<float> odds = new List<float>();
|
||||
if (adjacentRoom.Lock != null)
|
||||
{
|
||||
odds.Add(adjacentRoom.Lock.GetOdds());
|
||||
}
|
||||
else
|
||||
{
|
||||
locklessRooms.Add(adjacentRoom);
|
||||
}
|
||||
}
|
||||
|
||||
if (locklessRooms.Count > 0)
|
||||
{
|
||||
// Add locks to the rooms with odds adding to within the difficulty range
|
||||
List<Lock> locks = GenerateLocks(locklessRooms.Count, desiredSuccessChance);
|
||||
for (int i = 0; i < locklessRooms.Count; i++)
|
||||
{
|
||||
locklessRooms[i].Lock = locks[i];
|
||||
}
|
||||
}
|
||||
|
||||
currentRooms = adjacentRooms;
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Lock> GenerateLocks(int numLocks, float successChance)
|
||||
{
|
||||
List<Lock> locks = new List<Lock>();
|
||||
if (FindCombination(locks, numLocks, successChance, Lock.PossibleLocks))
|
||||
{
|
||||
return locks;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static bool FindCombination(List<Lock> generatedLocks, int numLocks, float successChance, List<Lock> lockOptions)
|
||||
{
|
||||
if (generatedLocks.Count == numLocks)
|
||||
{
|
||||
List<string> locksAsStrings = generatedLocks.Select(_lock => _lock.GetLock()).ToList();
|
||||
|
||||
// Return true if given the current locks the chance of being able to open one is close to difficulty
|
||||
float probalityOfAtleastOneUnlocking = RollFourSumTwo.GetProbalityOfAtleastOneUnlocking(locksAsStrings);
|
||||
return probalityOfAtleastOneUnlocking >= successChance - ACCEPTABLE_ERROR
|
||||
&& probalityOfAtleastOneUnlocking <= successChance + ACCEPTABLE_ERROR;
|
||||
}
|
||||
|
||||
Shuffle(lockOptions);
|
||||
|
||||
foreach (Lock _lock in lockOptions.ToList())
|
||||
{
|
||||
// if adding the lock won't bring us over the threshold difficulty.
|
||||
List<string> locksAsStrings = generatedLocks.Select(l => l.GetLock()).ToList();
|
||||
locksAsStrings.Add(_lock.GetLock());
|
||||
if (RollFourSumTwo.GetProbalityOfAtleastOneUnlocking(locksAsStrings) <= successChance)
|
||||
{
|
||||
generatedLocks.Add(new Lock(_lock.GetLock()));
|
||||
if (FindCombination(generatedLocks, numLocks, successChance, lockOptions))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// This combination didn't work. Remove the last one and try the next lock.
|
||||
generatedLocks.RemoveAt(generatedLocks.Count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void Shuffle<T>(List<T> list)
|
||||
{
|
||||
Random random = new Random();
|
||||
|
||||
int n = list.Count;
|
||||
for (int i = n - 1; i > 0; i--)
|
||||
{
|
||||
int j = random.Next(i + 1);
|
||||
(list[i], list[j]) = (list[j], list[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -33,15 +33,15 @@ namespace DungeonMapGenerator
|
|||
.Select(y => new Point(x,y))));
|
||||
}
|
||||
|
||||
public Dictionary<Point, int> GetPointRoomIdMapping()
|
||||
public Dictionary<Point, Room> GetPointRoomIdMapping()
|
||||
{
|
||||
var pointRoomMap = new Dictionary<Point, int>();
|
||||
var pointRoomMap = new Dictionary<Point, Room>();
|
||||
|
||||
foreach (var room in GetAllRooms())
|
||||
{
|
||||
foreach (var point in room.GetPointsInRoom())
|
||||
{
|
||||
pointRoomMap[point] = room.Id;
|
||||
pointRoomMap[point] = room;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -200,8 +200,8 @@ namespace DungeonMapGenerator
|
|||
public List<Room> GetNodeRooms()
|
||||
{
|
||||
List<Room> nodeRooms = new List<Room>();
|
||||
nodeRooms.AddRange(_monsterRooms.SelectMany(room => room.GetAdjacentRooms()));
|
||||
nodeRooms.AddRange(_bossRoom.GetAdjacentRooms());
|
||||
nodeRooms.AddRange(_monsterRooms.SelectMany(room => room.GetAdjacentRoomsDict().Values.SelectMany(roomList => roomList)));
|
||||
nodeRooms.AddRange(_bossRoom.GetAdjacentRoomsDict().Values.SelectMany(roomList => roomList));
|
||||
return nodeRooms;
|
||||
}
|
||||
|
||||
|
|
|
|||
53
DungeonMapGenerator/DungeonMapGenerator/Lock.cs
Normal file
53
DungeonMapGenerator/DungeonMapGenerator/Lock.cs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
using System.Collections.Generic;
|
||||
using DiceProbabilities;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DungeonMapGenerator
|
||||
{
|
||||
public class Lock
|
||||
{
|
||||
public static readonly List<Lock> PossibleLocks = new List<Lock>()
|
||||
{
|
||||
new Lock("="),
|
||||
new Lock("2"),
|
||||
new Lock("3"),
|
||||
new Lock("4"),
|
||||
new Lock("5"),
|
||||
new Lock("6"),
|
||||
new Lock("7"),
|
||||
new Lock("8"),
|
||||
new Lock("9"),
|
||||
new Lock("10"),
|
||||
new Lock("11"),
|
||||
new Lock("12"),
|
||||
};
|
||||
|
||||
[JsonProperty("LockType")]
|
||||
private string _lockType;
|
||||
|
||||
public Lock()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Lock(string lockType)
|
||||
{
|
||||
_lockType = lockType;
|
||||
}
|
||||
|
||||
public void SetLockType(string lockType)
|
||||
{
|
||||
_lockType = lockType;
|
||||
}
|
||||
|
||||
public string GetLock()
|
||||
{
|
||||
return _lockType;
|
||||
}
|
||||
|
||||
public float GetOdds()
|
||||
{
|
||||
return RollFourSumTwo.ResultOddsmapping[_lockType];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ namespace DungeonMapGenerator
|
|||
private static int _nextId = 1;
|
||||
|
||||
public RoomType TypeOfRoom { get; set; }
|
||||
public Lock Lock { get; set; }
|
||||
public int Height { get; set; }
|
||||
public int Width { get; set; }
|
||||
public Point PositionOfTopLeft { get; set; }
|
||||
|
|
@ -34,8 +35,9 @@ namespace DungeonMapGenerator
|
|||
|
||||
[JsonProperty("AdjacentRoomIds")]
|
||||
private HashSet<int> _adjacentRoomIds = new HashSet<int>();
|
||||
private List<Room> _adjacentRooms = new List<Room>();
|
||||
private readonly Dictionary<RoomSide, List<Room>> _adjacentRoomsBySide = new Dictionary<RoomSide, List<Room>>();
|
||||
|
||||
|
||||
public Room()
|
||||
{
|
||||
|
||||
|
|
@ -50,10 +52,12 @@ namespace DungeonMapGenerator
|
|||
PositionOfTopLeft = positionOfTopLeft;
|
||||
}
|
||||
|
||||
public void AddAdjacentRoomId(int id)
|
||||
public void AddAdjacentRoom(Room room)
|
||||
{
|
||||
_adjacentRoomIds.Add(id);
|
||||
_adjacentRooms.Add(room);
|
||||
_adjacentRoomIds.Add(room.Id);
|
||||
}
|
||||
|
||||
|
||||
public HashSet<int> GetAdjacentRoomIds()
|
||||
{
|
||||
|
|
@ -108,7 +112,7 @@ namespace DungeonMapGenerator
|
|||
|
||||
public IEnumerable<Room> GetAdjacentRooms()
|
||||
{
|
||||
return _adjacentRoomsBySide.Values.SelectMany(roomList => roomList);
|
||||
return new List<Room>(_adjacentRooms);
|
||||
}
|
||||
|
||||
public Dictionary<RoomSide, List<Room>> GetAdjacentRoomsDict()
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -9,6 +9,7 @@
|
|||
".NETStandard,Version=v2.0/": {
|
||||
"DungeonMapGenerator/1.0.0": {
|
||||
"dependencies": {
|
||||
"DiceProbabilities": "1.0.0",
|
||||
"NETStandard.Library": "2.0.3",
|
||||
"Newtonsoft.Json": "13.0.3",
|
||||
"System.Numerics.Vectors": "4.6.0"
|
||||
|
|
@ -38,6 +39,14 @@
|
|||
"fileVersion": "4.600.24.56208"
|
||||
}
|
||||
}
|
||||
},
|
||||
"DiceProbabilities/1.0.0": {
|
||||
"runtime": {
|
||||
"DiceProbabilities.dll": {
|
||||
"assemblyVersion": "1.0.0",
|
||||
"fileVersion": "1.0.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -74,6 +83,11 @@
|
|||
"sha512": "sha512-t+SoieZsRuEyiw/J+qXUbolyO219tKQQI0+2/YI+Qv7YdGValA6WiuokrNKqjrTNsy5ABWU11bdKOzUdheteXg==",
|
||||
"path": "system.numerics.vectors/4.6.0",
|
||||
"hashPath": "system.numerics.vectors.4.6.0.nupkg.sha512"
|
||||
},
|
||||
"DiceProbabilities/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue