精华内容
下载资源
问答
  • gif动画演示(让圣诞老人给阿拉蕾送礼物,多么绝妙的想法呀,把自己感动坏啦): 印刷电路板将布线区域划分成n×n个方格阵列,...这个问题和寻路问题很像,要从一点到达另一点,其间有很多的障碍,目的是要找出最短...

    gif动画演示(让圣诞老人给阿拉蕾送礼物,多么绝妙的想法呀,把自己感动坏啦):

    印刷电路板将布线区域划分成n×n个方格阵列,精确的电路布线问题要求确定连接方格a的中点到方格b的中点的最短布线方案。

    在布线时,电路只能沿直线或直角布线。为了避免线路相交,已布了线的方格做了封锁标记,其他线路不允许穿过封锁的方格。

    这个问题和寻路问题很像,要从一点到达另一点,其间有很多的障碍,目的是要找出最短的路径。

    全部功能采用Matlab编写,程序的功能是寻找从出发点到目的地的全部可行路径,最后只显示了最佳和最劣路径的动画效果,

    对每一步的移动进行了动画演示。

    完整代码下载地址:  CSDN资源下载

     

     

    展开全文
  • 2.智能无人行驶,在用户不操控的情况下自动行驶,智能车会自动寻路,避障,同时采集信息视频等信息,并发回手机APP终端。 3.智能小车采用 s3c2440 ARM9主控芯片,运行linux操作系统,系统主频405MHz,LCD、电机、...
  • 该网站可用于可视化多种算法,包括排序,寻路和ConvexHull。 您可以在这里访问它: : 演算法 排序 选择排序 合并排序 快速排序 寻找路径 Dijkstra的算法 凸包 格雷厄姆的扫描 安装 在计算机上安装Node 从克隆此...
  • A*寻路算法

    千次阅读 2016-03-05 17:33:26
    应用场景:游戏里的自动寻路 原理: 1,从起点开始找它周围可以走的格子,算出可走格子中F值最小的格子,再就以这个格子作为新的中心点,又同样找其周围可以走的格子,以此类推,直至找到目的点。 2,确定最优...

    实现原理

    算法名称:A*算法
    应用场景:游戏里的自动寻路
    原理:
    1,从起点开始找它周围可以走的格子,算出可走格子中F值最小的格子,再就以这个格子作为新的中心点,又同样找其周围可以走的格子,以此类推,直至找到目的点。
    2,确定最优格子是取F值最小为依据,那么F值怎么算?F = G + H,G:表示从起点移动到指定格子的耗费(一般横竖着的格子耗费为10(or 1),斜着的格子耗费为14(or 1.4),等于其父节点G + 自己的G的和)。H:表示从指定格子移动到终点的预计耗费(一般就是指定点到终点相差的X,Y绝对值的和)。
    3,每次找的周围格子都会放入到“开放列表”中,如果下次周围点某几个“开放列表”中已经存在,是否修改这些存在的点属性,是看新计算的G值,如果G值 > 原来的G值,则什么也不做,否则,就以新的G值替换,同时改变其父节点。
    4,每个格子都以其中心点作为父节点,这样链接起来,就像一个链表结构,这样直到找到目的点后,就可以通过目的点的父节点这样一级级还原出路径了。
    5,每个格子的属性:x坐标,y坐标,G值,H值,F值(F=G + H),父格子。(这种结构类似链表)

    寻路步骤

    1,从起点A开始, 把它作为待处理的方格存入一个”开启列表”, 开启列表就是一个等待检查方格的列表.
    2,寻找起点A周围可以到达的方格, 将它们放入”开启列表”, 并设置它们的”父方格”为A.
    3,从”开启列表”中删除起点 A, 并将起点 A 加入”关闭列表”, “关闭列表”中存放的都是不需要再次检查的方格.
    4, 从 “开启列表” 中选择 F 值最低的方格C.
    5,把它从 “开启列表” 中删除, 并放到 “关闭列表” 中.
    6,检查它所有相邻并且可以到达 (障碍物和 “关闭列表” 的方格都不考虑) 的方格. 如果这些方格还不在 “开启列表” 里的话, 将它们加入 “开启列表”, 计算这些方格的 G, H 和 F 值各是多少, 并设置它们的 “父方格”为C .
    7, 如果某个相邻方格 D 已经在 “开启列表” 里了, 检查如果用新的路径 (就是经过C 的路径) 到达它的话, G值是否会更低一些, 如果新的G值更低, 那就把它的 “父方格” 改为目前选中的方格 C, 然后重新计算它的 F 值和 G 值 (H 值不需要重新计算, 因为对于每个方块, H 值是不变的). 如果新的 G 值比较高, 就说明经过 C 再到达 D 不是一个明智的选择, 因为它需要更远的路, 这时我们什么也不做.
    8,然后继续找F值最小的,如此循环下去…

    下面是一张寻路的示例图:绿块是起点,蓝块是障碍,红块是终点,天蓝框是中心点,绿框是检测过的点,框左上角F值,框左下角是G值,框右下角是H值,红线是寻路过程。
    这里写图片描述

    最终通过父节点还原路径,如下图:(红点表示最终路径)
    这里写图片描述

    示例代码(Lua)

    这个是项目中的源码,寻路核心就是用的上面讲的A*算法。
    1,格子点结构定义(Node)

    local Point                         = class("Point")
    
    function Point:ctor(pos)
        self.parentPoint                = nil
        self.F                          = 0
        self.G                          = 0
        self.H                          = 0
        self.x                          = pos.x            
        self.y                          = pos.y       
    end
    
    --计算F值
    function Point:CalcF( point )
        self.F                          = self.G + self.H
    end
    
    return Point
    

    2,A*寻路类

    local FindPath                      = class("FindPath")
    
    function FindPath:ctor()
        --路径列表
        self.pathArry                   = {}
    end
    
    --获取列表中F值最小的点
    function FindPath:getMinPoint(pointList)
        local minPoint                  = pointList[1]
        for i = 1, table.getn(pointList) do
            if minPoint.F > pointList[i].F then
                minPoint                = pointList[i]
            end
        end
        return minPoint
    end
    
    --从开启列表移除点
    function FindPath:removePoint(point, pointList)
        if table.getn(pointList) <= 0 then
            return
        end
    
        for i=table.getn(pointList), 1, -1 do
            if pointList[i].x == point.x and pointList[i].y == point.y then
                table.remove(pointList, i)
            end
        end
    end
    
    --列表中是否包含点
    function FindPath:existPoint(pointList, point)
        for i, p in pairs(pointList) do
            if (p.x == point.x) and (p.y == point.y) then
                return i
            end
        end
        return false
    end
    
    --获取相邻的点
    function FindPath:getSurroundPoints(point)
        local surroundPoints            = {}
        for i=point.x - 1, point.x + 1 do
    
            for j=point.y - 1, point.y + 1 do
                if i == point.x and j == point.y then
                    --点自己
                elseif not self:existPoint(self.closeList, cc.p(i, j)) then
                    if mapLayer:isObstacleByTile(cc.p(i, j)) then
                        --障碍
                    else
                        local tPos  = require("app.control.Point").new(cc.p(i, j))
                        local dPos  = self.endPos
                        if i == point.x or j == point.y then
                            tPos.G  = 1
                        else
                            tPos.G  = 1.4 
                        end
                        tPos.H  = math.abs(dPos.x-tPos.x) + math.abs(dPos.y-tPos.y)
                        tPos.parentPoint    = point
                        table.insert(surroundPoints, tPos)
                    end
                end
            end
    
        end
    
        return surroundPoints   --返回point点的集合
    end
    
    --计算G值
    function FindPath:CalcG(point)
        local G                         = point.G
        local parentG                   = 0
        if point.parentPoint then
            parentG                     = point.parentPoint.G
        end
        return G + parentG
    end
    
    function FindPath:foundPoint(tempStart, point, idx)
        local lastP                     = self.openList[idx]
        local G                         = self:CalcG(point)
        if G < lastP.G then
            point.parentPoint           = tempStart
            point.G                     = G
            point:CalcF()
            self.openList[idx]          = point
        end
    end
    
    function FindPath:notFoundPoint(tempStart, point)
        point.parentPoint               = tempStart
        point.G                         = self:CalcG(point)
        point:CalcF()
        table.insert(self.openList, point)
    end
    
    --获得角色真实位置(移动一格完成后的位置)
    function FindPath:getRoleRealPos()
        local curPos                    = nil
        if self.roleTgtPos then
            curPos                      = self.roleTgtPos
        else
            --角色位置
            local x, y                  = myRole:getPosition()
            curPos                      = cc.p(x, y)
        end
    
        return mapLayer:tileCoordForPos(curPos)
    end
    
    --开始寻找路径
    function FindPath:startFindPath(endPos)
        local startPos                  = self:getRoleRealPos()
        if endPos.x == startPos.x and endPos.y == startPos.y then
            printInfo("click same point")
            return false
        end
        --print("startPos:", startPos.x, startPos.y)
        --print("endPos:", endPos.x, endPos.y)
    
    
        --初始化值
        self.openList                   = {}
        self.closeList                  = {}
        self.pathArry                   = {}
        local findPos                   = nil
        local isFind                    = true
        startPos                        = require("app.control.Point").new(startPos)
        self.endPos                     = require("app.control.Point").new(endPos)
    
        table.insert(self.openList, startPos)
        --寻路逻辑
        while table.getn(self.openList) > 0 do
            --找出F的最小值
            local tempStart             = self:getMinPoint(self.openList)
            self:removePoint(tempStart, self.openList)
            table.insert(self.closeList, tempStart)
    
            --找出它相邻的点
            local surroundPoints        = self:getSurroundPoints(tempStart)
            for i,point in pairs(surroundPoints) do
                local idx               = self:existPoint(self.openList, point)
                if idx then
                    --计算G值,如果比原来大,就什么都不做,否则设置他的父节点为当前节点,并更新G和F
                    self:foundPoint(tempStart, point, idx)
                else
                    --如果他们不再开始列表里面,就加入,并设置父节点,并计算GHF
                    self:notFoundPoint(tempStart, point)
                end
            end
    
            --如果最后一个存在则返回
            local idx                   = self:existPoint(self.openList, self.endPos)
            if idx then 
                findPos                 = self.openList[idx]
                break
            end
        end
    
        --添加路径
        --printInfo("find path")
        while findPos do
            --转换为地图坐标
            --printInfo("%d, %d", findPos.x, findPos.y)
            local tempPos               = mapLayer:posForTileGood(findPos)
            --printInfo("%d, %d", tempPos.x, tempPos.y)
            table.insert(self.pathArry, tempPos)
            findPos                     = findPos.parentPoint
        end
    
        if table.getn(self.pathArry) < 2 then
            isFind                      = false
        end             
    
        --重置
        self.openList                   = {}
        self.closeList                  = {}
        self.endPos                     = nil
        findPos                         = nil
        return isFind
    end
    
    --获取移动的偏移
    function FindPath:getMoveOffset()
        local num                       = table.getn(self.pathArry)
        if num < 2 then
            self:removePath()
            return false
        end
    
        local curPos                    = self.pathArry[num]
        local targetPos                 = self.pathArry[num - 1]
        table.remove(self.pathArry, num)
    
        local sPos                      = cc.pSub(curPos, targetPos)
        local angle                     = math.atan2(sPos.y, sPos.x) * 180 / math.pi + 180
    
        local direct                    = camera:getDirectionByAngle(angle)
        myRole:changeAction(actionList.run, direct)
    
        return cc.pMul(sPos, -1)
    end
    
    --移除路径
    function FindPath:removePath()
        self.pathArry                   = {}
    end
    
    --设置角色目标位置
    function FindPath:setRolePos(pos)
        self.roleTgtPos                 = pos
    end
    
    --获取当前路径
    function FindPath:getCurPath()
        return self.pathArry            
    end
    
    return FindPath
    

    项目运行示例图:
    这里写图片描述

    这里写图片描述

    展开全文
  • Create React App入门 该项目是通过引导的。 可用脚本 在项目目录中,可以运行: yarn start 在开发模式下运行该应用程序。 打开在浏览器中查看它。 如果您进行编辑,则页面将重新加载。 您还将在控制台中看到任何...
  • 迷宫寻路算法

    2020-02-25 23:31:07
    在Unity3d的一些2d游戏制作上,有时需要敌人在众多箱子(障碍物)中向主角移动,如果是简单的移动ai代码实现,敌人有可能...您还可以下载 CSDN 旗下精品原创内容社区 GitChat App ,阅读更多 GitChat 专享技术内容哦。

    在Unity3d的一些2d游戏制作上,有时需要敌人在众多箱子(障碍物)中向主角移动,如果是简单的移动ai代码实现,敌人有可能陷入死胡同然后左右移动,卡死在胡同上,为了一个智能的ai实现,比较常用的是A*算法,但这里为了简便,我们使用了深度搜索的方式进行判断。所谓深度搜索,一位博主总结得很好,就是“不见棺材不回头。算法会朝一个方向进发,直到遇到边界或者障碍物,才回溯。一般在实现的时候,我们采用递归的方式来进行,也可以采用模拟压栈的方式来实现。”

    这里给大家介绍一种用c#写的代码算法,希望能帮到大家

    阅读全文: http://gitbook.cn/gitchat/activity/5e54fe92e577af7e239ba463

    您还可以下载 CSDN 旗下精品原创内容社区 GitChat App ,阅读更多 GitChat 专享技术内容哦。

    FtooAtPSkEJwnW-9xkCLqSTRpBKX

    展开全文
  • 文章目录一、本篇目的二、开发环境三、简介四、程序结构五、寻路库的使用1、库添加到引用2、例子13、例子24、例子3六、使用`Excel`画地形图 一、本篇目的 学习了A*寻路基础之后,发现源码下载不了了,自己实现一下,...

    一、本篇目的

    学习了A*寻路基础之后,发现源码下载不了了,自己实现一下,并做一些扩展记录以及测试。

    本文所述完整源代码在这里下载

    二、开发环境

    • VS2017 C#

    三、简介

    关于A*寻路,这篇文章说得很清楚:A* Pathfinding for Beginners

    有人翻译成中文了,中文可以看这个:A*寻路入门

    这篇文章说得很清楚,想调试源代码加深理解,但是文档中提供的源码怎么都下不来了,就萌生了自己编程实现的想法。

    四、程序结构

    程序结构大体如下图所示:

    PathFinding +Terrain Terrain -MovePattern movePattern +FindPath() Terrain +Set() +SetXXX() MovePattern +MovablePositions() +NodeGValue() +NodeHValue() +NodeFValue() NormalMovePattern // 普通的移动样式 RiMovePattern // 马走日的移动样式

    寻路类PathFinding需要针对不同的地形寻路,移动方式不同也会影响寻路结果。比如沙地比较难移动,那么可以设置地形的沙地位置基本移动力大一点,爬山和下山消耗移动力也会不一样的,所以地形在不同高度差的位置之间移动会影响寻路消耗的移动力,地形的这些性质在地形类Terrain来设置。

    注意地形以左下角为原点,往右列号递增,往上行号递增。

    移动时一般是移动到相邻的位置,但是有些项目(或者游戏,或者数学题目)是走别的形状的,比如马走日字。所以引入MovePattern类,并根据具体的移动样式不同,衍生出子类,比如源码考虑了普通移动样式类NormalMovePattern和马走日的移动样式类,要增加别的样式,继承MovePattern,实现自己的移动样式子类就可以了。

    具体的实现代码注释很清晰了,看懂了简介中的文章,很容易能看懂源码和注释,本文不赘述。

    源码AStartPathFinding项目,是寻路的库,编译后,结果是库文件AStarPathFinding.dll

    后面描述如何使用这个库解决寻路的问题。

    五、寻路库的使用

    1、库添加到引用

    新建一个c#项目,叫AStarPathFindingDemo,把AStarPathFinding.dll加入到引用中。如下图,添加引用,浏览选取这个库文件,保证这个库文件被勾选了,确定就行了。

    添加引用

    2、例子1

    第1个先用简介中的图做例子:

    例子1

    文章答案给的是如下图:

    行动力,斜线消耗14行动力来计算,是2步斜线,4步直线,共消耗68行动力。答案不是唯一的,比如从上方走也是一个答案,最终判定是消耗的行动力。

    下面是使用的代码。

    如图所示,地形是5行、7列的,先设置地形,代码如下:

    /// <summary>
    /// 测试5行,7列的如下图的寻路,左下角坐标是(0, 0)
    /// X X X X X X X
    /// X X X 1 X X X
    /// X S X 1 X E X
    /// X X X 1 X X X
    /// X X X X X X X
    /// 如上如,S为起点,E为终点,中间的1表示不可以立足也不能跃过(即墙)
    /// </summary>
    static private Terrain SetExam1Terrain()
    {
        /* 先设置地形,没有高度差,高度全为0 */
        Terrain terrain = new Terrain();
        terrain.Set(7, 5);
        terrain.SetColumnMovableType(3, 1, 3, MovableType.NotStandonNotAcross);
        return terrain;
    }
    

    地形宽为7,高为5,不考虑每个位置的高度的话,高度全是0,不需要设置,所以使用terrain.Set(7, 5)来设置宽高,第4列的第2-4行是墙,既不可以立足,也不可以被跃过的地形,使用terrain.SetColumnMovableType(3, 1, 3, MovableType.NotStandonNotAcross)来设置,其中第一个参数3表示第4列(从0开始算,序号是3),第2给参数1表示第2行(从0开始算,序号是1),第3个参数3表示第4行,即设置第4列的行[1, 3]的可移动类型为MovableType.NotStandonNotAcross,即不可以立足,也不可以跃过。

    接着就是寻路,代码如下:

    static private void Exam1()
    {
        /* 设置地形 */
        Terrain terrain = SetExam1Terrain();
    
        PathFinding pathFinding = new PathFinding();
        List<Node> bestPath = null;
        int action = 0;
        pathFinding.Terrain = terrain;
        if (pathFinding.FindPath(1, 2, 5, 2, out bestPath, out action))
        {
            /* 找到路径,打印 */
            ShowBestPath(bestPath, action);
        }
        else
        {
            /* 找不到路径 */
            Console.WriteLine("Not found path!");
        }
    }
    

    先设置好地形,然后传入给FindPath方法,这个方法前两个参数就是起始位置的坐标,即(1, 2),接着是终点的坐标(5, 2)。然后返回结果并打印出来。结果如下:

    Found path:
    (1, 2) -> (1, 3) -> (2, 4) -> (3, 4) -> (4, 4) -> (4, 3) -> (5, 2)
    Action: 68
    

    答案是6步,消耗行动力68。答案路径如下图;

    和简介的文章答案不同,但是结果是对的,都是行动力68,2步斜线,4步直线

    3、例子2

    这个例子题目源于某小学生的课程中题目,如下图:

    骑士走的日字,问骑士几步就能拿到宝物?

    答案很明显是4步。假设马走日一步的行动力按照基本斜线来算14,那就是56的行动力。

    程序如下:

    设置地形:

    /// <summary>
    /// 测试日字步
    /// 测试4行6列的,S点是骑士,E点是宝物,骑士最少几步拿到宝物,如下图
    /// E X X X X X
    /// X X X X X X
    /// X X X X X X
    /// X X X X X S
    /// </summary>
    static private Terrain SetExam2Terrain()
    {
        /* 先设置地形,没有高度差,高度全为0 */
        Terrain terrain = new Terrain();
        terrain.Set(6, 4);
        return terrain;
    }
    

    地形就是6x4的,没什么特别。

    寻路代码是:

    static private void Exam2()
    {
        /* 先设置地形,没有高度差,高度全为0 */
        Terrain terrain = SetExam2Terrain();
    
        PathFinding pathFinding = new PathFinding();
        List<Node> bestPath = null;
        int action = 0;
        pathFinding.Terrain = terrain;
        if (pathFinding.FindPath(5, 0, 0, 3, out bestPath, out action, MoveType.RiMove))
        {
            /* 找到路径,打印 */
            ShowBestPath(bestPath, action);
        }
        else
        {
            /* 找不到路径 */
            Console.WriteLine("Not found path!");
        }
    }
    

    和例子1一样,就是先设置地形,然后传入起点、终点坐标寻路,不同的是最后的一个参数传入了MoveType.RiMove,表示移动类型是日字步。

    最后结果是:

    Found path:
    (5, 0) -> (3, 1) -> (2, 3) -> (1, 1) -> (0, 3)
    Action: 56
    

    路径画到图里和这个学生做题的答案有些不一样,但是很明显,结果也是对的。

    最后来个比上面稍微复杂点的应用。

    4、例子3

    也是来自小学生的数学题,如下图:

    骑士走的日字,骑士最少能用几步拿到两件宝物?

    应该没有比8步更好的答案了。

    地形和上面的有些不同,空白的位置是可以跃过去的,但是空白的位置是不可以立足的位置。比如图示的骑士起始的位置的左边几格都是空白,但是不影响骑士跃到标了1的位置,但是骑士却不可以跃到空白的位置去,那怕是日字的走法。

    所以这个题目地形设置有些复杂,代码如下:

    /// <summary>
    /// 测试日字步
    /// 测试9行10列的,S点是骑士,E点是宝物有2个,骑士最少几步拿到2个宝物,如下图:
    /// 2表示不可以立足,但是可以跃过的位置
    /// 2 2 2 2 2 2 2 2 X 2
    /// 2 X X X 2 2 2 X 2 2
    /// 2 X 2 X 2 2 2 2 X X
    /// 2 X X E 2 X 2 2 X 2
    /// 2 2 2 2 2 2 2 2 X 2
    /// X X 2 2 X X X 2 X 2
    /// 2 2 X 2 X 2 X 2 X 2
    /// E 2 X 2 2 X X X X X
    /// 2 2 2 2 2 2 2 2 S 2
    /// </summary>
    static private Terrain SetTest3Terrain()
    {
        Terrain terrain = new Terrain();
        terrain.Set(10, 9);
        terrain.SetPointMovableType(0, 0, MovableType.NotStandonAcross);
        terrain.SetPointMovableType(0, 2, MovableType.NotStandonAcross);
        terrain.SetColumnMovableType(0, 4, 8, MovableType.NotStandonAcross);
        terrain.SetColumnMovableType(1, 0, 2, MovableType.NotStandonAcross);
        terrain.SetPointMovableType(1, 4, MovableType.NotStandonAcross);
        terrain.SetPointMovableType(1, 8, MovableType.NotStandonAcross);
        terrain.SetPointMovableType(2, 0, MovableType.NotStandonAcross);
        terrain.SetColumnMovableType(2, 3, 4, MovableType.NotStandonAcross);
        terrain.SetPointMovableType(2, 6, MovableType.NotStandonAcross);
        terrain.SetPointMovableType(2, 8, MovableType.NotStandonAcross);
        terrain.SetColumnMovableType(3, 0, 4, MovableType.NotStandonAcross);
        terrain.SetPointMovableType(3, 8, MovableType.NotStandonAcross);
        terrain.SetColumnMovableType(4, 0, 1, MovableType.NotStandonAcross);
        terrain.SetColumnMovableType(4, 4, 8, MovableType.NotStandonAcross);
        terrain.SetPointMovableType(5, 0, MovableType.NotStandonAcross);
        terrain.SetPointMovableType(5, 2, MovableType.NotStandonAcross);
        terrain.SetPointMovableType(5, 4, MovableType.NotStandonAcross);
        terrain.SetColumnMovableType(5, 6, 8, MovableType.NotStandonAcross);
        terrain.SetPointMovableType(6, 0, MovableType.NotStandonAcross);
        terrain.SetColumnMovableType(6, 4, 8, MovableType.NotStandonAcross);
        terrain.SetPointMovableType(7, 0, MovableType.NotStandonAcross);
        terrain.SetColumnMovableType(7, 2, 6, MovableType.NotStandonAcross);
        terrain.SetPointMovableType(7, 8, MovableType.NotStandonAcross);
        terrain.SetPointMovableType(8, 7, MovableType.NotStandonAcross);
        terrain.SetPointMovableType(9, 0, MovableType.NotStandonAcross);
        terrain.SetColumnMovableType(9, 2, 5, MovableType.NotStandonAcross);
        terrain.SetColumnMovableType(9, 7, 8, MovableType.NotStandonAcross);
        return terrain;
    }
    

    需要使用地形类的接口设置好很多空白地方(可以跃过,但是不可以立足的位置,类型是MovableType.NotStandonAcross

    下面说寻路,寻路怎么做能找到最优的路径呢?

    为了利于说明,给宝物编号,假设上面的宝物叫1号宝物,下面的宝物叫2号宝物。

    寻路接口只支持一个起点,一个终点。那么做法是:

    • 假设先获取1号宝物,再获取2号宝物。

      即从起点到1号宝物寻路,再从1号宝物到达2号宝物寻路,把两次寻路的行动力求总和。

    • 再假设先获取2号宝物,再获取1号宝物。

      即“起点->2号宝物->1号宝物”,同样求出2次寻路的行动力总和。

    • 比较上面2种假设,行动力少的就是最优方案。

    • 注意,每种假设都寻路了两次,每次寻路都会造成地形力的评估值发生了改变,需要重新设置地形才可以进行第二次寻路,比如假设先取1号宝物,再取2号宝物的做法是:设置地形->寻路(起点,1号宝物)->重新设置地形->寻路(1号宝物, 2号宝物)->计算两次行动力总和。

    代码如下:

    static private void Exam3()
    {
        /* 先设置地形,没有高度差,高度全为0 */
        Terrain terrain = SetTest3Terrain();
        /* 先拿上面的宝物,再拿下面的宝物,所用的行动力 */
        Console.WriteLine("假设先拿上面的宝物,再拿下面的宝物,寻路中...");
        PathFinding pathFinding = new PathFinding();
        List<Node> bestPath = null;
        int action1 = 0;
        pathFinding.Terrain = terrain;
        if (pathFinding.FindPath(8, 0, 3, 5, out bestPath, out action1, MoveType.RiMove))
        {
            /* 找到路径,打印 */
            Console.WriteLine("从起点到达上面宝物的寻路为:");
            ShowBestPath(bestPath, action1);
        }
        else
        {
            /* 找不到路径 */
            Console.WriteLine("Not found path!");
        }
        /* 接着再计算从上面宝物走到走到下面宝物的行动力 */
        /* 要先恢复地形,很重要!!!! */
        terrain = SetTest3Terrain();
        pathFinding = new PathFinding();
        bestPath = null;
        int action2 = 0;
        pathFinding.Terrain = terrain;
        if (pathFinding.FindPath(3, 5, 0, 1, out bestPath, out action2, MoveType.RiMove))
        {
            /* 找到路径,打印 */
            Console.WriteLine("从上面宝物到达下面宝物的寻路为:");
            ShowBestPath(bestPath, action2);
        }
        else
        {
            /* 找不到路径 */
            Console.WriteLine("Not found path!");
        }
        /* 总行动力 */
        int action_type1 = action1 + action2;
        Console.WriteLine("假设先拿上面的宝物,再拿下面的宝物,所用行动力是{0}", action_type1);
    
        /* 假设先取下面的宝物,再取上面的宝物 ,再做一遍*/
        Console.WriteLine();
        Console.WriteLine("假设先拿下面的宝物,再拿上面的宝物,寻路中...");
        terrain = SetTest3Terrain();
        /* 先拿上面的宝物,再拿下面的宝物,所用的行动力 */
        pathFinding = new PathFinding();
        bestPath = null;
        action1 = 0;
        pathFinding.Terrain = terrain;
        if (pathFinding.FindPath(8, 0, 0, 1, out bestPath, out action1, MoveType.RiMove))
        {
            /* 找到路径,打印 */
            Console.WriteLine("从起点到达下面宝物的寻路为:");
            ShowBestPath(bestPath, action1);
        }
        else
        {
            /* 找不到路径 */
            Console.WriteLine("Not found path!");
        }
        /* 接着再计算从上面宝物走到走到下面宝物的行动力 */
        /* 要先恢复地形 */
        terrain = SetTest3Terrain();
        pathFinding = new PathFinding();
        bestPath = null;
        action2 = 0;
        pathFinding.Terrain = terrain;
        if (pathFinding.FindPath(0, 1, 3, 5, out bestPath, out action2, MoveType.RiMove))
        {
            /* 找到路径,打印 */
            Console.WriteLine("从下面宝物到达上面宝物的寻路为:");
            ShowBestPath(bestPath, action2);
        }
        else
        {
            /* 找不到路径 */
            Console.WriteLine("Not found path!");
        }
        /* 总行动力 */
        int action_type2 = action1 + action2;
        Console.WriteLine("假设先拿下面的宝物,再拿上面的宝物,所用行动力是{0}", action_type2);
    }
    

    结果为:

    假设先拿上面的宝物,再拿下面的宝物,寻路中...
    从起点到达上面宝物的寻路为:
    
    Found path:
    (8, 0) -> (6, 1) -> (4, 2) -> (6, 3) -> (5, 5) -> (4, 3) -> (3, 5)
    Action: 84
    从上面宝物到达下面宝物的寻路为:
    
    Found path:
    (3, 5) -> (4, 3) -> (2, 2) -> (0, 1)
    Action: 42
    假设先拿上面的宝物,再拿下面的宝物,所用行动力是126
    
    假设先拿下面的宝物,再拿上面的宝物,寻路中...
    从起点到达下面宝物的寻路为:
    
    Found path:
    (8, 0) -> (6, 1) -> (4, 2) -> (2, 1) -> (1, 3) -> (0, 1)
    Action: 70
    从下面宝物到达上面宝物的寻路为:
    
    Found path:
    (0, 1) -> (2, 2) -> (4, 3) -> (3, 5)
    Action: 42
    假设先拿下面的宝物,再拿上面的宝物,所用行动力是112
    

    最优的方案是和图示标的数字一样,先拿下面的宝物,再拿上面的宝物。

    六、使用Excel画地形图

    上面的例子,设置地形尤其麻烦,特别是不规则的图形,比如例子3,稍微不小心很容易就会出错。

    excel上画则简单多了,地形每个节点就是excel的一个单元格。

    比如例子1的图如下:

    比如例子3的图如下:

    例子3的图

    excel绘制地形图,如例子所示,比较简单而且直观,只要能读取excel的图,转成Terrain对象就可以了。

    读取Excel有开源库,可以用EPPlus,也可以用NPOI,经对比,我采用EPPlus

    因为读取excel,转成Terrain,必须要做些约定,才可以按照约定转化,约定如下:

    • 地形全部按照长方形形状的,对于不规则的,可以按照最长边补齐成长方形,不存在的地形使用不可立足的节点填充

    • 所有地形的边框用实线,这样通过识别单元格的实线,来识别出来地形的长宽

    • 所有背景颜色要用RGB颜色,因为EPPlus识别RGB颜色比较容易。

      excel图颜色

      如上图,要使用标准色,如果标准色中没有的,就在其他颜色中配置RGB颜色,使用过一次之后,就会记录在最近使用的颜色中了。

      地形的ARGB颜色约定:

      起点:绿色 #FF00B050,起点的单元格写上文字"马"标识走日字型,普通的什么都不写

      终点:红色 #FFFF0000

      可立足地形:灰色 #FFE6E6E6

      不可立足可跃过地形:保留excel原来单元格的空白,即没有颜色

      不可立足不可跃过地形:深蓝色 #FF002060

    • 单元格用文字标注地形的基本行动力和高度。为了更容易绘制,更美观,如果高度是0,可以不标高度,如果基础行动力是普通的10,可以不标基础行动力。例子1的图,F5单元格的位置本来是可以不标的,因为基础行动力是10,高度是0,为了说明,标了一下,也不会有错。B: 10标识基础行动力是10,H : 0标识高度是0。(注意冒号必须使用英文字符,而且每一项要用换行隔开)

    七、EPPlus读取excel地形图

    关于EPPlus的了解,可以网上搜索。

    我的VS2017,如果直接下载源码编译,会提示.net framework版本不对。

    所以我是从NuGet中下载的。直接得到可用的各个版本的EPPlus.dll库。

    和前述的添加AStarPathFinding.dll到引用一样的方法,把EPPlus.dll库添加到引用,程序增加一个读取Excel转换到Terrain的类,这个类提供方法,输入是excel文件名以及sheet序号,输出是Terrain对象。

    颜色

    不可立足不可跃过地形:深蓝色 #FF002060

    • 单元格用文字标注地形的基本行动力和高度。为了更容易绘制,更美观,如果高度是0,可以不标高度,如果基础行动力是普通的10,可以不标基础行动力。例子1的图,F5单元格的位置本来是可以不标的,因为基础行动力是10,高度是0,为了说明,标了一下,也不会有错。B: 10标识基础行动力是10,H : 0标识高度是0。(注意冒号必须使用英文字符,而且每一项要用换行隔开)

    七、EPPlus读取excel地形图

    关于EPPlus的了解,可以网上搜索。

    我的VS2017,如果直接下载源码编译,会提示.net framework版本不对。

    所以我是从NuGet中下载的。直接得到可用的各个版本的EPPlus.dll库。

    和前述的添加AStarPathFinding.dll到引用一样的方法,把EPPlus.dll库添加到引用,程序增加一个读取Excel转换到Terrain的类,这个类提供方法,输入是excel文件名以及sheet序号,输出是Terrain对象。

    最后使用例子4和例子5做测试,具体不再说明,参照源代码。

    展开全文
  • 百度地图开发java源码
  • App Cooker 的创造者)的共同创建者. 在本系列课程中,你将学到如何在一个简单的Cocos2D游戏中添加A*寻路算法. 在你学习本课程之前,如果你先阅读过 Introduction to A* Pathfinding (猫猪已经翻译完成,请到 ...
  • 大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流之用,请勿进行...
  • 基础寻路源代码.rar

    2012-06-26 19:57:28
    基础寻路源代码.rar
  • 寻路可视化器-源码

    2021-02-20 12:35:49
    Create React App入门 该项目是通过。 可用脚本 在项目目录中,可以运行: npm start 在开发模式下运行应用程序。 打开在浏览器中查看。 如果进行编辑,页面将重新加载。 您还将在控制台中看到任何棉绒错误。 npm ...
  • 托管在Netlify上: ://algorithm0visualiser.netlify.app/ 步骤来运行它 1.转到根文件夹,然后键入npm start 2.单击任何方法冒泡排序或任何排序算法(当前仅实现冒泡排序) 3.然后您可以输入您自己的内容,也可以...
  • nih-寻路 NIH 寻路工具(原型) 构建状态 地方发展 Vagrant 1.5+ 和 Ansible 1.8+ 的组合用于为该项目设置开发环境... cd /opt/app grunt serve 从那里,您应该能够访问位于以下位置的开发服务器:[http://localhost:
  • A星寻路算法的Lua实现

    千次阅读 2016-03-06 19:48:05
    这里有一篇文章,很适合新手学习 莫水千流:A星寻路算法介绍 。对A星算法的理解还是要从公式 F = G + H开始:在节点化的地图上,每一步的操作,使得已走距离 + 距离终点距离最小。具体的实现上是维护一个open表和一个...
  • 复制该存储库后,使用以下命令打开GUI $ python app.py 然后,插入矩阵的宽度和高度,然后单击“创建矩阵” 最后,点击“ DO !!” 看到随机开始位置和结束位置之间的A *线,其中st为开始,fi为结束 \ `
  • Project1 迷宫寻路 实验报告 思路 1.从指定地址输入一个给定大小的01数组,0代表通路,1代表墙体。 2.定义结构体node,包括横坐标x,纵坐标y,指向前一个位置的指针pre。定义node数组way[100],并将其首元素初始化...
  • Create React App入门 该项目是通过引导的。 可用脚本 在项目目录中,可以运行: yarn start 在开发模式下运行应用程序。 打开在浏览器中查看它。 如果您进行编辑,则页面将重新加载。 您还将在控制台中看到任何...
  • AStar-寻路原理

    2020-01-09 14:27:27
    由于一次面试被问起AStar算法原理,我当场面红耳赤,不知怎么开口,这个耳熟能详的寻路算法,我对它的原理却浑然不知,一直都有听大家说到这个算法,也有调用过相关接口,然自己却那么陌生,真想一头钻到地底。...
  • Create React App入门 该项目是通过引导的。 可用脚本 在项目目录中,可以运行: npm start 在开发模式下运行该应用程序。打开在浏览器中查看它。 如果您进行编辑,则页面将重新加载。您还将在控制台中看到任何棉绒...
  • A*寻路算法入门(一)

    千次阅读 2015-11-21 20:45:36
    App Cooker 的创造者)的共同创建者. 学习A*寻路算法是如何实现的! 你是否在你的游戏中想要怪物或者玩家移动到特定的地点,同时避免墙和障碍物? 如果是,读一读这篇课程,它将向你展示你能用A*寻路算法做些...
  • 在张朝阳看来,“狐友APP很好的满足了弥补陌生人从陌生到熟悉过程开阔的地段现在没有好的APP来满足需求。”例如对观众而言,校花大赛将在狐友上用社交网络和视频或者直播多种形式,包括Vlog全方位记录,让人能够比较...
  • java实现寻路

    千次阅读 2016-04-09 15:48:53
    package com.person.appframework.test;... * 图寻路算法  * 深度回溯  * @author wuwhe  *  */ public class GraphPath {  private int[][] block;  /** 高度 */  private int maxHeigh
  • PathfindingVisualizer组件已导入并在App.js中呈现。 如果您希望以此为基础来创建自己的Pathfinding Visualizer,请随意分叉该项目或仅复制粘贴代码。 另外,如果您还没有订阅我的,请在我所有的视频上点赞按钮。 ...
  • is8dir: false, // 是否8方向寻路 map: cc.Graphics, }, statics: { _instance: null, Instance() { return AStar._instance; }, }, onLoad() { this.timer = 0; this.timeron = true; //this.map =...
  • 2D寻路可视化器 现场演示: : 目前仅Dijkstra可用 堆 React钩 样式预处理器 可用脚本(create-react-app) 在项目目录中,可以运行: yarn start 在开发模式下运行应用程序。 打开在浏览器中查看。 如果进行编辑...
  • 迷宫寻路

    2012-12-19 09:53:54
    写了一个小程序,使用BFS(宽度优先),GREED(贪婪算法),A*(启发式),GA(遗传算法)来解决迷宫寻路问题,大家看看算法有没有可以的改进的地方?源代码可以直接查看。 Demo地址: [url]...
  • 在已知其结论的情况下,作为程序员的我,还是想利用该问题当做出发点,写一个可以遍历所有“可能路线”的寻路算法,当做学习“图”相关算法的练习。如果对那个原始问题有兴趣,点击上面的文章链接,出门右转便是。 ...
  • Create React App入门 该项目是通过引导的。 可用脚本 在项目目录中,可以运行: npm start 在开发模式下运行应用程序。 打开在浏览器中查看它。 如果您进行编辑,则页面将重新加载。 您还将在控制台中看到任何...
  • A*算法寻路之Ogre实践

    2012-12-07 12:56:02
    这里将使用A*算法对地图里的一个机器人实现指示之后自动寻路的功能。  基本功能如下:1.利用鼠标点击指示目的地。  2.机器人收到指令后自己搜寻最优路径。  3.机器人需要绕开障碍物,并且随着路径转换自己的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 967
精华内容 386
关键字:

寻路app