Skip to content

Instantly share code, notes, and snippets.

@lostplesed
Created March 29, 2019 15:49
Show Gist options
  • Save lostplesed/9367b7560b3f932fb2f8440a0310666f to your computer and use it in GitHub Desktop.
Save lostplesed/9367b7560b3f932fb2f8440a0310666f to your computer and use it in GitHub Desktop.
AStar c#
using System;
using System.Collections;
using System.Collections.Generic;
namespace AStar
{
public class Point
{
public int x;
public int y;
public Point(int _x, int _y)
{
x = _x;
y = _y;
}
}
public class Node
{
public bool canWalk;
public int gridX, gridY;
public int gCost;
public int hCost;
public int FCost
{
get
{
return gCost + hCost;
}
}
public Node Parent
{
get;
set;
}
public Node(bool canWalk,int x,int y)
{
this.canWalk = canWalk;
this.gridX = x;
this.gridY = y;
}
}
public class Grid
{
public Node[,] grid;
public int gird_count_x;
public int gird_count_y;
public Grid(int _count_x, int _count_y) {
gird_count_x = _count_x;
gird_count_y = _count_y;
grid = new Node[gird_count_x, gird_count_y];
for (int i = 0; i < gird_count_x; ++i) {
for (int j = 0; j < gird_count_y; ++j) {
grid [i, j] = new Node (true, i, j);
}
}
}
public Node GetNode(int x, int y)
{
return grid[x, y];
}
public List<Node> GetNeibourhood(Node node)
{
List<Node> neibourhood = new List<Node> ();
// 上下左右
for (int i = -1; i <= 1; i++)
{
for (int j = -1; j <= 1; j++)
{
if (i == 0 && j == 0)
continue;
if (Math.Abs (i) == Math.Abs (j))
continue;
int tempX = node.gridX + i;
int tempY = node.gridY + j;
if((tempX < gird_count_x && tempX >= 0) && (tempY < gird_count_y && tempY >= 0))
{
neibourhood.Add (grid [tempX, tempY]);
}
}
}
return neibourhood;
}
}
public class FindPath
{
private Grid gird;
public FindPath(int gird_count_x, int gird_count_y)
{
gird = new Grid (gird_count_x, gird_count_y);
}
public List<Node> FindingPath(Point startPos, Point endPos)
{
List<Node> openList = new List<Node> ();
HashSet<Node> closeList = new HashSet<Node> ();
Node startNode = gird.GetNode(startPos.x, startPos.y);
Node endNode = gird.GetNode(endPos.x, endPos.y);
openList.Add (startNode);
while (openList.Count > 0)
{
Node currentNode = openList [0];
for (int i = 1; i < openList.Count; i++)
{
if(openList[i].FCost < currentNode.FCost ||
openList[i].FCost == currentNode.FCost && openList[i].hCost < currentNode.hCost)
{
currentNode = openList [i];
}
}
openList.Remove (currentNode);
closeList.Add (currentNode);
if(currentNode == endNode)
{
return GeneratePath (startNode, endNode);
}
List<Node> nebinourhoodList = gird.GetNeibourhood (currentNode);
foreach (var node in nebinourhoodList)
{
if (!node.canWalk || closeList.Contains (node))
continue;
int newGCost = GetDistanceNodes (currentNode, node);
if(newGCost < node.gCost || !openList.Contains(node))
{
node.gCost = newGCost;
node.hCost = GetDistanceNodes (node, endNode);
node.Parent = currentNode;
if(!openList.Contains(node))
{
openList.Add (node);
}
}
}
}
return null;
}
public List<Node> GeneratePath(Node startNode ,Node endNode)
{
List<Node> path = new List<Node> ();
Node temp = endNode;
while (temp != startNode)
{
path.Add (temp);
temp = temp.Parent;
}
return path;
}
private int GetDistanceNodes(Node a, Node b)
{
int x = Math.Abs (a.gridX - b.gridX);
int y = Math.Abs (a.gridY - b.gridY);
if(x > y)
{
return 14 * y + 10 * (x - y);
}
return 14 * x + 10 * (y - x);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment