玩过即时战略,RPG等类型的游戏的朋友一定会知道,当我们用鼠标选取某些单位并命令其到达地图上确定的位置时,这些单位总是可以自动的选择最短的路径到达。这个时候我们就会联想到大名鼎鼎的A*寻路算法,下文简略介绍算法实现原理,并附上C#实现方法。

算法原理请见:http://data.gameres.com/message.asp?TopicID=25439

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace ConsoleApplication2
{
class Program
{

static void Main(string[] args)
{

test mytest = new test();

//定义出发位置
Point pa = new Point();
pa.x = 1;
pa.y = 1;

//定义目的地
Point pb = new Point();
pb.x = 8;
pb.y = 8;

mytest.FindWay(pa, pb);

mytest.PrintMap();
Console.ReadLine();
}
}
class test
{

//数组用1表示可通过,0表示障碍物
byte[,] R = new byte[10, 10] {
{ 1, 1, 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, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }

};

//开启列表
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 IsBar(Point p, byte[,] map)
{
if (map[p.y, p.x] == 0) return true;
return false;
}

//判断关闭列表是否包含一个坐标的点
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 Point GetPointFromCloseList(int x, int y)
{
foreach (Point p in Close_List) if (p.x == x && p.y == y) return p;
return null;
}

//判断开启列表是否包含一个坐标的点
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;
}

//计算某个点的G值
private 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;
}

//计算某个点的H值
private int GetH(Point p, Point pb)
{
return Math.Abs(p.x - pb.x) + Math.Abs(p.y - pb.y);
}

//检查当前节点附近的节点
private void CheckP8(Point p0, byte[,] map, Point pa, ref Point pb)
{
for (int xt = p0.x - 1; xt <= p0.x + 1; xt++)
{
for (int yt = p0.y - 1; yt <= p0.y + 1; yt++)
{
//排除超过边界和等于自身的点
if ((xt >= 0 && xt < 10 && yt >= 0 && yt < 10) && !(xt == p0.x && yt == p0.y))
{
//排除障碍点和关闭列表中的点
if (map[yt, xt] != 0 && !IsInCloseList(xt, yt))
{
if (IsInOpenList(xt, yt))
{
Point pt = GetPointFromOpenList(xt, yt);
int G_new = 0;
if (p0.x == pt.x || p0.y == pt.y) G_new = p0.G + 10;
else G_new = p0.G + 14;
if (G_new < pt.G)
{
Open_List.Remove(pt);
pt.father = p0;
pt.G = G_new;
Open_List.Add(pt);
}
}
else
{
//不在开启列表中
Point pt = new Point();
pt.x = xt;
pt.y = yt;
pt.father = p0;
pt.G = GetG(pt);
pt.H = GetH(pt, pb);
Open_List.Add(pt);
}
}
}
}
}
}

public void FindWay(Point pa, Point pb)
{

Open_List.Add(pa);
while (!(IsInOpenList(pb.x, pb.y) || Open_List.Count == 0))
{
Point p0 = GetMinFFromOpenList();
if (p0 == null) return;
Open_List.Remove(p0);
Close_List.Add(p0);
CheckP8(p0, R, pa, ref pb);
}

Point p = GetPointFromOpenList(pb.x, pb.y);
while (p.father != null)
{
p = p.father;
R[p.y, p.x] = 3;
}

}

public void SaveWay( Point pb)
{

Point p = pb;
while (p.father != null)
{
p = p.father;
R[p.y, p.x] = 3;
}
}

public void PrintMap()
{

for (int a = 0; a < 10; a++)
{
for (int b = 0; b < 10; b++)
{
if (R[a, b] == 1) Console.Write("█");
else if (R[a, b] == 3) Console.Write("★");
else if (R[a, b] == 4) Console.Write("○");

else Console.Write(" ");
}
Console.Write("\n");
}

}

}

class Point
{
public int y;
public int x;
public int G;
public int H;

public Point()
{
}
public Point(int x0, int y0, int G0, int H0, Point F)
{
x = x0;
y = y0;
G = G0;
H = H0;
father = F;
}

public Point father;
}

}

转载于:https://www.cnblogs.com/lipan/archive/2010/07/01/1769420.html

