Created
March 29, 2019 15:49
-
-
Save lostplesed/9367b7560b3f932fb2f8440a0310666f to your computer and use it in GitHub Desktop.
AStar c#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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