diff --git a/Paths/Assembly-CSharp-Editor.csproj.DotSettings b/Paths/Assembly-CSharp-Editor.csproj.DotSettings new file mode 100644 index 0000000..8691f12 --- /dev/null +++ b/Paths/Assembly-CSharp-Editor.csproj.DotSettings @@ -0,0 +1,2 @@ + + False \ No newline at end of file diff --git a/Paths/Assets/Editor/DisableScriptReload.cs b/Paths/Assets/Editor/DisableScriptReload.cs index d0de55d..85af8b5 100644 --- a/Paths/Assets/Editor/DisableScriptReload.cs +++ b/Paths/Assets/Editor/DisableScriptReload.cs @@ -1,32 +1,34 @@ using UnityEditor; using UnityEngine; -/// -/// 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 -/// -[InitializeOnLoad] -public class DisableScriptReload { - static DisableScriptReload() { - EditorApplication.playModeStateChanged - += OnPlayModeStateChanged; - } +namespace Editor { + /// + /// 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 + /// + [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; + } } } } diff --git a/Paths/Assets/Scripts/Algorithms/AStar.cs b/Paths/Assets/Scripts/Algorithms/AStar.cs index 1588779..1d9a1ab 100644 --- a/Paths/Assets/Scripts/Algorithms/AStar.cs +++ b/Paths/Assets/Scripts/Algorithms/AStar.cs @@ -43,7 +43,7 @@ namespace Algorithms { _closedList.Add(current); RecordState(); - List adjacentNodes = this._nodeGrid.GetAdjacentNodes(current); + List adjacentNodes = this._nodeGrid.GetAdjacentNodesList(current); if (adjacentNodes.Count > 0) { foreach (Node n in adjacentNodes) { diff --git a/Paths/Assets/Scripts/Algorithms/NodeGrid.cs b/Paths/Assets/Scripts/Algorithms/NodeGrid.cs index 54d67a4..ab5dcbc 100644 --- a/Paths/Assets/Scripts/Algorithms/NodeGrid.cs +++ b/Paths/Assets/Scripts/Algorithms/NodeGrid.cs @@ -20,10 +20,11 @@ namespace Algorithms { "The height of the grid must be a positive non-zero integer."); grid = new List>(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 list = new List(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 GetAdjacentNodes(Node node) { + public List GetAdjacentNodesList(Node node) { List temp = new List(); int col = node.Position.x; @@ -53,7 +54,25 @@ 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 + }; + } + + /// + /// Tests whether a coordinate is valid on the NodeGrid + /// + /// The X (column) coordinate + /// The Y (row) coordinate + /// public bool IsValid(int x, int y) { return x > 0 && x < Width && y > 0 && y < Height; } @@ -81,8 +100,8 @@ namespace Algorithms { /// 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 { /// /// a valid Vector2Int position within the grid 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)); } /// @@ -127,13 +146,13 @@ namespace Algorithms { 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)]; + return grid[Random.Range(0, Width)][Random.Range(0, Height)]; } } } \ No newline at end of file diff --git a/Paths/Assets/Scripts/ILevelGenerator.cs b/Paths/Assets/Scripts/ILevelGenerator.cs index e0d4fe5..6156160 100644 --- a/Paths/Assets/Scripts/ILevelGenerator.cs +++ b/Paths/Assets/Scripts/ILevelGenerator.cs @@ -1,5 +1,11 @@ using Algorithms; public interface ILevelGenerator { + /// + /// Applies the LevelGenerator's algorithm. + /// A empty NodeGrid is recommended, as the algorithm may perform in unexpected ways, possibly even fail. + /// + /// A NodeGrid object. + /// A modified NodeGrid object. NodeGrid Generate(NodeGrid nodeGrid); } \ No newline at end of file diff --git a/Paths/Assets/Scripts/LevelGeneration/DrunkardWalk.cs b/Paths/Assets/Scripts/LevelGeneration/DrunkardWalk.cs index bfdace4..d714b5c 100644 --- a/Paths/Assets/Scripts/LevelGeneration/DrunkardWalk.cs +++ b/Paths/Assets/Scripts/LevelGeneration/DrunkardWalk.cs @@ -10,6 +10,9 @@ namespace LevelGeneration { /// /// 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. /// /// The number of independent walks that will be started. /// The maximum number of nodes to be added/cleared @@ -24,16 +27,10 @@ namespace LevelGeneration { _continueBias = continueBias; } - /// - /// - /// - /// - /// 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; diff --git a/Paths/Assets/Scripts/Manager.cs b/Paths/Assets/Scripts/Manager.cs index d0ac3be..8e40ab4 100644 --- a/Paths/Assets/Scripts/Manager.cs +++ b/Paths/Assets/Scripts/Manager.cs @@ -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 _states; private int _curIndex; - private Stack path; + private Stack _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"; }