思路参照地址:http://www.cnblogs.com/technology/archive/2011/05/26/2058842.html
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Astar
{
class Program
{
static void Main(string[] args)
{
Point begin = new Point();//起点
begin.x = 1;
begin.y = 1;//坐标
//定义目的地
Point end = new Astar.Point();//终点
end.x = 9;
end.y = 9;
AllOperation ao= new AllOperation();
ao.WayFinding(begin,end);
ao.PrintMap();//打印
Console.ReadKey();
}
}
class AllOperation
{
#region 地图
int[,] Map = new int[10, 10]//定义一个地图
{
{ 1,1,1,1,1,1,1,1,1,1},
{ 1,1,1,1,1,1,1,1,1,1},
{ 1,1,0,1,1,1,1,1,1,1},
{ 1,1,0,1,0,1,0,0,0,0},
{ 1,1,0,1,1,1,0,1,1,1},
{ 0,0,0,1,1,1,0,1,1,1},
{ 0,1,1,1,1,0,0,1,1,1},
{ 0,1,0,1,1,0,1,1,1,1},
{ 1,1,0,0,0,0,1,1,1,1},
{ 1,1,1,1,1,1,1,1,1,1}
};//1表示可通过无障碍
//两个集合保存可用和不可用的点
#endregion
List<Point> can = new List<Point>();
List<Point> cannot = new List<Point>();
public bool ThePointIsInCannot(int x,int y)
{
foreach (Point p in cannot)
{
if(p.x==x&&p.y==y)
return true;
}
return false;
}
public bool ThePointIsInCan(int x, int y)
{
foreach (Point p in can)
{
if (p.x == x && p.y == y)
return true;
}
return false;
}
public int GetG(Point p)
{
if (p.father == null) return 0;//指的是没有第一个点
if (p.x == p.father.x || p.y == p.father.y)
return p.father.G + 10;//表示上一个点到这个点的距离
else
return p.father.G + 14;//表示斜着的
}//得到G,得到H
public int GetH(Point p,Point end)
{
return Math.Abs(p.x - end.x)*10 + Math.Abs(p.y - end.y)*10;
}
public Point getMinGH() //得到最小路径值,返回最小的点
{
Point pmin = null;
foreach (Point p in can)//遍历所有p值
{
if (pmin == null)
{
pmin = p;
}
else {
//说明已经有pmin值
if (pmin.G + pmin.H > p.G + p.H) pmin = p;
}
}
return pmin;//返回路径最小的点
}
public Point GetPointFromCan(int x,int y)//按照坐标找到can集合中的点
{
foreach(Point p in can )
if (p.x==x&&p.y==y)
return p;
return null;
}
public void CheckAround(Point p0,int [,] map,Point a,Point b)//检查p0点周围的点,if没有初始化值那就先赋值,else
{
for (int i = p0.x - 1; i <= p0.x + 1; i++)
{
for (int j = p0.y - 1; j <= p0.y + 1; j++)
{
//我们要遍历除了自身之外的8个点
//而且这8个点要在地图内部
if (i >= 0 && i < 10 && j >= 0 && j < 10 && !(i == p0.x && j == p0.y) )
{
//第一轮可能会刷下去一波点
//这轮我们要刷下去障碍的点和已经处在关闭集合里的点
if ((map[i, j] != 0) && !ThePointIsInCannot(i, j))
{
//第二轮结束
//如果这几个周围点不在开始列表里我们要先放进开始列表
//如果在里面说明已经初始化点的信息了
if (!ThePointIsInCan(i, j))
{
Point p = new Point();
p.x = i;
p.y = j;
p.father = p0;//表示从0走过来的
p.G = GetG(p);
p.H = GetH(p,b);
//初始化后我们要把这个点添加到can集合
can.Add(p);
Console.WriteLine("我们给can集合添加新的点,把周围的点给赋值 :"+i+" "+j +" "+p.G+" "+p.H+" 父节点:"+p.father.x+" "+p.father.y);
}
else
{
//说明此点已经处于can集合中,可以走一波
Point p = GetPointFromCan(i,j);
//找到了p点,
int GGGG = 0;
//判断参照点到这里的距离
if (p0.x == p.x || p0.y == p.y)
GGGG = p0.G + 10;
else
GGGG = p0.G + 14;
if (GGGG < p.G)
//如果新的g值比原来的小,那就说明原来的路线可以用现在的路线代替
//否则说明这么走不省路费
{
//todo//这个地方我们应该怎样控制呢
// can.Remove(p);//我们要把这个点移除,因为信息更新了,路线更新了,源点发生改变,G点改变
p.father = p0;//p的父点换成p0
p.G = GGGG;//替换掉G值
}
}
}
}
}
}
}
public void WayFinding(Point a,Point b)
{
can.Add(a);//我们要把开始点添加到can集合
//while()
while (true)//我们要一直循环,直到所有的点都不在can集合里,说明没找到路
//,或者 我们找到了终点
{
Console.Write("还在while里");
Point p0 = getMinGH();//得到距离最近的点
Console.WriteLine("我们本次找到的最合适的点是:" + p0.x + " " + p0.y +" G H分别是多少呢 ?:"+p0.G+" "+p0.H+" ");//+p0.father.x+ " "+p0.father.y
if (p0 == null)
{
Console.WriteLine("我们没找到最小的");
break;
}//没有点就是找不到路了
if (p0.x==b.x&&p0.y==b.y) {
Console.WriteLine("终点现在包含在can集合里");
break;
}
can.Remove(p0);//删除那个最近距离的点
cannot.Add(p0);//在关闭列表中添加此值
CheckAround(p0, Map, a, b);//传递参数依次为参照点,地图,起始点,终点
}
//循环结束后我们要记录路径
Point p = GetPointFromCan(b.x, b.y);//找到终点的point
Map[b.x, b.y] = 5;
Map[a.x, a.y] = 4;
while (p.father != null)
{
Console.WriteLine(p.x+" "+p.y+"地图路线赋值");
p = p.father;//往起始点方向跳转
Map[p.x, p.y] = 2;//2就表示我们的路线
}
Map[b.x, b.y] = 5;//收尾赋值
Map[a.x, a.y] = 4;
}
public void PrintMap()
{
for (int i= 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (Map[i, j] == 1) Console.Write("■");//█ ■▲▼♤※☹☺
else if (Map[i, j] == 2) Console.Write("★");
else if (Map[i, j] == 0) Console.Write("※");
else if (Map[i, j] == 4) Console.Write("▲");
else if (Map[i, j] == 5) Console.Write("yes");
// else Console.Write(" ");
}
Console.Write("\n");
}
}
}
public class Point
{
public int x, y;//坐标
public int G, H;//相关值
public Point father=null;//指向的对象
};
}
运行结果:
还在while里我们本次找到的最合适的点是:1 1 G H分别是多少呢 ?:0 0
我们给can集合添加新的点,把周围的点给赋值 :0 0 14 180 父节点:1 1
我们给can集合添加新的点,把周围的点给赋值 :0 1 10 170 父节点:1 1
我们给can集合添加新的点,把周围的点给赋值 :0 2 14 160 父节点:1 1
我们给can集合添加新的点,把周围的点给赋值 :1 0 10 170 父节点:1 1
我们给can集合添加新的点,把周围的点给赋值 :1 2 10 150 父节点:1 1
我们给can集合添加新的点,把周围的点给赋值 :2 0 14 160 父节点:1 1
我们给can集合添加新的点,把周围的点给赋值 :2 1 10 150 父节点:1 1
还在while里我们本次找到的最合适的点是:1 2 G H分别是多少呢 ?:10 150
我们给can集合添加新的点,把周围的点给赋值 :0 3 24 150 父节点:1 2
我们给can集合添加新的点,把周围的点给赋值 :1 3 20 140 父节点:1 2
我们给can集合添加新的点,把周围的点给赋值 :2 3 24 130 父节点:1 2
还在while里我们本次找到的最合适的点是:2 3 G H分别是多少呢 ?:24 130
我们给can集合添加新的点,把周围的点给赋值 :1 4 38 130 父节点:2 3
我们给can集合添加新的点,把周围的点给赋值 :2 4 34 120 父节点:2 3
我们给can集合添加新的点,把周围的点给赋值 :3 3 34 120 父节点:2 3
还在while里我们本次找到的最合适的点是:2 4 G H分别是多少呢 ?:34 120
我们给can集合添加新的点,把周围的点给赋值 :1 5 48 120 父节点:2 4
我们给can集合添加新的点,把周围的点给赋值 :2 5 44 110 父节点:2 4
我们给can集合添加新的点,把周围的点给赋值 :3 5 48 100 父节点:2 4
还在while里我们本次找到的最合适的点是:3 5 G H分别是多少呢 ?:48 100
我们给can集合添加新的点,把周围的点给赋值 :2 6 62 100 父节点:3 5
我们给can集合添加新的点,把周围的点给赋值 :4 4 62 100 父节点:3 5
我们给can集合添加新的点,把周围的点给赋值 :4 5 58 90 父节点:3 5
还在while里我们本次找到的最合适的点是:4 5 G H分别是多少呢 ?:58 90
我们给can集合添加新的点,把周围的点给赋值 :5 4 72 90 父节点:4 5
我们给can集合添加新的点,把周围的点给赋值 :5 5 68 80 父节点:4 5
还在while里我们本次找到的最合适的点是:5 5 G H分别是多少呢 ?:68 80
我们给can集合添加新的点,把周围的点给赋值 :6 4 82 80 父节点:5 5
还在while里我们本次找到的最合适的点是:3 3 G H分别是多少呢 ?:34 120
我们给can集合添加新的点,把周围的点给赋值 :4 3 44 110 父节点:3 3
还在while里我们本次找到的最合适的点是:4 4 G H分别是多少呢 ?:48 100
我们给can集合添加新的点,把周围的点给赋值 :5 3 62 100 父节点:4 4
还在while里我们本次找到的最合适的点是:5 4 G H分别是多少呢 ?:58 90
我们给can集合添加新的点,把周围的点给赋值 :6 3 72 90 父节点:5 4
还在while里我们本次找到的最合适的点是:6 4 G H分别是多少呢 ?:68 80
我们给can集合添加新的点,把周围的点给赋值 :7 3 82 80 父节点:6 4
我们给can集合添加新的点,把周围的点给赋值 :7 4 78 70 父节点:6 4
还在while里我们本次找到的最合适的点是:7 4 G H分别是多少呢 ?:78 70
还在while里我们本次找到的最合适的点是:2 5 G H分别是多少呢 ?:44 110
我们给can集合添加新的点,把周围的点给赋值 :1 6 58 110 父节点:2 5
还在while里我们本次找到的最合适的点是:2 6 G H分别是多少呢 ?:54 100
我们给can集合添加新的点,把周围的点给赋值 :1 7 68 100 父节点:2 6
我们给can集合添加新的点,把周围的点给赋值 :2 7 64 90 父节点:2 6
还在while里我们本次找到的最合适的点是:4 3 G H分别是多少呢 ?:44 110
还在while里我们本次找到的最合适的点是:5 3 G H分别是多少呢 ?:54 100
我们给can集合添加新的点,把周围的点给赋值 :6 2 68 100 父节点:5 3
还在while里我们本次找到的最合适的点是:6 3 G H分别是多少呢 ?:64 90
还在while里我们本次找到的最合适的点是:7 3 G H分别是多少呢 ?:74 80
还在while里我们本次找到的最合适的点是:2 7 G H分别是多少呢 ?:64 90
我们给can集合添加新的点,把周围的点给赋值 :1 8 78 90 父节点:2 7
我们给can集合添加新的点,把周围的点给赋值 :2 8 74 80 父节点:2 7
还在while里我们本次找到的最合适的点是:2 8 G H分别是多少呢 ?:74 80
我们给can集合添加新的点,把周围的点给赋值 :1 9 88 80 父节点:2 8
我们给can集合添加新的点,把周围的点给赋值 :2 9 84 70 父节点:2 8
还在while里我们本次找到的最合适的点是:2 9 G H分别是多少呢 ?:84 70
还在while里我们本次找到的最合适的点是:2 1 G H分别是多少呢 ?:10 150
我们给can集合添加新的点,把周围的点给赋值 :3 0 24 150 父节点:2 1
我们给can集合添加新的点,把周围的点给赋值 :3 1 20 140 父节点:2 1
还在while里我们本次找到的最合适的点是:1 3 G H分别是多少呢 ?:20 140
我们给can集合添加新的点,把周围的点给赋值 :0 4 34 140 父节点:1 3
还在while里我们本次找到的最合适的点是:1 4 G H分别是多少呢 ?:30 130
我们给can集合添加新的点,把周围的点给赋值 :0 5 44 130 父节点:1 4
还在while里我们本次找到的最合适的点是:1 5 G H分别是多少呢 ?:40 120
我们给can集合添加新的点,把周围的点给赋值 :0 6 54 120 父节点:1 5
还在while里我们本次找到的最合适的点是:1 6 G H分别是多少呢 ?:50 110
我们给can集合添加新的点,把周围的点给赋值 :0 7 64 110 父节点:1 6
还在while里我们本次找到的最合适的点是:1 7 G H分别是多少呢 ?:60 100
我们给can集合添加新的点,把周围的点给赋值 :0 8 74 100 父节点:1 7
还在while里我们本次找到的最合适的点是:1 8 G H分别是多少呢 ?:70 90
我们给can集合添加新的点,把周围的点给赋值 :0 9 84 90 父节点:1 8
还在while里我们本次找到的最合适的点是:1 9 G H分别是多少呢 ?:80 80
还在while里我们本次找到的最合适的点是:3 1 G H分别是多少呢 ?:20 140
我们给can集合添加新的点,把周围的点给赋值 :4 0 34 140 父节点:3 1
我们给can集合添加新的点,把周围的点给赋值 :4 1 30 130 父节点:3 1
还在while里我们本次找到的最合适的点是:4 1 G H分别是多少呢 ?:30 130
还在while里我们本次找到的最合适的点是:6 2 G H分别是多少呢 ?:68 100
我们给can集合添加新的点,把周围的点给赋值 :6 1 78 110 父节点:6 2
我们给can集合添加新的点,把周围的点给赋值 :7 1 82 100 父节点:6 2
还在while里我们本次找到的最合适的点是:0 2 G H分别是多少呢 ?:14 160
还在while里我们本次找到的最合适的点是:2 0 G H分别是多少呢 ?:14 160
还在while里我们本次找到的最合适的点是:0 3 G H分别是多少呢 ?:24 150
还在while里我们本次找到的最合适的点是:3 0 G H分别是多少呢 ?:24 150
还在while里我们本次找到的最合适的点是:0 4 G H分别是多少呢 ?:34 140
还在while里我们本次找到的最合适的点是:0 5 G H分别是多少呢 ?:44 130
还在while里我们本次找到的最合适的点是:0 6 G H分别是多少呢 ?:54 120
还在while里我们本次找到的最合适的点是:0 7 G H分别是多少呢 ?:64 110
还在while里我们本次找到的最合适的点是:0 8 G H分别是多少呢 ?:74 100
还在while里我们本次找到的最合适的点是:0 9 G H分别是多少呢 ?:84 90
还在while里我们本次找到的最合适的点是:4 0 G H分别是多少呢 ?:34 140
还在while里我们本次找到的最合适的点是:0 1 G H分别是多少呢 ?:10 170
还在while里我们本次找到的最合适的点是:1 0 G H分别是多少呢 ?:10 170
还在while里我们本次找到的最合适的点是:7 1 G H分别是多少呢 ?:82 100
我们给can集合添加新的点,把周围的点给赋值 :8 0 96 100 父节点:7 1
我们给can集合添加新的点,把周围的点给赋值 :8 1 92 90 父节点:7 1
还在while里我们本次找到的最合适的点是:8 1 G H分别是多少呢 ?:92 90
我们给can集合添加新的点,把周围的点给赋值 :9 0 106 90 父节点:8 1
我们给can集合添加新的点,把周围的点给赋值 :9 1 102 80 父节点:8 1
我们给can集合添加新的点,把周围的点给赋值 :9 2 106 70 父节点:8 1
还在while里我们本次找到的最合适的点是:9 2 G H分别是多少呢 ?:106 70
我们给can集合添加新的点,把周围的点给赋值 :9 3 116 60 父节点:9 2
还在while里我们本次找到的最合适的点是:9 3 G H分别是多少呢 ?:116 60
我们给can集合添加新的点,把周围的点给赋值 :9 4 126 50 父节点:9 3
还在while里我们本次找到的最合适的点是:9 4 G H分别是多少呢 ?:126 50
我们给can集合添加新的点,把周围的点给赋值 :9 5 136 40 父节点:9 4
还在while里我们本次找到的最合适的点是:9 5 G H分别是多少呢 ?:136 40
我们给can集合添加新的点,把周围的点给赋值 :8 6 150 40 父节点:9 5
我们给can集合添加新的点,把周围的点给赋值 :9 6 146 30 父节点:9 5
还在while里我们本次找到的最合适的点是:9 6 G H分别是多少呢 ?:146 30
我们给can集合添加新的点,把周围的点给赋值 :8 7 160 30 父节点:9 6
我们给can集合添加新的点,把周围的点给赋值 :9 7 156 20 父节点:9 6
还在while里我们本次找到的最合适的点是:9 7 G H分别是多少呢 ?:156 20
我们给can集合添加新的点,把周围的点给赋值 :8 8 170 20 父节点:9 7
我们给can集合添加新的点,把周围的点给赋值 :9 8 166 10 父节点:9 7
还在while里我们本次找到的最合适的点是:9 8 G H分别是多少呢 ?:166 10
我们给can集合添加新的点,把周围的点给赋值 :8 9 180 10 父节点:9 8
我们给can集合添加新的点,把周围的点给赋值 :9 9 176 0 父节点:9 8
还在while里我们本次找到的最合适的点是:9 9 G H分别是多少呢 ?:176 0
终点现在包含在can集合里
9 9地图路线赋值
9 8地图路线赋值
9 7地图路线赋值
9 6地图路线赋值
9 5地图路线赋值
9 4地图路线赋值
9 3地图路线赋值
9 2地图路线赋值
8 1地图路线赋值
7 1地图路线赋值
6 2地图路线赋值
5 3地图路线赋值
4 3地图路线赋值
3 3地图路线赋值
2 3地图路线赋值
1 2地图路线赋值
地图截图: