switch to Vector2Int instead of float based System.Numerics.Vector2, redundant code removal command

This commit is contained in:
Xevion
2020-11-13 09:20:43 -06:00
parent caf071fc70
commit b8e9e383c4
6 changed files with 69 additions and 78 deletions

View File

@@ -1,7 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Vector2 = System.Numerics.Vector2;
namespace Algorithms {
public class AStar : IPathfinding {
@@ -12,18 +11,18 @@ namespace Algorithms {
private List<Node> _closedList;
private List<GridState> _states;
private Vector2 _start;
private Vector2 _end;
private Vector2Int _start;
private Vector2Int _end;
public Vector2 Start { get => _start; }
public Vector2 End { get => _end; }
public Vector2Int Start { get => _start; }
public Vector2Int End { get => _end; }
public AStar(NodeGrid nodeGrid) {
this._nodeGrid = nodeGrid;
_states = new List<GridState>();
}
public Stack<Node> FindPath(Vector2 start, Vector2 end) {
public Stack<Node> FindPath(Vector2Int start, Vector2Int end) {
this._start = start;
this._end = end;

View File

@@ -1,10 +1,10 @@
using System.Numerics;
using UnityEngine;
namespace Algorithms {
public class Node {
// Change this depending on what the desired size is for each element in the grid
public Node Parent;
public Vector2 Position;
public Vector2Int Position;
// A* Algorithm variables
public float DistanceToTarget;
@@ -21,7 +21,7 @@ namespace Algorithms {
public bool Walkable;
public Node(Vector2 pos, bool walkable, float weight = 1) {
public Node(Vector2Int pos, bool walkable, float weight = 1) {
Parent = null;
Position = pos;
DistanceToTarget = -1;
@@ -31,7 +31,7 @@ namespace Algorithms {
}
public override string ToString() {
return $"Node({Position.X}, {Position.Y}, {Walkable})";
return $"Node({Position.x}, {Position.y}, {Walkable})";
}
}
}

View File

@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using UnityEngine;
using Random = UnityEngine.Random;
namespace Algorithms {
@@ -13,50 +13,50 @@ namespace Algorithms {
public NodeGrid(int width, int height) {
if (width <= 0)
throw new ArgumentOutOfRangeException(nameof(width),
$"The width of the grid must be a positive non-zero integer.");
"The width of the grid must be a positive non-zero integer.");
if (height <= 0)
throw new ArgumentOutOfRangeException(nameof(height),
$"The height of the grid must be a positive non-zero integer.");
"The height of the grid must be a positive non-zero integer.");
this.grid = new List<List<Node>>(width);
grid = new List<List<Node>>(width);
// Fill grid with width*height nodes, zero-indexed
foreach (int x in Enumerable.Range(0, width - 1)) {
List<Node> list = new List<Node>(height);
foreach (int y in Enumerable.Range(0, height))
list.Add(new Node(new Vector2(x, y), true));
list.Add(new Node(new Vector2Int(x, y), true));
this.grid.Add(list);
grid.Add(list);
}
this.Width = width;
this.Height = height;
Width = width;
Height = height;
}
public NodeGrid(List<List<Node>> grid) {
this.grid = grid;
this.Height = this.grid[0].Count;
this.Width = this.grid.Count;
Height = this.grid[0].Count;
Width = this.grid.Count;
}
public List<Node> GetAdjacentNodes(Node node) {
List<Node> temp = new List<Node>();
int row = (int) node.Position.Y;
int col = (int) node.Position.X;
int row = node.Position.y;
int col = node.Position.x;
if (row + 1 < Height) temp.Add(this.grid[col][row + 1]);
if (row - 1 >= 0) temp.Add(this.grid[col][row - 1]);
if (col - 1 >= 0) temp.Add(this.grid[col - 1][row]);
if (col + 1 < Width) temp.Add(this.grid[col + 1][row]);
if (row + 1 < Height) temp.Add(grid[col][row + 1]);
if (row - 1 >= 0) temp.Add(grid[col][row - 1]);
if (col - 1 >= 0) temp.Add(grid[col - 1][row]);
if (col + 1 < Width) temp.Add(grid[col + 1][row]);
return temp;
}
public bool IsValid(int x, int y) {
return x > 0 && x < this.Width && y > 0 && y < this.Height;
return x > 0 && x < Width && y > 0 && y < Height;
}
/// <summary>
/// Retrieves a node at a given coordinate.
/// </summary>
@@ -66,30 +66,29 @@ namespace Algorithms {
/// <exception cref="ArgumentOutOfRangeException">when the coordinate given does not exist on the grid</exception>
public Node GetNode(int x, int y) {
// if(!IsValid(x, y))
// throw new ArgumentOutOfRangeException();
return this.grid[x][y];
// throw new ArgumentOutOfRangeException();
return grid[x][y];
}
public void FlipRandomWall() {
this.grid[Random.Range(0, this.Width - 1)][Random.Range(0, this.Height - 1)].Walkable = false;
grid[Random.Range(0, Width - 1)][Random.Range(0, Height - 1)].Walkable = false;
}
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);
return Math.Abs(first.Position.x - second.Position.x) + Math.Abs(first.Position.y - second.Position.y);
}
public static float Manhattan(Vector2 algorithmStart, Vector2 algorithmEnd) {
return NodeGrid.Manhattan(new Node(algorithmStart, false), new Node(algorithmEnd, false));
public static float Manhattan(Vector2Int algorithmStart, Vector2Int algorithmEnd) {
return Manhattan(new Node(algorithmStart, false), new Node(algorithmEnd, false));
}
/// <summary>
/// Returns a random Vector2 position within the grid.
/// Returns a random Vector2Int position within the grid.
/// </summary>
/// <returns>a valid Vector2 position within the grid</returns>
public Vector2 RandomPosition() {
return new Vector2(Random.Range(0, Width - 1), Random.Range(0, Height - 1));
/// <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));
}
}
}

View File

@@ -1,55 +1,55 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using Algorithms;
using UnityEngine;
using Vector2 = System.Numerics.Vector2;
public class GridState {
public List<List<GridNodeType>> Grid;
public float time;
public GridState(NodeGrid grid, IEnumerable<Node> seen, IEnumerable<Node> expanded, Vector2 start, Vector2 end, IReadOnlyCollection<Node> path) {
this.time = Time.realtimeSinceStartup;
this.Grid = new List<List<GridNodeType>>(grid.Width);
public GridState(NodeGrid grid, IEnumerable<Node> seen, IEnumerable<Node> expanded, Vector2Int start,
Vector2Int end, IReadOnlyCollection<Node> path) {
time = Time.realtimeSinceStartup;
Grid = new List<List<GridNodeType>>(grid.Width);
// Add walls and empty tiles
foreach (var x in Enumerable.Range(0, grid.Width - 1)) {
this.Grid.Add(new List<GridNodeType>(grid.Height));
Grid.Add(new List<GridNodeType>(grid.Height));
foreach (var y in Enumerable.Range(0, grid.Height - 1)) {
Node node = grid.GetNode(x, y);
this.Grid[x].Add(!node.Walkable ? GridNodeType.Wall : GridNodeType.Empty);
Grid[x].Add(!node.Walkable ? GridNodeType.Wall : GridNodeType.Empty);
}
}
// Add 'seen' tiles
foreach (Node seenNode in seen)
this.Grid[(int) seenNode.Position.X][(int) seenNode.Position.Y] = GridNodeType.Seen;
Grid[seenNode.Position.x][seenNode.Position.y] = GridNodeType.Seen;
// Add 'expanded' tiles
foreach (Node expandedNode in expanded)
this.Grid[(int) expandedNode.Position.X][(int) 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)
this.Grid[(int) pathNode.Position.X][(int) pathNode.Position.Y] = GridNodeType.Path;
Grid[pathNode.Position.y][pathNode.Position.y] = GridNodeType.Path;
// Set start and end tiles
this.Grid[(int) start.X][(int) start.Y] = GridNodeType.Start;
this.Grid[(int) end.X][(int) end.Y] = GridNodeType.End;
Grid[start.x][start.y] = GridNodeType.Start;
Grid[end.x][end.y] = GridNodeType.End;
}
public IEnumerable<GridNodeType> GetNodes() {
return this.Grid.SelectMany(nodeList => nodeList).ToList();
return Grid.SelectMany(nodeList => nodeList).ToList();
}
public string RenderGrid() {
string result = "";
foreach (List<GridNodeType> nodeTypes in this.Grid) {
foreach (List<GridNodeType> nodeTypes in Grid) {
result = nodeTypes.Aggregate(result, (current, nodeType) => current + $"{(int) nodeType}") + "\n";
}
return result;
}
}

View File

@@ -3,9 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using Algorithms;
using TMPro;
using UnityEditor;
using UnityEngine;
using Vector2 = System.Numerics.Vector2;
/// <summary>
/// The primary controller of the entire application, managing state, events and sending commands
@@ -20,8 +18,8 @@ public class Manager : MonoBehaviour {
public TextMeshPro debugText;
public void Start() {
GeneratePath();
_states = new List<GridState>();
GeneratePath();
}
public void OnDrawGizmos() {
@@ -32,17 +30,13 @@ public class Manager : MonoBehaviour {
if (_curIndex < _states.Count)
this.LoadNextState();
else {
float t1 = Time.time, t2 = Time.time;
try {
t1 = Time.time;
lastStart = Time.realtimeSinceStartup;
GeneratePath();
_curIndex = 0;
Debug.Log($"({NodeGrid.Manhattan(_algorithm.Start, _algorithm.End)} in {_states.Count} states. {path.Count} path length.");
t2 = Time.time;
// Debug.Log(t2 - t1);
// _curIndex = path != null && path.Count > 30 ? 0 : _states.Count;
}
catch (ArgumentOutOfRangeException e) {
catch (ArgumentOutOfRangeException) {
}
}
}
@@ -51,13 +45,12 @@ public class Manager : MonoBehaviour {
var nodeGrid = new NodeGrid(gridController.size, gridController.size);
_algorithm = new AStar(nodeGrid);
Vector2 start = nodeGrid.RandomPosition();
Vector2 end = nodeGrid.RandomPosition();
// Vector2 start = new Vector2(1, 1);
// Vector2 end = new Vector2(gridController.size - 5, gridController.size - 5);
// Vector2 start = nodeGrid.RandomPosition();
Vector2Int start = new Vector2Int(30, 30);
Vector2Int end = nodeGrid.RandomPosition();
int wallCount = (int) (gridController.size * gridController.size * 0.1);
foreach (int index in Enumerable.Range(0, wallCount))
int wallCount = (int) (gridController.size * gridController.size * 0.5);
foreach (int unused in Enumerable.Range(0, wallCount))
nodeGrid.FlipRandomWall();
path = _algorithm.FindPath(start, end);

View File

@@ -1,6 +1,6 @@
using System.Collections.Generic;
using System.Numerics;
using Algorithms;
using UnityEngine;
/// <summary>
/// A general interface for implementing pathfinding algorithms.
@@ -12,14 +12,14 @@ public interface IPathfinding {
/// <param name="start">The position from which pathfinding begins</param>
/// <param name="end">The position trying to be found via pathfinding</param>
/// <returns>A List of NodeGridGrid objects representing the timeline of Pathfinding</returns>
Stack<Node> FindPath(Vector2 start, Vector2 end);
Stack<Node> FindPath(Vector2Int start, Vector2Int end);
/// <summary>
/// Records the current state of the pathfinding algorithm. Internal usage only.
/// </summary>
void RecordState();
List<GridState> GetStates();
Vector2 Start { get; }
Vector2 End { get; }
List<GridState> GetStates();
Vector2Int Start { get; }
Vector2Int End { get; }
}