using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
test mytest = new test();
//定义出发位置
Point startingPoint = new Point();
startingPoint.x = 1;
startingPoint.y = 3;
//定义目的地
Point destination = new Point();
destination.x = 5;
destination.y = 0;
//定义移动力
int power = 10;
DateTime time1 = DateTime.Now;
mytest.FindWay(startingPoint, destination, power);
DateTime time2 = DateTime.Now;
mytest.PrintMap(startingPoint, destination);
Console.WriteLine("用时:" + (time2 - time1));
}
}
class test
{
//数值表示移动力消耗
public byte[,] R = new byte[10, 10]{
{ 8, 8, 8, 8, 8, 1, 1, 1, 3, 1 },
{ 8, 1, 1, 1, 1, 1, 1, 1, 6, 1 },
{ 8, 8, 1, 8, 8, 1, 1, 2, 1, 1 },
{ 8, 8, 8, 8, 8, 1, 1, 1, 1, 1 },
{ 8, 8, 8, 2, 8, 1, 1, 1, 1, 1 },
{ 1, 8, 1, 2, 8, 1, 1, 3, 1, 1 },
{ 1, 1, 1, 1, 8, 1, 2, 1, 1, 2 },
{ 1, 2, 5, 1, 8, 1, 2, 1, 1, 1 },
{ 1, 1, 7, 1, 1, 1, 2, 2, 1, 1 },
{ 1, 1, 1, 1, 1, 2, 2, 3, 1, 1 }};
//最终路径
List<Point> way = new List<Point>();
//开启列表
List<Point> Open_List = new List<Point>();
//关闭列表
List<Point> Close_List = new List<Point>();
//从开启列表查找F值最小的节点
private Point GetMinFFromOpenList()
{
Point Pmin = null;
foreach (Point p in Open_List) if (Pmin == null || Pmin.G + Pmin.H > p.G + p.H) Pmin = p;
return Pmin;
}
//判断关闭列表是否包含一个坐标的点
private bool IsInCloseList(int x, int y)
{
foreach (Point p in Close_List) if (p.x == x && p.y == y) return true;
return false;
}
//判断开启列表是否包含一个坐标的点
private bool IsInOpenList(int x, int y)
{
foreach (Point p in Open_List) if (p.x == x && p.y == y) return true;
return false;
}
//从开启列表返回对应坐标的点
private Point GetPointFromOpenList(int x, int y)
{
foreach (Point p in Open_List) if (p.x == x && p.y == y) return p;
return null;
}
//检查当前节点附近的节点
private void CheckGrid(Point nowPoint, Point startingPoint, Point destination)
{
for (int xt = nowPoint.x - 1; xt <= nowPoint.x + 1; xt++)
{
for (int yt = nowPoint.y - 1; yt <= nowPoint.y + 1; yt++)
{
//排除超过边界、不相干和关闭列表中的点
if (!(xt >= 0 && xt < R.GetLength(0) && yt >= 0 && yt < R.GetLength(1))) continue;
if (IsInCloseList(xt, yt)) continue;
if (!(xt == nowPoint.x && yt - 1 == nowPoint.y) && !(xt - 1 == nowPoint.x && yt == nowPoint.y) && !(xt + 1 == nowPoint.x && yt == nowPoint.y) && !(xt == nowPoint.x && yt + 1 == nowPoint.y))
continue;
if (IsInOpenList(xt, yt))
{
Point pt = GetPointFromOpenList(xt, yt);
int G_new = nowPoint.G + R[pt.x, pt.y];
if (G_new < pt.G)
{
Open_List.Remove(pt);
pt.father = nowPoint;
pt.G = G_new;
Open_List.Add(pt);
}
}
else //不在开启列表中
{
Point pt = new Point();
pt.x = xt;
pt.y = yt;
pt.father = nowPoint;
pt.G = pt.father.G + R[pt.x, pt.y];
pt.H = Math.Abs(pt.x - destination.x) + Math.Abs(pt.y - destination.y);
Open_List.Add(pt);
}
}
}
}
public void FindWay(Point startingPoint, Point destination, int power)
{
Open_List.Add(startingPoint);
while (!(IsInOpenList(destination.x, destination.y))) //当终点存在开启列表中就意味着寻路结束了
{
Point nowPoint = GetMinFFromOpenList();
Open_List.Remove(nowPoint);
Close_List.Add(nowPoint);
CheckGrid(nowPoint, startingPoint, destination);
}
Point p = GetPointFromOpenList(destination.x, destination.y);
List<Point> temp = new List<Point>();
while (p.father != null)
{
temp.Add(p);
p = p.father;
}
temp.Reverse();
foreach (Point pt in temp)
{
if (pt.G > power) break;
way.Add(pt);
}
}
public void PrintMap(Point startingPoint, Point destination)
{
for (int x = 0; x < 10; x++)
{
for (int y = 0; y < 10; y++)
{
if (x == startingPoint.x && y == startingPoint.y) Console.Write("▲");
else if (x == destination.x && y == destination.y) Console.Write("▲");
else if (Contains(x,y)) Console.Write("★");
else Console.Write("□");
}
Console.Write("\n");
}
}
private Boolean Contains(int x, int y)
{
foreach (Point p in way)
if (p.x == x && p.y == y) return true;
return false;
}
}
class Point
{
public Point() { }
public int G;
public int H;
public int x;
public int y;
public Point father;
}
}