Moved Dungeon Map Generator to it's own solution.

This commit is contained in:
Max 2025-02-10 15:43:13 +01:00
parent 5c46281334
commit fd2a28afe5
50 changed files with 86389 additions and 84 deletions

View file

@ -0,0 +1,13 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/contentModel.xml
/.idea.DungeonMapGenerator.iml
/projectSettingsUpdater.xml
/modules.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

View file

@ -0,0 +1,20 @@
// See https://aka.ms/new-console-template for more information
using DungeonMapGenerator;
class Program
{
static void Main(string[] args)
{
// Create an instance of your DungeonMapGenerator class
var generator = new DungeonGenerator();
generator.GenerateDungeon(25, .5f);
// Call the method you want to run
var map = generator.GenerateDungeon(25, .5f);
// Print the map to the console (assuming it returns a string or something printable)
Console.WriteLine(map.GetMapAsString());
Console.ReadLine();
}
}

View file

@ -0,0 +1,66 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v9.0",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v9.0": {
"DungeonMapConsolePrinter/1.0.0": {
"dependencies": {
"DungeonMapGenerator": "1.0.0"
},
"runtime": {
"DungeonMapConsolePrinter.dll": {}
}
},
"Newtonsoft.Json/13.0.3": {
"runtime": {
"lib/net6.0/Newtonsoft.Json.dll": {
"assemblyVersion": "13.0.0.0",
"fileVersion": "13.0.3.27908"
}
}
},
"System.Numerics.Vectors/4.6.0": {},
"DungeonMapGenerator/1.0.0": {
"dependencies": {
"Newtonsoft.Json": "13.0.3",
"System.Numerics.Vectors": "4.6.0"
},
"runtime": {
"DungeonMapGenerator.dll": {
"assemblyVersion": "1.0.0",
"fileVersion": "1.0.0.0"
}
}
}
}
},
"libraries": {
"DungeonMapConsolePrinter/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Newtonsoft.Json/13.0.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==",
"path": "newtonsoft.json/13.0.3",
"hashPath": "newtonsoft.json.13.0.3.nupkg.sha512"
},
"System.Numerics.Vectors/4.6.0": {
"type": "package",
"serviceable": true,
"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"
},
"DungeonMapGenerator/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

View file

@ -0,0 +1,12 @@
{
"runtimeOptions": {
"tfm": "net9.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "9.0.0"
},
"configProperties": {
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
}
}
}

View file

@ -0,0 +1,15 @@
using System.Collections.Generic;
namespace DungeonMapGenerator
{
public static class CollectionExtensions
{
public static void AddRange<T>(this ICollection<T> collection, IEnumerable<T> items)
{
foreach (var item in items)
{
collection.Add(item);
}
}
}
}

View file

