C#实现4种经典迷宫生成算法和迷宫寻路算法(六)

A*迷宫寻路算法

在A*算法里面,有两个概念,一个是已经走过的步数G,一个是走到目标需要的步数H。

例如我从起点S出发,S的G就是0了。往右走一格到T,那T的G就是0+1=1。再走一步,就是1+1=2。反正从G=g的点出发,走一格后的G就是g+1。

H也很好算。例如目标是(m,n),当然格是(u,v),那么H=abs(u-m)+abs(v-n)

算出G和H之后,我们要算一个F,简单的话,F=G+H。实际有些地方会偏重G或H,可以加个权值,这个需要根据实际情况判断。我们这里直接令F=G+H。

根据这样的定义,我们可以看到,如果F越小,则说明走过的步数较少,而且离目标较近,是一个比较好的点。

A*寻路算法就是基于上面的理论,其过程如下:

(1)把起点S放到一个open_list里面。

(2)对open_list进行排序,找出F最小的格子。

(3)取出F最小的格子,放到close_list里面。

(4)找到当前格子相邻的格子,计算它的F。

1)如果这个格子在close_list里面,不用管,跳过。

2)如果这个格子在open_list里面,而且F比open_list里的值小,更新open_list里的值。

3)如果这个格子不在open_list里面,直接加入到open_list。

(5)重复第2步。

 

实现的代码如下:

/// <summary>
/// 计算路径
/// </summary>
public void CalcPath()
{
    PosNode pn0 = new PosNode(1, 1, 0, null, ROW, COL);
    open_list.Add(pn0);

    bool finish = false;
    while (open_list.Count != 0)
    {
        open_list.Sort();

        PosNode now = open_list[open_list.Count - 1];
        open_list.RemoveAt(open_list.Count - 1);
        close_dict.Add(now, 0);

        PosNode[] nextto = new PosNode[4];
        nextto[0] = new PosNode(now.row - 1, now.col, now.G + 1, now, ROW, COL);
        nextto[1] = new PosNode(now.row + 1, now.col, now.G + 1, now, ROW, COL);
        nextto[2] = new PosNode(now.row, now.col - 1, now.G + 1, now, ROW, COL);
        nextto[3] = new PosNode(now.row, now.col + 1, now.G + 1, now, ROW, COL);

        for (int i = 0; i < 4; i++)
        {
            if (!IsValid(nextto[i]))
            {
                continue;
            }
            if (close_dict.ContainsKey(nextto[i]))
            {
                continue;
            }

            int index = -1;
            for (int j = open_list.Count - 1; j >= 0; j--)
            {
                if (open_list[j].Equals(nextto[i]))
                {
                    index = j;
                    break;
                }
            }

            if (index == -1)
            {
                open_list.Add(nextto[i]);
                if (nextto[i].row == ROW - 2 && nextto[i].col == COL - 2)
                {
                    finish = true;
                    break;
                }
            }
            else
            {
                if (nextto[i].F < open_list[index].F)
                {
                    open_list[index].F = nextto[i].F;
                    open_list[index].pre = nextto[i].pre;
                }
            }
        }

        if (finish)
        {
            break;
        }
    }
}

/// <summary>
/// 是否合法节点
/// </summary>
private bool IsValid(PosNode pn)
{
    if (pn.row < 0 || pn.row >= ROW || pn.col < 0 || pn.col >= COL)
    {
        return false;
    }
    if (maze[pn.row, pn.col] == 1)
    {
        return false;
    }
    return true;
}

/// <summary>
/// 打印路径
/// </summary>
public List<Position> PrintPath()
{
    List<Position> list = new List<Position>();

    PosNode now = open_list[open_list.Count - 1];
    while (now != null)
    {
        list.Add(GetPosition(now.row, now.col));
        now = now.pre;
    }

    return list;
}

代码就是这么多,不难吧!

源码下载:https://download.csdn.net/download/lweiyue/10830542

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值