fix off by one Random.Range generation (??), improve docs, GetAdjacentNodesArray

This commit is contained in:
Xevion
2020-11-13 19:19:53 -06:00
parent 30b115ab2a
commit ce4343c349
7 changed files with 77 additions and 52 deletions

View File

@@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=assets_005Ceditor/@EntryIndexedValue">False</s:Boolean></wpf:ResourceDictionary>

View File

@@ -1,32 +1,34 @@
using UnityEditor;
using UnityEngine;
/// <summary>
/// Prevents script compilation and reload while in play mode.
/// The editor will show a the spinning reload icon if there are unapplied changes but will not actually
/// apply them until playmode is exited.
/// Note: Script compile errors will not be shown while in play mode.
/// Derived from the instructions here:
/// https://support.unity3d.com/hc/en-us/articles/210452343-How-to-stop-automatic-assembly-compilation-from-script
/// </summary>
[InitializeOnLoad]
public class DisableScriptReload {
static DisableScriptReload() {
EditorApplication.playModeStateChanged
+= OnPlayModeStateChanged;
}
namespace Editor {
/// <summary>
/// Prevents script compilation and reload while in play mode.
/// The editor will show a the spinning reload icon if there are unapplied changes but will not actually
/// apply them until playmode is exited.
/// Note: Script compile errors will not be shown while in play mode.
/// Derived from the instructions here:
/// https://support.unity3d.com/hc/en-us/articles/210452343-How-to-stop-automatic-assembly-compilation-from-script
/// </summary>
[InitializeOnLoad]
public class DisableScriptReload {
static DisableScriptReload() {
EditorApplication.playModeStateChanged
+= OnPlayModeStateChanged;
}
static void OnPlayModeStateChanged(PlayModeStateChange stateChange) {
switch (stateChange) {
case (PlayModeStateChange.EnteredPlayMode): {
EditorApplication.LockReloadAssemblies();
Debug.Log("Assembly Reload locked as entering play mode");
break;
}
case (PlayModeStateChange.ExitingPlayMode): {
Debug.Log("Assembly Reload unlocked as exiting play mode");
EditorApplication.UnlockReloadAssemblies();
break;
static void OnPlayModeStateChanged(PlayModeStateChange stateChange) {
switch (stateChange) {
case (PlayModeStateChange.EnteredPlayMode): {
EditorApplication.LockReloadAssemblies();
Debug.Log("Assembly Reload locked as entering play mode");
break;
}
case (PlayModeStateChange.ExitingPlayMode): {
Debug.Log("Assembly Reload unlocked as exiting play mode");
EditorApplication.UnlockReloadAssemblies();
break;
}
}
}
}

View File

@@ -43,7 +43,7 @@ namespace Algorithms {
_closedList.Add(current);
RecordState();
List<Node> adjacentNodes = this._nodeGrid.GetAdjacentNodes(current);
List<Node> adjacentNodes = this._nodeGrid.GetAdjacentNodesList(current);
if (adjacentNodes.Count > 0) {
foreach (Node n in adjacentNodes) {

View File

@@ -20,10 +20,11 @@ namespace Algorithms {
"The height of the grid must be a positive non-zero integer.");
grid = new List<List<Node>>(width);
// Fill grid with width*height nodes, zero-indexed
foreach (int x in Enumerable.Range(0, width - 1)) {
for (int x = 0; x < width; x++) {
List<Node> list = new List<Node>(height);
foreach (int y in Enumerable.Range(0, height - 1))
for (int y = 0; y < height; y++)
list.Add(new Node(new Vector2Int(x, y), true));
grid.Add(list);
@@ -40,7 +41,7 @@ namespace Algorithms {
Width = this.grid.Count;
}
public List<Node> GetAdjacentNodes(Node node) {
public List<Node> GetAdjacentNodesList(Node node) {
List<Node> temp = new List<Node>();
int col = node.Position.x;
@@ -54,6 +55,24 @@ namespace Algorithms {
return temp;
}
public Node[] GetAdjacentNodesArray(Node node) {
int col = node.Position.x;
int row = node.Position.y;
return new Node[] {
row + 1 < Height ? grid[col][row + 1] : null,
row - 1 >= 0 ? grid[col][row - 1] : null,
col - 1 >= 0 ? grid[col - 1][row] : null,
col + 1 < Width ? grid[col + 1][row] : null
};
}
/// <summary>
/// Tests whether a coordinate is valid on the NodeGrid
/// </summary>
/// <param name="x">The X (column) coordinate</param>
/// <param name="y">The Y (row) coordinate</param>
/// <returns></returns>
public bool IsValid(int x, int y) {
return x > 0 && x < Width && y > 0 && y < Height;
}
@@ -81,8 +100,8 @@ namespace Algorithms {
/// </summary>
public void AddRandomWall() {
while (true) {
int x = Random.Range(0, Width - 1);
int y = Random.Range(0, Height - 1);
int x = Random.Range(0, Width);
int y = Random.Range(0, Height);
if (grid[x][y].Walkable) {
grid[x][y].Walkable = false;
@@ -104,7 +123,7 @@ namespace Algorithms {
/// </summary>
/// <returns>a valid Vector2Int position within the grid</returns>
public Vector2Int RandomPosition() {
return new Vector2Int(Random.Range(0, Width - 1), Random.Range(0, Height - 1));
return new Vector2Int(Random.Range(0, Width), Random.Range(0, Height));
}
/// <summary>
@@ -133,7 +152,7 @@ namespace Algorithms {
/// </summary>
/// <returns>A Node object.</returns>
public Node GetRandomNode() {
return grid[Random.Range(0, Width - 1)][Random.Range(0, Height - 1)];
return grid[Random.Range(0, Width)][Random.Range(0, Height)];
}
}
}

View File

@@ -1,5 +1,11 @@
using Algorithms;
public interface ILevelGenerator {
/// <summary>
/// Applies the LevelGenerator's algorithm.
/// A empty NodeGrid is recommended, as the algorithm may perform in unexpected ways, possibly even fail.
/// </summary>
/// <param name="nodeGrid">A NodeGrid object.</param>
/// <returns>A modified NodeGrid object.</returns>
NodeGrid Generate(NodeGrid nodeGrid);
}

View File

@@ -10,6 +10,9 @@ namespace LevelGeneration {
/// <summary>
/// A simple level generator implementing the Drunkard Walk algorithm.
/// This implementation simply starts 'walks' a certain number of times.
/// Each walk chooses a node, and then repeatedly chooses an adjacent node randomly.
/// Each move clears (or adds) walls.
/// </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>
@@ -24,16 +27,10 @@ namespace LevelGeneration {
_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);
Node[] nodes = nodeGrid.GetAdjacentNodesArray(node);
}
return nodeGrid;

View File

@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Algorithms;
using TMPro;
using UnityEngine;
@@ -12,7 +11,7 @@ public class Manager : MonoBehaviour {
private IPathfinding _algorithm;
private List<GridState> _states;
private int _curIndex;
private Stack<Node> path;
private Stack<Node> _path;
private float _lastStart;
private float _runtime;
@@ -30,10 +29,10 @@ public class Manager : MonoBehaviour {
GeneratePath();
}
public void OnDrawGizmos() {
float size = (float) (10.0 / gridController.size);
Gizmos.DrawWireCube(transform.position, new Vector3(size, size, size));
}
// public void OnDrawGizmos() {
// float size = (float) (10.0 / gridController.size);
// Gizmos.DrawWireCube(transform.position, new Vector3(size, size, size));
// }
public void Update() {
_runtime += Time.deltaTime * speed;
@@ -56,8 +55,8 @@ public class Manager : MonoBehaviour {
var nodeGrid = new NodeGrid(gridController.size, gridController.size);
_algorithm = new AStar(nodeGrid);
// Vector2 start = nodeGrid.RandomPosition();
Vector2Int start = new Vector2Int(30, 30);
Vector2Int start = nodeGrid.RandomPosition();
// Vector2Int start = new Vector2Int(30, 30);
Vector2Int end = nodeGrid.RandomPosition();
@@ -68,7 +67,7 @@ public class Manager : MonoBehaviour {
nodeGrid.GetNode(start).Walkable = true;
nodeGrid.GetNode(end).Walkable = true;
path = _algorithm.FindPath(start, end);
_path = _algorithm.FindPath(start, end);
_states = _algorithm.GetStates();
@@ -80,7 +79,7 @@ public class Manager : MonoBehaviour {
gridController.LoadGridState(state);
float change = state.Time - _lastStart;
string pathCount = path != null ? $"{path.Count}" : "N/A";
string pathCount = _path != null ? $"{_path.Count}" : "N/A";
debugText.text =
$"{change * 1000.0:F1}ms\n{this.CurrentIndex:000} / {this._states.Count:000}\nPath: {pathCount} tiles";
}