From 30b115ab2af0ad118dab14ee64f666fe157b139e Mon Sep 17 00:00:00 2001 From: Xevion Date: Wed, 11 Nov 2020 18:26:35 -0600 Subject: [PATCH] begin working on new level/cave generation abilities, RandomPlacement & DrunkardWalk --- Paths/Assets/Scripts/Algorithms/NodeGrid.cs | 32 +++++++++++++- Paths/Assets/Scripts/ILevelGenerator.cs | 5 +++ Paths/Assets/Scripts/ILevelGenerator.cs.meta | 3 ++ .../{Pathfinding.cs => IPathfinding.cs} | 0 ...thfinding.cs.meta => IPathfinding.cs.meta} | 0 Paths/Assets/Scripts/LevelGeneration.meta | 3 ++ .../Scripts/LevelGeneration/DrunkardWalk.cs | 42 ++++++++++++++++++ .../LevelGeneration/DrunkardWalk.cs.meta | 3 ++ .../LevelGeneration/RandomPlacement.cs | 43 +++++++++++++++++++ .../LevelGeneration/RandomPlacement.cs.meta | 3 ++ Paths/Assets/Scripts/Manager.cs | 2 + Paths/Assets/Scripts/PathfindingAlgorithms.cs | 6 --- .../Scripts/PathfindingAlgorithms.cs.meta | 3 -- 13 files changed, 135 insertions(+), 10 deletions(-) create mode 100644 Paths/Assets/Scripts/ILevelGenerator.cs create mode 100644 Paths/Assets/Scripts/ILevelGenerator.cs.meta rename Paths/Assets/Scripts/{Pathfinding.cs => IPathfinding.cs} (100%) rename Paths/Assets/Scripts/{Pathfinding.cs.meta => IPathfinding.cs.meta} (100%) create mode 100644 Paths/Assets/Scripts/LevelGeneration.meta create mode 100644 Paths/Assets/Scripts/LevelGeneration/DrunkardWalk.cs create mode 100644 Paths/Assets/Scripts/LevelGeneration/DrunkardWalk.cs.meta create mode 100644 Paths/Assets/Scripts/LevelGeneration/RandomPlacement.cs create mode 100644 Paths/Assets/Scripts/LevelGeneration/RandomPlacement.cs.meta delete mode 100644 Paths/Assets/Scripts/PathfindingAlgorithms.cs delete mode 100644 Paths/Assets/Scripts/PathfindingAlgorithms.cs.meta diff --git a/Paths/Assets/Scripts/Algorithms/NodeGrid.cs b/Paths/Assets/Scripts/Algorithms/NodeGrid.cs index 98b0788..54d67a4 100644 --- a/Paths/Assets/Scripts/Algorithms/NodeGrid.cs +++ b/Paths/Assets/Scripts/Algorithms/NodeGrid.cs @@ -9,6 +9,7 @@ namespace Algorithms { private List> grid; public readonly int Width; public readonly int Height; + public int CellCount => this.Width * this.Height; public NodeGrid(int width, int height) { if (width <= 0) @@ -52,7 +53,7 @@ namespace Algorithms { return temp; } - + public bool IsValid(int x, int y) { return x > 0 && x < Width && y > 0 && y < Height; } @@ -105,5 +106,34 @@ namespace Algorithms { public Vector2Int RandomPosition() { return new Vector2Int(Random.Range(0, Width - 1), Random.Range(0, Height - 1)); } + + /// + /// Applies a ILevelGenerators's generate function to a NodeGrid + /// + /// A instantiated level generator (ILevelGenerator) object + public void ApplyGenerator(ILevelGenerator generator) { + } + + public IEnumerable Iterator() { + for (int x = 0; x < this.grid.Count; x++) + for (int y = 0; y < this.grid[0].Count; y++) + yield return this.grid[x][y]; + } + + public IEnumerable Walls() { + return this.Iterator().Where(node => !node.Walkable); + } + + public IEnumerable Empty() { + return this.Iterator().Where(node => node.Walkable); + } + + /// + /// Returns a random valid node on the grid. + /// + /// A Node object. + public Node GetRandomNode() { + return grid[Random.Range(0, Width - 1)][Random.Range(0, Height - 1)]; + } } } \ No newline at end of file diff --git a/Paths/Assets/Scripts/ILevelGenerator.cs b/Paths/Assets/Scripts/ILevelGenerator.cs new file mode 100644 index 0000000..e0d4fe5 --- /dev/null +++ b/Paths/Assets/Scripts/ILevelGenerator.cs @@ -0,0 +1,5 @@ +using Algorithms; + +public interface ILevelGenerator { + NodeGrid Generate(NodeGrid nodeGrid); +} \ No newline at end of file diff --git a/Paths/Assets/Scripts/ILevelGenerator.cs.meta b/Paths/Assets/Scripts/ILevelGenerator.cs.meta new file mode 100644 index 0000000..ed7bc68 --- /dev/null +++ b/Paths/Assets/Scripts/ILevelGenerator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 24f2296f0d384c598d2637daf13df886 +timeCreated: 1605297076 \ No newline at end of file diff --git a/Paths/Assets/Scripts/Pathfinding.cs b/Paths/Assets/Scripts/IPathfinding.cs similarity index 100% rename from Paths/Assets/Scripts/Pathfinding.cs rename to Paths/Assets/Scripts/IPathfinding.cs diff --git a/Paths/Assets/Scripts/Pathfinding.cs.meta b/Paths/Assets/Scripts/IPathfinding.cs.meta similarity index 100% rename from Paths/Assets/Scripts/Pathfinding.cs.meta rename to Paths/Assets/Scripts/IPathfinding.cs.meta diff --git a/Paths/Assets/Scripts/LevelGeneration.meta b/Paths/Assets/Scripts/LevelGeneration.meta new file mode 100644 index 0000000..b371b9f --- /dev/null +++ b/Paths/Assets/Scripts/LevelGeneration.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2e6679c6cec34399ac2cb0b03d08bdb4 +timeCreated: 1605296902 \ No newline at end of file diff --git a/Paths/Assets/Scripts/LevelGeneration/DrunkardWalk.cs b/Paths/Assets/Scripts/LevelGeneration/DrunkardWalk.cs new file mode 100644 index 0000000..bfdace4 --- /dev/null +++ b/Paths/Assets/Scripts/LevelGeneration/DrunkardWalk.cs @@ -0,0 +1,42 @@ +using Algorithms; + +namespace LevelGeneration { + public class DrunkardWalk : ILevelGenerator { + private readonly int _walks; + private readonly int _walkLength; + private readonly bool _add; + private readonly double _centerBias; + private readonly double _continueBias; + + /// + /// A simple level generator implementing the Drunkard Walk algorithm. + /// + /// The number of independent walks that will be started. + /// The maximum number of nodes to be added/cleared + /// if true, adds nodes to the grid - if false, removes nodes + /// the bias to walk towards the center of the grid + /// a bias to walk in the same direction as before + public DrunkardWalk(int walks, int walkLength, bool add, double centerBias = 0.1, double continueBias = 0.2) { + _walks = walks; + _walkLength = walkLength; + _add = add; + _centerBias = centerBias; + _continueBias = continueBias; + } + + /// + /// + /// + /// + /// + public NodeGrid Generate(NodeGrid nodeGrid) { + for (int unused = 0; unused < _walks; unused++) { + Node node = nodeGrid.GetRandomNode(); + + nodeGrid.GetAdjacentNodes(node); + } + + return nodeGrid; + } + } +} \ No newline at end of file diff --git a/Paths/Assets/Scripts/LevelGeneration/DrunkardWalk.cs.meta b/Paths/Assets/Scripts/LevelGeneration/DrunkardWalk.cs.meta new file mode 100644 index 0000000..609b780 --- /dev/null +++ b/Paths/Assets/Scripts/LevelGeneration/DrunkardWalk.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c2659a6b7f8f4dd8bfcd2f3407d25158 +timeCreated: 1605296926 \ No newline at end of file diff --git a/Paths/Assets/Scripts/LevelGeneration/RandomPlacement.cs b/Paths/Assets/Scripts/LevelGeneration/RandomPlacement.cs new file mode 100644 index 0000000..086976c --- /dev/null +++ b/Paths/Assets/Scripts/LevelGeneration/RandomPlacement.cs @@ -0,0 +1,43 @@ +using System; +using System.Linq; +using Algorithms; +using UnityEngine; + +namespace LevelGeneration { + public class RandomPlacement : ILevelGenerator { + private readonly float _percentFill; + private readonly bool _fillTo; + + + /// + /// A completely random level generator, placing walls randomly with no pattern or point. + /// Walls will be placed to meet a target percentage. + /// + /// The target percentage to fill the graph to. + /// If true, the graph will be filled to the target percentage. If false, it will simply add that percentage. + public RandomPlacement(float percentFill, bool fillTo) { + _percentFill = percentFill; + _fillTo = fillTo; + } + + public NodeGrid Generate(NodeGrid nodeGrid) { + // Calculate the number of walls to place + int wallsLeft = (int) Math.Round(nodeGrid.CellCount * _percentFill); + if (_fillTo) wallsLeft -= nodeGrid.Walls().Count(); + wallsLeft = Mathf.Clamp(wallsLeft, 0, nodeGrid.CellCount); + + // Begin adding walls + while (wallsLeft > 0) { + // Grab a node, skip if already a wall + Node node = nodeGrid.GetRandomNode(); + if (!node.Walkable) continue; + + // Node is empty, set to a wall + node.Walkable = false; + wallsLeft--; + } + + return nodeGrid; + } + } +} \ No newline at end of file diff --git a/Paths/Assets/Scripts/LevelGeneration/RandomPlacement.cs.meta b/Paths/Assets/Scripts/LevelGeneration/RandomPlacement.cs.meta new file mode 100644 index 0000000..67780ef --- /dev/null +++ b/Paths/Assets/Scripts/LevelGeneration/RandomPlacement.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5428da1d3ed1467fa51cf15de42c4d0c +timeCreated: 1605297927 \ No newline at end of file diff --git a/Paths/Assets/Scripts/Manager.cs b/Paths/Assets/Scripts/Manager.cs index abb9093..d0ac3be 100644 --- a/Paths/Assets/Scripts/Manager.cs +++ b/Paths/Assets/Scripts/Manager.cs @@ -71,6 +71,8 @@ public class Manager : MonoBehaviour { path = _algorithm.FindPath(start, end); _states = _algorithm.GetStates(); + + } private void LoadNextState() { diff --git a/Paths/Assets/Scripts/PathfindingAlgorithms.cs b/Paths/Assets/Scripts/PathfindingAlgorithms.cs deleted file mode 100644 index fdfe9c6..0000000 --- a/Paths/Assets/Scripts/PathfindingAlgorithms.cs +++ /dev/null @@ -1,6 +0,0 @@ -using System.ComponentModel; - -public enum PathfindingAlgorithms { - [Description("A description of the A")] - AStar -} \ No newline at end of file diff --git a/Paths/Assets/Scripts/PathfindingAlgorithms.cs.meta b/Paths/Assets/Scripts/PathfindingAlgorithms.cs.meta deleted file mode 100644 index badcf0b..0000000 --- a/Paths/Assets/Scripts/PathfindingAlgorithms.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: b24cdc9eff904f8eb4b2c42aa2cc12a2 -timeCreated: 1604700739 \ No newline at end of file