`
wostyh
  • 浏览: 77210 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Silverlight 实现 A* 寻径算法

阅读更多

建议在新窗口中查看:
http://www.dotnet.pp.ru/silverlight/SilverlightAStar.html



花了几天的时间研究
A*算法,总算是搞出来了。放上来给大伙儿瞧瞧。

点击“StartPoint”指定开始点,点击“EndPoint”指定目标点。点击“Impediment”指定不可通过区域。

GridSize设置节点大小,节点越小,容器中的节点就越多,填好后点Set保存设置。

Clear清除所有。

StartFindPath 开始寻径

Completed Tim 显示寻径所耗时间。

Diagonals 设置是否可以斜着走。

自我感觉速度不错。

下面说说算法的大致流程

 

首先定义两个列表

        private List<PathNote> openedList = new List<PathNote>(); //开启列表

        private List<PathNote> colsedList = new List<PathNote>(); //关闭列表

开启列表中存储待检测节点。关闭列表中存储已检测节点。

 

从开始点开始,拿到开始点周围48个方向的节点,把他们添加进开启列表中。

G等于当前节点的父节点加上10或者14,水平或垂直方向加10,对角线方向加14

H等于当前节点的X的差与目标的的X的差、Y与目标点Y的差的绝对值的和。

 

F = G + H

把当前节点从开启列表中删除。并添加进关闭列表中。以“F”值为依据从小到大排序,把F值最小的节点拿出来,重复以上过程。

大致流程是这样的。细节方面已经有一篇文章写的非常详细,在此也没有必要赘述了。

传送门:http://data.gameres.com/message.asp?TopicID=25439


最后放上算法的代码,不多。直接以文本形式发出来算了。

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;

namespace SilverlightAStar
{
    public class PathNote
    {
        public int F; //F = G + H
        public int G;
        public int H;
        public int X;
        public int Y;
        public PathNote parentNote;
    }

    public class PathFinder
    {
        /// <summary>
        /// 矩阵
        /// </summary>
        private byte[,] matrix;
        /// <summary>
        /// 开始点
        /// </summary>
        private Point startPoint;
        /// <summary>
        /// 结束点
        /// </summary>
        private Point endPoint;
        /// <summary>
        /// 开启列表
        /// </summary>
        private List<PathNote> openedList = new List<PathNote>(); //开启列表
        /// <summary>
        /// 关闭列表
        /// </summary>
        private List<PathNote> colsedList = new List<PathNote>(); //关闭列表
        /// <summary>
        /// 是否允许斜线行走
        /// </summary>
        private bool diagonals;
        /// <summary>
        /// 方向
        /// </summary>
        private sbyte[,] direction = new sbyte[8, 2] { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 }, { 1, -1 }, { 1, 1 }, { -1, 1 }, { -1, -1 } }; //默认方向
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="matrix">待检测矩阵</param>
        /// <param name="startPoint">开始点</param>
        /// <param name="endPoint">结束点</param>
        public PathFinder(byte[,] matrix, Point startPoint, Point endPoint)
        {
            this.matrix = matrix;
            this.startPoint = startPoint;
            this.endPoint = endPoint;
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="matrix">矩阵</param>
        /// <param name="startPoint">开始点</param>
        /// <param name="endPoint">结束点</param>
        /// <param name="diagonals">是否允许斜线行走</param>
        public PathFinder(byte[,] matrix, Point startPoint, Point endPoint, bool diagonals)
        {
            this.matrix = matrix;
            this.startPoint = startPoint;
            this.endPoint = endPoint;
            this.diagonals = diagonals;
            if (!diagonals)
            {
                direction = new sbyte[4, 2] { { 0, -1 }, { 0, 1 }, { -1, 0 }, { 1, 0 } }; //不允许穿角,4方向
            }
        }
        /// <summary>
        /// 开始寻找路径
        /// </summary>
        /// <returns></returns>
        public List<Point> StartFindPath()
        {
            var found = false;
            var pathNote = new PathNote() { F = 0, G = 0, H = 0, X = (int)startPoint.X, Y = (int)startPoint.Y, parentNote = null };
            List<Point> resultPoints = null;
            while (true)
            {
                for (int i = 0; i < (diagonals ? 8 : 4); i++)  //找到pathNote四方向或八方向周围节点,取F值最小的那个继续此过程
                {
                    var x = pathNote.X + direction[i, 0];
                    var y = pathNote.Y + direction[i, 1];

                    if (x < 0 || y < 0 || x > matrix.GetUpperBound(0) || y > matrix.GetUpperBound(1)) //坐标过界
                        continue;

                    var newPathNote = new PathNote();
                    newPathNote.parentNote = pathNote;
                    newPathNote.X = x;
                    newPathNote.Y = y;

                    bool isClosed = false;
                    bool isOpened = false;
                    PathNote theOpendandSameNote = null;
                    foreach (var closedNote in colsedList)
                    {
                        if (closedNote.X == newPathNote.X && closedNote.Y == newPathNote.Y)
                        {
                            isClosed = true;  //节点已经在关闭列表中
                        }
                    }

                    foreach (var openedNote in openedList)
                    {
                        if (openedNote.X == newPathNote.X && openedNote.Y == newPathNote.Y)
                        {
                            isOpened = true; //节点已经在开启列表中,稍后比较两条路径
                            theOpendandSameNote = openedNote;
                        }
                    }

                    if (matrix[newPathNote.X, newPathNote.Y] != 0 || isClosed) //不能通行或者已经在关闭列表中存在
                        continue;

                    if (Math.Abs(direction[i, 0] + direction[i, 1]) == 2)  //G值
                    {
                        newPathNote.G = newPathNote.parentNote.G + 14;
                    }
                    else
                    {
                        newPathNote.G = newPathNote.parentNote.G + 10;
                    }

                    newPathNote.H = (int)(Math.Abs(endPoint.X - newPathNote.X) + Math.Abs(endPoint.Y - newPathNote.Y)) * 10;  //H值
                    newPathNote.F = newPathNote.G + newPathNote.H;  //F值


                    if (isOpened) //比较已在开启列表中的节点G值和准备创建的节点G值
                    {
                        if (newPathNote.G >= theOpendandSameNote.G)
                        {
                            this.openedList.Remove(pathNote);
                            continue;
                        }
                        else
                        {
                            this.openedList.Remove(theOpendandSameNote);
                            this.openedList.Add(newPathNote);
                            continue;
                        }
                    }

                    this.openedList.Add(newPathNote); //创建节点(添加进开启列表)
                }
                this.colsedList.Add(pathNote); //把当前节点放进关闭列表
                this.openedList.Remove(pathNote); //从开启列表移除当前节点
                foreach (var openedNote in openedList)
                {
                    if (openedNote.X == (int)endPoint.X && openedNote.Y == (int)endPoint.Y) // 到达终点
                    {
                        resultPoints = GetPointListByParent(openedNote, null); //得到以Point构成的路径
                        found = true;
                        break;
                    }
                }

                if (found)
                {
                    break;
                }
                else
                {
                    if (openedList.Count == 0)  //找不到路径
                    {
                        break;
                    }
                    else
                    {
                        openedList.Sort(Compare);
                        pathNote = openedList[0];
                    }
                }
            }
            return resultPoints;
        }

        /// <summary>
        /// 组织传入的PathNote的所有父节点为List
        /// </summary>
        /// <param name="pathNote">PathNote</param>
        /// <param name="pathPoints">列表</param>
        /// <returns>路径</returns>
        private List<Point> GetPointListByParent(PathNote pathNote, List<Point> pathPoints)
        {
            if (pathPoints == null)
                pathPoints = new List<Point>();
            if (pathNote.parentNote != null)
            {
                pathPoints.Add(new Point(pathNote.parentNote.X, pathNote.parentNote.Y));
                GetPointListByParent(pathNote.parentNote, pathPoints);
            }
            return pathPoints;
        }

        /// <summary>
        /// 比较两个节点的F值
        /// </summary>
        /// <param name="x">第一个节点</param>
        /// <param name="y">第二个节点</param>
        /// <returns></returns>
        private int Compare(PathNote x, PathNote y)
        {
            if (x.F > y.F)
                return 1;
            else if (x.F < y.F)
                return -1;
            return 0;
        }
    }
}

 

 

文章出处:http://www.cnblogs.com/zhubenwuzui/archive/2009/09/18/1569534.html 猪笨无罪的博客

分享到:
评论

相关推荐

    共享Silverlight版A路径寻径算法包

    本资源“共享Silverlight版A*路径寻径算法包”提供了在Silverlight环境中实现A*(A-Star)算法的解决方案。A*算法是一种广泛应用的启发式搜索算法,以其高效性和准确性著称,它在寻找两点间的最短路径时,结合了...

    A*寻路算法(silverlight实现)

    总的来说,A*寻路算法在Silverlight中的实现是一个集成了算法理论与实践操作的案例,对学习者来说具有很高的参考价值,可以帮助他们掌握路径规划的基本原理,并能将其应用到各种实际问题中,如迷宫求解、游戏AI路径...

    Silverlight.4 and SharePoint 2010

    将 **Silverlight 4** 与 **SharePoint 2010** 结合使用,可以显著增强企业应用的功能性和用户体验,实现更高级的数据可视化、用户界面设计及更复杂的应用逻辑。 #### 二、Silverlight 4 和 SharePoint 2010 的集成...

    Silverlight入门

    - **什么是Silverlight**:Silverlight是一种浏览器插件,它可以增强网页的媒体播放、图形展示和用户交互功能。 - **目标平台**:Silverlight支持多种操作系统和浏览器,包括Windows、Mac OS以及主流的Web浏览器。 -...

    A星算法_自动寻路_silverlight

    在Silverlight中实现A星算法,通常涉及到以下几个步骤: 1. **建立网格**:将地图划分为可行走的格子,每个格子代表一个节点,记录其邻居节点。 2. **定义代价函数**:确定每移动一格的成本,如平坦地面与障碍物的...

    C#开发WPFSilverlight动画及游戏系列教程(Game Tutorial)

    接着,教程⑦介绍了A*寻径算法,这是一种高效的路径规划方法,用于解决游戏中的智能体如何在复杂环境中找到最优路径的问题。 第⑧和⑨章则深入到A*寻径算法的动态应用,展示了如何将寻径结果实时转化为动画效果,使...

    silverlight(资料)

    **Silverlight技术详解** Silverlight是由微软开发的一种插件技术,用于在Web浏览器中呈现丰富的媒体和交互式应用程序。这项技术在2007年首次发布,旨在与Adobe的Flash平台竞争,提供跨平台、跨浏览器的多媒体和...

    关于silverlight的书

    5. **数据访问**:介绍如何在Silverlight应用中实现数据绑定,使用ADO.NET Entity Framework或其他数据访问技术来与数据库交互。 6. **Silverlight控件**:详述Silverlight提供的各种内置控件,如按钮、文本框、...

    silverlight 简单例子

    Silverlight在2007年首次发布,目的是与Adobe Flash竞争,提供一种跨浏览器、跨平台的插件来实现高质量的多媒体播放和交互性应用。虽然Silverlight在早期受到了一定的关注,但随着HTML5的兴起和微软的策略调整,...

    silverlight源码

    在深入研究这些源码时,我们可以学习到如何设计和实现Silverlight应用,以及如何利用其特性提升Web应用的交互性和性能。通过对这些源码的解构和学习,开发者能够更好地理解和运用Silverlight技术,为自己的项目增添...

    Silverlight

    **Microsoft Silverlight** 是一种由微软公司开发的跨浏览器、跨平台的插件,主要用于增强Web应用程序的多媒体体验。它在2007年首次发布,版本为1.0,标志着微软进入富互联网应用程序(RIA)领域的尝试,与Adobe ...

    silverlight 资料及其code

    - **OData支持**:Silverlight可以利用OData协议与Web服务进行数据交换,实现前后端的交互。 - **离线应用**:通过结合Silverlight Out-of-Browser(OOB)功能,可以创建能在本地运行的离线应用程序。 通过深入...

    Silverlight实现的多图片列表框

    【标题】"Silverlight实现的多图片列表框"是一个基于微软的Silverlight技术构建的应用示例,它展示了如何在Silverlight应用中展示多个图片,并以列表框的形式进行展示。这个项目可能是一个用户界面组件,用于在Web...

    Silverlight3_Tools.exe下载

    4. **深度集成数据绑定**:Silverlight 3增强了数据绑定机制,使开发者能更容易地将数据与UI元素关联,实现数据驱动的用户界面。 5. **强大的文本渲染**:引入了新的文本引擎,提供了更好的字体渲染和文本排版,...

    Silverlight.DataSet

    首先,我们来了解一下**Silverlight**。Silverlight是微软推出的一种RIA(Rich Internet Application)技术,它提供了一种创建具有丰富媒体体验和交互式用户界面的Web应用程序的方式。通过XAML(Extensible ...

    silverlight寻光之旅 源代码

    源代码中包含的“silverlight寻光之旅”很可能涵盖上述各个知识点的具体实现,通过阅读和分析这些代码,开发者能够深入理解Silverlight的各种特性和应用场景,并从中学习如何构建高效、互动的Web应用。

    SilverLight如何安装

    **Silverlight介绍** Silverlight是由微软开发的一种富互联网应用程序(RIA)平台,它主要用于构建和展示具有丰富媒体体验和交互式用户界面的Web应用。Silverlight支持多媒体、动画、图形和交互式功能,广泛应用于...

    ArcGIS RIA开发讲座 for Silverlight API.pdf

    **Silverlight** 是微软推出的一种跨浏览器的富互联网应用程序(RIA)框架,旨在为 Web 开发者提供一个强大的平台来创建具有高度交互性的用户界面。自2007年9月首次发布以来,Silverlight 不断发展和完善,为开发者...

    Silverlight教程.zip

    - **数据绑定和数据服务**:Silverlight支持WCF(Windows Communication Foundation)服务,可以方便地与Web服务进行交互,实现数据的获取和提交。 - **AJAX集成**:可以与现有的ASP.NET AJAX应用程序集成,提供更...

Global site tag (gtag.js) - Google Analytics