begin working on new level/cave generation abilities, RandomPlacement & DrunkardWalk

This commit is contained in:
Xevion
2020-11-11 18:26:35 -06:00
parent 3761b3c26b
commit 30b115ab2a
13 changed files with 135 additions and 10 deletions

View File

@@ -9,6 +9,7 @@ namespace Algorithms {
private List<List<Node>> grid; private List<List<Node>> grid;
public readonly int Width; public readonly int Width;
public readonly int Height; public readonly int Height;
public int CellCount => this.Width * this.Height;
public NodeGrid(int width, int height) { public NodeGrid(int width, int height) {
if (width <= 0) if (width <= 0)
@@ -52,7 +53,7 @@ namespace Algorithms {
return temp; return temp;
} }
public bool IsValid(int x, int y) { public bool IsValid(int x, int y) {
return x > 0 && x < Width && y > 0 && y < Height; return x > 0 && x < Width && y > 0 && y < Height;
} }
@@ -105,5 +106,34 @@ namespace Algorithms {
public Vector2Int RandomPosition() { public Vector2Int RandomPosition() {
return new Vector2Int(Random.Range(0, Width - 1), Random.Range(0, Height - 1)); return new Vector2Int(Random.Range(0, Width - 1), Random.Range(0, Height - 1));
} }
/// <summary>
/// Applies a ILevelGenerators's generate function to a NodeGrid
/// </summary>
/// <param name="generator">A instantiated level generator (ILevelGenerator) object</param>
public void ApplyGenerator(ILevelGenerator generator) {
}
public IEnumerable<Node> 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<Node> Walls() {
return this.Iterator().Where(node => !node.Walkable);
}
public IEnumerable<Node> Empty() {
return this.Iterator().Where(node => node.Walkable);
}
/// <summary>
/// Returns a random valid node on the grid.
/// </summary>
/// <returns>A Node object.</returns>
public Node GetRandomNode() {
return grid[Random.Range(0, Width - 1)][Random.Range(0, Height - 1)];
}
} }
} }

View File

@@ -0,0 +1,5 @@
using Algorithms;
public interface ILevelGenerator {
NodeGrid Generate(NodeGrid nodeGrid);
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 24f2296f0d384c598d2637daf13df886
timeCreated: 1605297076

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2e6679c6cec34399ac2cb0b03d08bdb4
timeCreated: 1605296902

View File

@@ -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;
/// <summary>
/// A simple level generator implementing the Drunkard Walk algorithm.
/// </summary>
/// <param name="walks">The number of independent walks that will be started.</param>
/// <param name="walkLength">The maximum number of nodes to be added/cleared</param>
/// <param name="add">if true, adds nodes to the grid - if false, removes nodes</param>
/// <param name="centerBias">the bias to walk towards the center of the grid</param>
/// <param name="continueBias">a bias to walk in the same direction as before</param>
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;
}
/// <summary>
///
/// </summary>
/// <param name="nodeGrid"></param>
/// <returns></returns>
public NodeGrid Generate(NodeGrid nodeGrid) {
for (int unused = 0; unused < _walks; unused++) {
Node node = nodeGrid.GetRandomNode();
nodeGrid.GetAdjacentNodes(node);
}
return nodeGrid;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c2659a6b7f8f4dd8bfcd2f3407d25158
timeCreated: 1605296926

View File

@@ -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;
/// <summary>
/// A completely random level generator, placing walls randomly with no pattern or point.
/// Walls will be placed to meet a target percentage.
/// </summary>
/// <param name="percentFill">The target percentage to fill the graph to.</param>
/// <param name="fillTo">If true, the graph will be filled to the target percentage. If false, it will simply add that percentage.</param>
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;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5428da1d3ed1467fa51cf15de42c4d0c
timeCreated: 1605297927

View File

@@ -71,6 +71,8 @@ public class Manager : MonoBehaviour {
path = _algorithm.FindPath(start, end); path = _algorithm.FindPath(start, end);
_states = _algorithm.GetStates(); _states = _algorithm.GetStates();
} }
private void LoadNextState() { private void LoadNextState() {

View File

@@ -1,6 +0,0 @@
using System.ComponentModel;
public enum PathfindingAlgorithms {
[Description("A description of the A")]
AStar
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: b24cdc9eff904f8eb4b2c42aa2cc12a2
timeCreated: 1604700739