A*寻路算法基于C#实现相关推荐

  1. 【Android】基于A星寻路算法的简单迷宫应用

    简介 基于[漫画算法-小灰的算法之旅]上的A星寻路算法,开发的一个Demo.目前实现后退.重新载入.路径提示.地图刷新等功能.没有做太多的性能优化,算是深化对A星寻路算法的理解. 界面预览: 初始化: ...

  2. 基于STL实现自动贪心寻路算法的贪吃蛇小游戏

    基于STL实现自动贪心寻路算法的贪吃蛇小游戏 写贪吃蛇小游戏的想法来自CometOJ-Contest#13的B题,当时用STL双端队列维护蛇身的时候觉得非常方便,现在用EasyX图形库实现一下. 运行 ...

  3. A*寻路算法的探寻与改良(三)

    A*寻路算法的探寻与改良(三) by:田宇轩                                        第三分:这部分内容基于树.查找算法等对A*算法的执行效率进行了改良,想了解细 ...

  4. 光速AStar寻路算法(C++)

    光速AStar寻路算法(C++) 一.最终效果 可以看到,我创建了500个小动物,也有110的FPS.虽然它们并不是每一帧都在计算寻路,但是平均下来不卡顿也不错了.我是i7 6700 + GT 720 ...

  5. 寻路算法实例解析:贪吃蛇AI的实现

    本文是寻路算法的实际应用篇,以贪吃蛇的实现为例子. 1.首先看下这个在微博上很火的贪吃蛇gif 这次我们尝试用代码来模拟下,说不定上面这个图就是计算机搞的. 2.讲贪吃蛇snake AI之前,我们先看 ...

  6. 游戏中常用的寻路算法(5)预先计算好的路径的所用空间

    有时候,影响计算寻路路径的不是时间,而是计算路径所需的上百个单元格所占的空间.寻路是需要内存来运行寻路算法,还需要额外内存来存储寻到的路径.运行寻路算法(A*,开集或闭集)所需的临时空间经常会比存储这 ...

  7. 游戏中常用的寻路算法(6):地图表示

    在本系列文档大部分内容中,我都假设A*用于某种网格上,其中的"节点"是一个个网格的位置,"边"是从某个网格位置出发的各个方向.然而,A*可用于任意图形,不仅仅是 ...

  8. 如何快速找到最优路线?深入理解游戏中寻路算法

    如果你玩过MMOARPG游戏,比如魔兽,你会发现人物行走会很有趣,为了模仿人物行走的真实体验,他们会选择最近路线达到目的地,期间会避开高山或者湖水,绕过箱子或者树林,直到走到你所选定的目的地. 这种看 ...

  9. 关于寻路算法的一些思考(6):预先计算好的路径的所用空间

    有时候,影响计算寻路路径的不是时间,而是计算路径所需的上百个单元格所占的空间.寻路是需要内存来运行寻路算法,还需要额外内存来存储寻到的路径.运行寻路算法(A*,开集或闭集)所需的临时空间经常会比存储这 ...

最新文章

  1. ubuntu 默认鼠标双击问题
  2. symfony的安装方法
  3. mac catalina删除系统多余文件 内存不足_macOS Catalina Patcher(如何在旧mac上安装Catalina系统)...
  4. Ant Design入门之开始使用
  5. Java High CPU故障排除指南–第1部分
  6. THINKPAD T420(4180J4C)还是THINKPAD T420(4180PLC)好?
  7. 查看服务器的性能和使用状态(top,free,df)
  8. python列表用什么符号表示_python列表类型
  9. 原生的APP、小程序(微信小程序、支付宝小程序、头条小程序、百度小程序.等等)、H5 的优势与劣势分析有那些?
  10. ThreatScan-免费的网站在线安全检测平台_TScan
  11. Beego-HelloWorld
  12. acpc2013 G. The Stones Game (思维)
  13. 测角误差估计算法matlab,Harris角点检测 及 Matlab实验
  14. 后台管理----首页布局分析1
  15. 罗杨老师带你了解谷歌编程之夏(GSoC)活动全流程
  16. Robust Consistent Video Depth Estimation_具有鲁棒一致性的视频深度估计
  17. 记一次APP去壳破解重新打包
  18. 新手上路:什么是API接口
  19. Ubuntu软件仓库源类型:官方源、第三方源、本地源
  20. 5年内的暴风骤雨:12诱因统领软件行业大革命【转载】

热门文章

  1. java 封装dll_java调用C#封装的DLL文件
  2. textview 背景变形_嘉兴海宁市家庭别墅背景墙装修供应——零度木门厂家
  3. SGD、Adam优化器
  4. 注释可以出现在c语言任何位置,在c程序中,注释语句只能位于一条语句的后面吗...
  5. 战斗服务器响应超时是否尝试重连,刺激战场:教你,从开伞到落地瞬间技巧
  6. 机器学习--python代码实现基于Fisher的线性判别(鸢尾花数据集的分类)
  7. linun开启oracle监听,Linux下配置Oracle监听器
  8. 输入日期java_java怎么格式化输入日期
  9. Blog主场转至51CTO.com
  10. virtualbox谨记:续....