@ -2,12 +2,9 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using Unity.VisualScripting;
using Unity.VisualScripting.Dependencies.NCalc;
using Random = System.Random;
namespace DungeonGenerator
namespace DungeonMapGenerator
{
public class DungeonGenerator
{
@ -119,14 +116,24 @@ namespace DungeonGenerator
// Randomly shuffle and take the required number of sides
foreach (RoomSide side in availableSides.OrderBy(_ => random.Next()).Take(numRoomsToAdd))
{
List<Point> unoccupiedPointsOnSide = side switch
List<Point> unoccupiedPointsOnSide;
switch (side)
{
RoomSide.Top => topUnoccupiedPoints,
RoomSide.Bottom => bottomUnoccupiedPoints,
RoomSide.Left => leftUnoccupiedPoints,
RoomSide.Right => rightUnoccupiedPoints,
_ => throw new ArgumentOutOfRangeException(nameof(side), $"Unexpected RoomSide value: {side}")
};
case RoomSide.Top:
unoccupiedPointsOnSide = topUnoccupiedPoints;
break;
case RoomSide.Bottom:
unoccupiedPointsOnSide = bottomUnoccupiedPoints;
break;
case RoomSide.Left:
unoccupiedPointsOnSide = leftUnoccupiedPoints;
break;
case RoomSide.Right:
unoccupiedPointsOnSide = rightUnoccupiedPoints;
break;
default:
throw new ArgumentOutOfRangeException(nameof(side), $"Unexpected RoomSide value: {side}");
}
// Create room and add it if valid
Room newRoom = CreateAdjacentRoom(RoomType.Normal, unoccupiedPointsOnSide, side, dungeon.GetOccupiedPoints());
@ -222,14 +229,25 @@ namespace DungeonGenerator
Point firstPoint = potentialPoints.First();
// Adjust the first point for different sides
Point adjustedPoint = side switch
Point adjustedPoint;
switch (side)
{
RoomSide.Top => new Point(firstPoint.X, firstPoint.Y), // Move up for top side
RoomSide.Bottom => new Point(firstPoint.X, firstPoint.Y - 1), // Move down for bottom side
RoomSide.Left => new Point(firstPoint.X, firstPoint.Y), // Move left for left side
RoomSide.Right => new Point(firstPoint.X - 1, firstPoint.Y), // Move right for right side
_ => firstPoint // Default case (shouldn't happen)
};
case RoomSide.Top:
adjustedPoint = new Point(firstPoint.X, firstPoint.Y); // Move up for top side
break;
case RoomSide.Bottom:
adjustedPoint = new Point(firstPoint.X, firstPoint.Y - 1); // Move down for bottom side
break;
case RoomSide.Left:
adjustedPoint = new Point(firstPoint.X, firstPoint.Y); // Move left for left side
break;
case RoomSide.Right:
adjustedPoint = new Point(firstPoint.X - 1, firstPoint.Y); // Move right for right side
break;
default:
adjustedPoint = firstPoint; // Default case (shouldn't happen)
break;
}
if (!potentialPoints.Any(occupiedPoints.Contains))
{
@ -321,7 +339,7 @@ namespace DungeonGenerator
const int numEntranceRooms = 12;
List<Room> entranceRooms = new List<Room>();
Random random = new Random();
Dictionary<Side, int> sidesToEnterOn = new()
Dictionary<Side, int> sidesToEnterOn = new Dictionary<Side, int>()
{
{ Side.Top, 0},
{ Side.Right, 0},
@ -457,17 +475,28 @@ namespace DungeonGenerator
List<Room> obstructions)
{
const float minClosestLength = 0;
Vector2 lookDirection = attachedSide switch
Vector2 lookDirection;
switch (attachedSide)
{
RoomSide.Top => new Vector2(0, -1), // Expanding upward
RoomSide.Bottom => new Vector2(0, 1), // Expanding downward
RoomSide.Left => new Vector2(-1, 0), // Expanding left
RoomSide.Right => new Vector2(1, 0), // Expanding right
_ => Vector2.Zero // Default (should not happen)
};
case RoomSide.Top:
lookDirection = new Vector2(0, -1); // Expanding upward
break;
case RoomSide.Bottom:
lookDirection = new Vector2(0, 1); // Expanding downward
break;
case RoomSide.Left:
lookDirection = new Vector2(-1, 0); // Expanding left
break;
case RoomSide.Right:
lookDirection = new Vector2(1, 0); // Expanding right
break;
default:
lookDirection = Vector2.Zero; // Default (should not happen)
break;
}
Point nodeCenter = nodeRoom.GetCenterOfRoom();
float visionConeAngle = MathF.PI / 4; // 45 degree cone in each side
Double visionConeAngle = Math.PI / 4; // 45 degree cone in each side
Room closestSeenRoom = null;
float closestDistance = float.MaxValue;
@ -486,7 +515,7 @@ namespace DungeonGenerator
toOther = Vector2.Normalize(toOther);
Vector2 lookNormalized = Vector2.Normalize(lookDirection);
float angle = MathF.Acos(Vector2.Dot(lookNormalized, toOther));
Double angle = Math.Acos(Vector2.Dot(lookNormalized, toOther));
if (angle <= visionConeAngle)
{

View file

@ -2,11 +2,8 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Unity.VisualScripting;
using UnityEngine;
namespace DungeonGenerator
namespace DungeonMapGenerator
{
public class DungeonMap
{
@ -103,7 +100,7 @@ namespace DungeonGenerator
return new HashSet<Point>(_occupiedPoints);
}
public void PrintMap()
public string GetMapAsString()
{
List<Point> monsterRoomPoints = _monsterRooms.SelectMany(room => room.GetPointsInRoom()).ToList();
List<Point> entranceRoomPoints = _entranceRooms.SelectMany(room => room.GetPointsInRoom()).ToList();
@ -147,11 +144,11 @@ namespace DungeonGenerator
sb.Append(Environment.NewLine);
}
Debug.Log($"{DateTime.Now}{Environment.NewLine}" +
return $"{DateTime.Now}{Environment.NewLine}" +
$"X Length: {_width}{Environment.NewLine}" +
$"Y Length: {_height}{Environment.NewLine}" +
$"Monster Rooms: {_monsterRooms.Count}{Environment.NewLine}" +
sb.ToString());
sb.ToString();
}
private void AddPointsToOccupied(List<Point> points)

View file

@ -0,0 +1,46 @@
using System;
using System.IO;
using Newtonsoft.Json;
namespace DungeonMapGenerator
{
public class DungeonMapSerializer
{
// Serialize DungeonMap to JSON file
public static void SerializeToFile(DungeonMap dungeonMap, string filePath)
{
try
{
// Convert DungeonMap object to JSON string
string json = JsonConvert.SerializeObject(dungeonMap, Formatting.Indented);
// Write JSON string to a file
File.WriteAllText(filePath, json);
}
catch (Exception ex)
{
Console.WriteLine($"Error during serialization: {ex.Message}");
}
}
// Deserialize DungeonMap from JSON file
public static DungeonMap DeserializeFromFile(string filePath)
{
try
{
// Read JSON string from file
string json = File.ReadAllText(filePath);
// Convert JSON string to DungeonMap object
DungeonMap dungeonMap = JsonConvert.DeserializeObject<DungeonMap>(json);
return dungeonMap;
}
catch (Exception ex)
{
Console.WriteLine($"Error during deserialization: {ex.Message}");
return null;
}
}
}
}

View file

@ -1,10 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.UIElements;
using Random = System.Random;
namespace DungeonGenerator
namespace DungeonMapGenerator
{
public class EvenDisperser
{

View file

@ -1,6 +1,6 @@
using System;
namespace DungeonGenerator
namespace DungeonMapGenerator
{
public struct Point
{
@ -13,7 +13,7 @@ namespace DungeonGenerator
}
public override bool Equals(object obj) => obj is Point p && X == p.X && Y == p.Y;
public override int GetHashCode() => HashCode.Combine(X, Y);
public override int GetHashCode() => (X, Y).GetHashCode();
public override string ToString() => $"({X}, {Y})";

View file

@ -1,10 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using Unity.VisualScripting;
namespace DungeonGenerator
namespace DungeonMapGenerator
{
public enum RoomSide
{
@ -31,7 +29,7 @@ namespace DungeonGenerator
PositionOfTopLeft = positionOfTopLeft;
}
private readonly Dictionary<RoomSide, List<Room>> _adjacentRooms = new();
private readonly Dictionary<RoomSide, List<Room>> _adjacentRooms = new Dictionary<RoomSide, List<Room>>();
public RoomType TypeOfRoom { get; set; }
public int Height { get; set; }
@ -95,13 +93,21 @@ namespace DungeonGenerator
}
// Helper method to get the opposite side
private RoomSide GetOppositeSide(RoomSide side) => side switch
private RoomSide GetOppositeSide(RoomSide side)
{
RoomSide.Top => RoomSide.Bottom,
RoomSide.Bottom => RoomSide.Top,
RoomSide.Left => RoomSide.Right,
RoomSide.Right => RoomSide.Left,
_ => throw new ArgumentException("Invalid RoomSide", nameof(side))
};
switch (side)
{
case RoomSide.Top:
return RoomSide.Bottom;
case RoomSide.Bottom:
return RoomSide.Top;
case RoomSide.Left:
return RoomSide.Right;
case RoomSide.Right:
return RoomSide.Left;
default:
throw new ArgumentException("Invalid RoomSide", nameof(side));
}
}
}
}

View file

@ -0,0 +1,79 @@
{
"runtimeTarget": {
"name": ".NETStandard,Version=v2.0/",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETStandard,Version=v2.0": {},
".NETStandard,Version=v2.0/": {
"DungeonMapGenerator/1.0.0": {
"dependencies": {
"NETStandard.Library": "2.0.3",
"Newtonsoft.Json": "13.0.3",
"System.Numerics.Vectors": "4.6.0"
},
"runtime": {
"DungeonMapGenerator.dll": {}
}
},
"Microsoft.NETCore.Platforms/1.1.0": {},
"NETStandard.Library/2.0.3": {
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0"
}
},
"Newtonsoft.Json/13.0.3": {
"runtime": {
"lib/netstandard2.0/Newtonsoft.Json.dll": {
"assemblyVersion": "13.0.0.0",
"fileVersion": "13.0.3.27908"
}
}
},
"System.Numerics.Vectors/4.6.0": {
"runtime": {
"lib/netstandard2.0/System.Numerics.Vectors.dll": {
"assemblyVersion": "4.1.3.0",
"fileVersion": "4.600.24.56208"
}
}
}
}
},
"libraries": {
"DungeonMapGenerator/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Microsoft.NETCore.Platforms/1.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==",
"path": "microsoft.netcore.platforms/1.1.0",
"hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512"
},
"NETStandard.Library/2.0.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
"path": "netstandard.library/2.0.3",
"hashPath": "netstandard.library.2.0.3.nupkg.sha512"
},
"Newtonsoft.Json/13.0.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==",
"path": "newtonsoft.json/13.0.3",
"hashPath": "newtonsoft.json.13.0.3.nupkg.sha512"
},
"System.Numerics.Vectors/4.6.0": {
"type": "package",
"serviceable": true,
"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"
}
}
}

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?><configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="mscorlib" publicKeyToken="b77a5c561934e089" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="netstandard" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System" publicKeyToken="b77a5c561934e089" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View file

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: b2976da120e9418ab6437c973c915dd7
timeCreated: 1738336012

