astar rewritten for c#

runs without screaming, don't have output yet though
This commit is contained in:
Simon O'Shea
2023-08-08 18:05:55 -04:00
parent ddc02784c2
commit 96a90a647d
3 changed files with 140 additions and 22 deletions
@@ -146,8 +146,7 @@ public class Main : MonoBehaviour
if ( true ) if ( true )
{ {
Pathfinder astar = new Pathfinder(world, agent, obstacles, samples, 0, 0); Pathfinder path = new Pathfinder(world, agent, obstacles, samples, 0, 0);
astar.go();
} }
} }
@@ -4,19 +4,19 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityEngine; using UnityEngine;
class Node : IComparable<Node> public class Node //: IComparable<Node>
{ {
// helper variables just to make indexing arrays easier to read // helper variables just to make indexing arrays easier to read
public static int row = 0; public static int row = 0;
public static int col = 1; public static int col = 1;
Node parent; public Node parent;
Vector2Int agent; public Vector2Int agent;
List<Vector2Int> samples; public List<Vector2Int> samples;
char lastMove; // for output/animation public char lastMove; // for output/animation
int distanceTraveled; // for calculating f(n) value public int distanceTraveled; // for calculating f(n) value
double heuristic; public double heuristic;
public double fn; // distance traveled + heuristic value public static double fn; // distance traveled + heuristic value
bool canSample; // for expansion bool canSample; // for expansion
// construct node :) // construct node :)
@@ -28,7 +28,7 @@ using UnityEngine;
this.lastMove = lastMove; this.lastMove = lastMove;
this.distanceTraveled = distanceTraveled; this.distanceTraveled = distanceTraveled;
this.heuristic = heuristic; this.heuristic = heuristic;
this.fn = distanceTraveled + heuristic; fn = distanceTraveled + heuristic;
} }
// determine valid moves and collect children to be sent back to search // determine valid moves and collect children to be sent back to search
@@ -101,7 +101,6 @@ using UnityEngine;
{ {
Node child = new Node(this, this.agent, this.samples, 'S', this.distanceTraveled + 1, this.heuristic); Node child = new Node(this, this.agent, this.samples, 'S', this.distanceTraveled + 1, this.heuristic);
// PROBLEM?
child.samples.RemoveAt(onSample.y); child.samples.RemoveAt(onSample.y);
//SampleWorld.nodesGenerated++; //SampleWorld.nodesGenerated++;
@@ -191,18 +190,18 @@ using UnityEngine;
} }
// we use to override comparisons for priorityQueues so that our heuristic calculations are actually used // we use to override comparisons for priorityQueues so that our heuristic calculations are actually used
public int CompareTo(Node other) /* public int CompareTo(Node other)
{ {
if (this.fn > other.fn) if (this.fn > other.fn)
return 1; return 1;
else else
return -1; return -1;
} }*/
} }
// helper class for Node // helper class for Node
class NodeComparator : Comparer<Node> /* class NodeComparator : Comparer<Node>
{ {
// used to sort nodes based on sum of distance traveled + heuristic estimation of work left // used to sort nodes based on sum of distance traveled + heuristic estimation of work left
public override int Compare(Node a, Node b) public override int Compare(Node a, Node b)
@@ -212,7 +211,7 @@ using UnityEngine;
else else
return -1; return -1;
} }
} }*/
// helper class for Node // helper class for Node
public class State public class State
{ {
@@ -1,6 +1,8 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using System.Linq;
public class Pathfinder : MonoBehaviour public class Pathfinder : MonoBehaviour
{ {
@@ -32,14 +34,17 @@ public class Pathfinder : MonoBehaviour
algorithm = algo; algorithm = algo;
heuristic = heu; heuristic = heu;
printInfo();
StartWork();
} }
public void printInfo()
public void go()
{ {
Debug.Log("Agent: " + agent[0] + "," + agent[1]); Debug.Log("Agent: " + agent[0] + "," + agent[1]);
for(int i = 0; i < obstacles.Count; i++) for (int i = 0; i < obstacles.Count; i++)
{ {
Debug.Log("Obstacle " + i + ": " + obstacles[i].x + ", " + obstacles[i].y); Debug.Log("Obstacle " + i + ": " + obstacles[i].x + ", " + obstacles[i].y);
} }
@@ -48,6 +53,121 @@ public class Pathfinder : MonoBehaviour
{ {
Debug.Log("Sample " + i + ": " + samples[i].x + ", " + samples[i].y); Debug.Log("Sample " + i + ": " + samples[i].x + ", " + samples[i].y);
} }
}
public void StartWork()
{
Node initialState = new Node(null, agent, samples, '0', 0, 0);
Stack<Node> result = new Stack<Node>();
if (algorithm == 0)
{
result = StartAStar(initialState);
} }
}
public static Stack<Node> StartAStar(Node initialState)
{
Stack<Node> solution = new Stack<Node>();
Queue<Node> open = new Queue<Node>();
//PriorityQueue<Node> open = new PriorityQueue<Node>();
open.Enqueue(initialState);
int cap = 10000;
while (true && cap > 0)
{
if (!open.Any())
return solution;
Node currentNode = open.Dequeue();
// check whether we are in goal state
if (currentNode.samples.Count() == 0)
{
var orderedList = open.OrderBy(Node => Node.fn);
while (currentNode.parent != null)
{
solution.Push(currentNode);
currentNode = currentNode.parent;
}
return solution;
}
// if not, expand children and continue
List<Node> children = currentNode.expand(-1);
if (heuristic.Equals("h0"))
h0(children);
/* else if (heuristic.Equals("h1"))
h1(children);
else if (heuristic.Equals("h2"))
h2(children);*/
foreach (Node child in children)
{
open.Enqueue(child);
}
cap--;
}
}
// HEURISTICS FOR ASTAR
public static List<Node> h0(List<Node> children)
{
List<Node> sorted = new List<Node>();
for (int i = 0; i < children.Count(); i++)
{
// estimated moves left: zero
children[i].heuristic = 0;
sorted.Add(children[i]);
}
sorted = sorted.OrderBy(Node => Node.fn).ToList();
return sorted;
}
/* public static List<Node> h1(List<Node> children)
{
Queue<Node> sorted = new PriorityQueue<>(new NodeComparator());
for (int i = 0; i < children.size(); i++)
{
// estimated moves left: samples left
children.get(i).heuristic = children.get(i).samples.size();
sorted.add(children.get(i));
}
return children;
}
public static Queue<Node> h2(List<Node> children)
{
Queue<Node> sorted = new PriorityQueue<>(new NodeComparator());
if (children.size() == 0)
return sorted;
Node child;
for (int i = 0; i < children.size(); i++)
{
// estimated moves left:
// distance to nearest sample + 1 (+1 to account for sample action)
child = children.get(i);
child.heuristic = Node.distance(child.agent, child.nearestSample()) + 1;
sorted.add(child);
}
return sorted;
}*/
} }