diff --git a/Paths/Assets/Scenes/Default.unity b/Paths/Assets/Scenes/Default.unity index 118ae59..98ecd58 100644 --- a/Paths/Assets/Scenes/Default.unity +++ b/Paths/Assets/Scenes/Default.unity @@ -145,7 +145,7 @@ AudioListener: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 519420028} - m_Enabled: 1 + m_Enabled: 0 --- !u!20 &519420031 Camera: m_ObjectHideFlags: 0 @@ -575,7 +575,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: gridMaterial: {fileID: 2100000, guid: 780d53bea4df7b0418e9c8ed8afd6410, type: 2} - size: 31 + size: 32 --- !u!23 &2092623186 MeshRenderer: m_ObjectHideFlags: 0 diff --git a/Paths/Assets/Scripts/Algorithms/AStar.cs b/Paths/Assets/Scripts/Algorithms/AStar.cs index 9b5ee5b..1588779 100644 --- a/Paths/Assets/Scripts/Algorithms/AStar.cs +++ b/Paths/Assets/Scripts/Algorithms/AStar.cs @@ -11,11 +11,8 @@ namespace Algorithms { private List _closedList; private List _states; - private Vector2Int _start; - private Vector2Int _end; - - public Vector2Int Start { get => _start; } - public Vector2Int End { get => _end; } + public Vector2Int Start { get; private set; } + public Vector2Int End { get; private set; } public AStar(NodeGrid nodeGrid) { this._nodeGrid = nodeGrid; @@ -23,17 +20,17 @@ namespace Algorithms { } public Stack FindPath(Vector2Int start, Vector2Int end) { - this._start = start; - this._end = end; + this.Start = start; + this.End = end; var startNode = new Node(start, true); var endNode = new Node(end, true); - + _path = new Stack(); _openList = new List(); _closedList = new List(); - + RecordState(); Node current = startNode; @@ -58,16 +55,16 @@ namespace Algorithms { _openList.Add(n); _openList = _openList.OrderBy(node => node.F).ToList(); - } } } + RecordState(); } } // construct path, if end was not closed return null - if (!_closedList.Exists(x => x.Position == endNode.Position)) { + if (!_closedList.Exists(node => node.Position == endNode.Position)) { return null; } @@ -89,7 +86,7 @@ namespace Algorithms { public void RecordState() { // TODO: Record pathfinding state information (stages, heuristic, statistical info) this._states.Add( - new GridState(this._nodeGrid, this._openList, this._closedList, _start, _end, _path) + new GridState(this._nodeGrid, this._openList, this._closedList, Start, End, _path) ); } diff --git a/Paths/Assets/Scripts/Algorithms/NodeGrid.cs b/Paths/Assets/Scripts/Algorithms/NodeGrid.cs index 1f52e39..98b0788 100644 --- a/Paths/Assets/Scripts/Algorithms/NodeGrid.cs +++ b/Paths/Assets/Scripts/Algorithms/NodeGrid.cs @@ -22,14 +22,14 @@ namespace Algorithms { // Fill grid with width*height nodes, zero-indexed foreach (int x in Enumerable.Range(0, width - 1)) { List list = new List(height); - foreach (int y in Enumerable.Range(0, height)) + foreach (int y in Enumerable.Range(0, height - 1)) list.Add(new Node(new Vector2Int(x, y), true)); grid.Add(list); } - Width = width; - Height = height; + Width = this.grid.Count; + Height = this.grid[0].Count; } public NodeGrid(List> grid) { @@ -42,8 +42,8 @@ namespace Algorithms { public List GetAdjacentNodes(Node node) { List temp = new List(); - int row = node.Position.y; int col = node.Position.x; + int row = node.Position.y; if (row + 1 < Height) temp.Add(grid[col][row + 1]); if (row - 1 >= 0) temp.Add(grid[col][row - 1]); @@ -71,16 +71,31 @@ namespace Algorithms { return grid[x][y]; } - public void FlipRandomWall() { - grid[Random.Range(0, Width - 1)][Random.Range(0, Height - 1)].Walkable = false; + public Node GetNode(Vector2Int position) { + return GetNode(position.x, position.y); } - public static float Manhattan(Node first, Node second) { - return Math.Abs(first.Position.x - second.Position.x) + Math.Abs(first.Position.y - second.Position.y); + /// + /// Finds one random walkable cell and turns it into a wall. + /// + public void AddRandomWall() { + while (true) { + int x = Random.Range(0, Width - 1); + int y = Random.Range(0, Height - 1); + + if (grid[x][y].Walkable) { + grid[x][y].Walkable = false; + return; + } + } } - public static float Manhattan(Vector2Int algorithmStart, Vector2Int algorithmEnd) { - return Manhattan(new Node(algorithmStart, false), new Node(algorithmEnd, false)); + public static float Manhattan(Node a, Node b) { + return Math.Abs(a.Position.x - b.Position.x) + Math.Abs(a.Position.y - b.Position.y); + } + + public static float Manhattan(Vector2Int a, Vector2Int b) { + return Manhattan(new Node(a, false), new Node(b, false)); } /// diff --git a/Paths/Assets/Scripts/GridController.cs b/Paths/Assets/Scripts/GridController.cs index 8563eb7..d6edf4a 100644 --- a/Paths/Assets/Scripts/GridController.cs +++ b/Paths/Assets/Scripts/GridController.cs @@ -14,7 +14,7 @@ public enum PropertyName { public class GridController : MonoBehaviour { public Material gridMaterial; // Maintain reference to the Grid Material the Shader is implanted upon public int size = 32; // Size of the grid, width and height - + // Value management private int[] _values; private ComputeBuffer _buffer; @@ -54,7 +54,7 @@ public class GridController : MonoBehaviour { throw new ArgumentOutOfRangeException(nameof(property), property, null); } } - + private void OnApplicationQuit() { // Release ComputeBuffer memory _buffer.Release(); @@ -66,12 +66,14 @@ public class GridController : MonoBehaviour { /// public void LoadGridState(GridState gridState) { // Loop over matrix and set values via cast Enum to int - foreach(int x in Enumerable.Range(0, gridState.Grid.Count - 1)) - foreach(int y in Enumerable.Range(0, gridState.Grid[0].Count - 1)) - this.SetValue(x, y, (int) gridState.Grid[x][y]); + for (int x = 0; x < gridState.Grid.GetLength(0); x++) { + for (int y = 0; y < gridState.Grid.GetLength(1); y++) + this.SetValue(x, y, (int) gridState.Grid[x, y]); + } + UpdateShader(PropertyName.Values); } - + /// /// Sets a value in the 1D array at a particular 2D coordinate /// @@ -81,7 +83,7 @@ public class GridController : MonoBehaviour { public void SetValue(int x, int y, int value) { _values[size * y + x] = value; } - + /// /// Returns the value at a 2D coordinate within the 1D array /// diff --git a/Paths/Assets/Scripts/GridState.cs b/Paths/Assets/Scripts/GridState.cs index e254e98..588af43 100644 --- a/Paths/Assets/Scripts/GridState.cs +++ b/Paths/Assets/Scripts/GridState.cs @@ -1,55 +1,58 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using Algorithms; using UnityEngine; public class GridState { - public List> Grid; + public readonly GridNodeType[,] Grid; + + // public List> Grid; public float time; public GridState(NodeGrid grid, IEnumerable seen, IEnumerable expanded, Vector2Int start, Vector2Int end, IReadOnlyCollection path) { time = Time.realtimeSinceStartup; - Grid = new List>(grid.Width); + + Grid = new GridNodeType[grid.Width, grid.Height]; // Add walls and empty tiles - foreach (var x in Enumerable.Range(0, grid.Width - 1)) { - Grid.Add(new List(grid.Height)); - foreach (var y in Enumerable.Range(0, grid.Height - 1)) { + for (int x = 0; x < grid.Width; x++) { + for (int y = 0; y < grid.Height; y++) { Node node = grid.GetNode(x, y); - Grid[x].Add(!node.Walkable ? GridNodeType.Wall : GridNodeType.Empty); + Grid[x, y] = node.Walkable ? GridNodeType.Empty : GridNodeType.Wall; } } // Add 'seen' tiles foreach (Node seenNode in seen) - Grid[seenNode.Position.x][seenNode.Position.y] = GridNodeType.Seen; + Grid[seenNode.Position.x, seenNode.Position.y] = GridNodeType.Seen; // Add 'expanded' tiles foreach (Node expandedNode in expanded) - Grid[expandedNode.Position.x][expandedNode.Position.y] = GridNodeType.Expanded; + Grid[expandedNode.Position.x, expandedNode.Position.y] = GridNodeType.Expanded; // Add 'path' tiles if (path != null) foreach (Node pathNode in path) - Grid[pathNode.Position.y][pathNode.Position.y] = GridNodeType.Path; + Grid[pathNode.Position.x, pathNode.Position.y] = GridNodeType.Path; // Set start and end tiles - Grid[start.x][start.y] = GridNodeType.Start; - Grid[end.x][end.y] = GridNodeType.End; + Grid[start.x, start.y] = GridNodeType.Start; + Grid[end.x, end.y] = GridNodeType.End; } - public IEnumerable GetNodes() { - return Grid.SelectMany(nodeList => nodeList).ToList(); - } + // public IEnumerable GetNodes() { + // return Grid.SelectMany(nodeList => nodeList).ToList(); + // } - public string RenderGrid() { - string result = ""; - foreach (List nodeTypes in Grid) { - result = nodeTypes.Aggregate(result, (current, nodeType) => current + $"{(int) nodeType}") + "\n"; - } + // public string RenderGrid() { + // string result = ""; + // foreach (List nodeTypes in Grid) { + // result = nodeTypes.Aggregate(result, (current, nodeType) => current + $"{(int) nodeType}") + "\n"; + // } - return result; - } + // return result; + // } } \ No newline at end of file diff --git a/Paths/Assets/Scripts/Manager.cs b/Paths/Assets/Scripts/Manager.cs index 443d339..a8b7136 100644 --- a/Paths/Assets/Scripts/Manager.cs +++ b/Paths/Assets/Scripts/Manager.cs @@ -23,7 +23,8 @@ public class Manager : MonoBehaviour { } public void OnDrawGizmos() { - Gizmos.DrawSphere(transform.position, 1); + float size = (float) (10.0 / gridController.size); + Gizmos.DrawWireCube(transform.position, new Vector3(size, size, size)); } public void Update() { @@ -48,10 +49,14 @@ public class Manager : MonoBehaviour { // Vector2 start = nodeGrid.RandomPosition(); Vector2Int start = new Vector2Int(30, 30); Vector2Int end = nodeGrid.RandomPosition(); + - int wallCount = (int) (gridController.size * gridController.size * 0.5); - foreach (int unused in Enumerable.Range(0, wallCount)) - nodeGrid.FlipRandomWall(); + int wallCount = (int) (gridController.size * gridController.size * 0.25); + for (int unused = 0; unused < wallCount; unused++) + nodeGrid.AddRandomWall(); + + nodeGrid.GetNode(start).Walkable = true; + nodeGrid.GetNode(end).Walkable = true; path = _algorithm.FindPath(start, end); @@ -64,7 +69,8 @@ public class Manager : MonoBehaviour { float change = state.time - lastStart; string pathCount = path != null ? $"{path.Count}" : "N/A"; - debugText.text = $"{change * 1000.0:F1}ms\n{this._curIndex:000} / {this._states.Count:000}\nPath: {pathCount} tiles"; - _curIndex += 1; + debugText.text = + $"{change * 1000.0:F1}ms\n{this._curIndex:000} / {this._states.Count:000}\nPath: {pathCount} tiles"; + _curIndex += 3; } } \ No newline at end of file