View file

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: e9db8a8571ad45d9a8d7c8d22ebe0d05
timeCreated: 1738336090

View file

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: b8c880c12ad649f8a395e6367a9c8838
timeCreated: 1738774051

View file

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 3ce67840c99f4761af7805355099b495
timeCreated: 1738577856

View file

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 5c2b1ba54c4043b19dd204ab61f465c3
timeCreated: 1738579679

View file

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 2dd79ebcc11d4938a8d116e711842b89
timeCreated: 1738337240

View file

@ -1,13 +0,0 @@
using DungeonGenerator;
using UnityEngine;
public class TestRun : MonoBehaviour
{
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
DungeonGenerator.DungeonGenerator gen = new DungeonGenerator.DungeonGenerator();
DungeonMap dungeon = gen.GenerateDungeon(0 , 0.5f);
dungeon.PrintMap();
}
}

View file

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 05a951debbad424aada4449064592d39

Binary file not shown.

View file

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2007 James Newton-King
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1,71 @@
# ![Logo](https://raw.githubusercontent.com/JamesNK/Newtonsoft.Json/master/Doc/icons/logo.jpg) Json.NET
[![NuGet version (Newtonsoft.Json)](https://img.shields.io/nuget/v/Newtonsoft.Json.svg?style=flat-square)](https://www.nuget.org/packages/Newtonsoft.Json/)
[![Build status](https://dev.azure.com/jamesnk/Public/_apis/build/status/JamesNK.Newtonsoft.Json?branchName=master)](https://dev.azure.com/jamesnk/Public/_build/latest?definitionId=8)
Json.NET is a popular high-performance JSON framework for .NET
## Serialize JSON
```csharp
Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Sizes = new string[] { "Small" };
string json = JsonConvert.SerializeObject(product);
// {
// "Name": "Apple",
// "Expiry": "2008-12-28T00:00:00",
// "Sizes": [
// "Small"
// ]
// }
```
## Deserialize JSON
```csharp
string json = @"{
'Name': 'Bad Boys',
'ReleaseDate': '1995-4-7T00:00:00',
'Genres': [
'Action',
'Comedy'
]
}";
Movie m = JsonConvert.DeserializeObject<Movie>(json);
string name = m.Name;
// Bad Boys
```
## LINQ to JSON
```csharp
JArray array = new JArray();
array.Add("Manual text");
array.Add(new DateTime(2000, 5, 23));
JObject o = new JObject();
o["MyArray"] = array;
string json = o.ToString();
// {
// "MyArray": [
// "Manual text",
// "2000-05-23T00:00:00"
// ]
// }
```
## Links
- [Homepage](https://www.newtonsoft.com/json)
- [Documentation](https://www.newtonsoft.com/json/help)
- [NuGet Package](https://www.nuget.org/packages/Newtonsoft.Json)
- [Release Notes](https://github.com/JamesNK/Newtonsoft.Json/releases)
- [Contributing Guidelines](https://github.com/JamesNK/Newtonsoft.Json/blob/master/CONTRIBUTING.md)
- [License](https://github.com/JamesNK/Newtonsoft.Json/blob/master/LICENSE.md)
- [Stack Overflow](https://stackoverflow.com/questions/tagged/json.net)

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net471" />
</packages>