STM32借助A*算法完成贪吃蛇

简介: 笔记

一. 简介


借助在前面stm32完成的贪吃蛇小游戏,现在借助A算法,来完成贪吃蛇的一个自动寻找食物的过程,从而解放我们的双手。终于从完成功能代码,到了算法的部分啦。经过这里例子,可以很好的感受将我们学习到的算法应用到实际的项目当中去。例如这里的寻路算法可以利用深度优先和广度优先搜索算法来完成,都是寻路入门级的算法。在A算法中,可以感受到排序算法的用处,以及数据结构的魅力。需要的可以关注哦

演示视频


欢迎关注微信公众号 FPGA之旅 回复 A*STM32贪吃蛇

获取下载链接

这里我是先在软件上实现,然后将其移植到stm32当中去。

15.png

二. 算法简介


算法的详细过程就不细细介绍了,主要来说一下实现的具体步骤,这样根据步骤,也可以自己实现出来,而不用看很多很多文章。


创建两个列表,一个为待访问列表,另外一个为已经访问列表

将起始点加入到待访问列表中,并计算其预估值F。

从待访问列表中选择预估值最小的点,作为当前节点,并在待访问列表中删除。

寻找当前节点附近的点,并计算其预估值,已经将当前节点,设置为它们的父节点,然后将这些点加入到待访问列表中

将当前节点加入到已经访问列表中

重复执行3-5。直到寻找到目标点。然后通过该点的父节点依次递推,几个获取到起始点到目标点的路径。

F = G + H.

H表示当前节点到目标点之间的距离值

G表示当前节点到起始点之间的距离值

计算得过程中,可以在前面加上权重,表示当前节点到那个点更为重要。


三. 代码实现


通过上面的步骤,一步一步就可以实现A*算法。


节点的定义,主要是定义了节点的预估值和父节点

//A*算法的节点
typedef struct Node
{
  int F;    
  Point2 p;
  struct Node* father;
}Node;


待访问列表和已经访问列表,这样比较消耗内存,特别是对于单片机带说,后面再改善吧

Node nodeLists[140];   //待访问列表
Node visitedNodeLists[140];  //已经访问的列表
uint16_t   nodeListsIndex = 0; 
uint16_t   visitedNodeListsIndex = 0;
uint16_t   CurrListIndex = 0;


A*算法

主要流程入下,和上面的实现步骤是一致的,很好理解。


对待访问列表的排序是从大到小进行排序。这样我每次只需要取出最后一个就是最小的那个了,对于的Index值减一,就表示将其从待访问列表中移除,非常方便。 这个思想非常重要。

同时这里需要注意的是malloc可能申请不到内存,这也是头疼的一个问题。ε=(´ο`*)))唉


uint8 AutoEateByAStar()
{
    uint16 i;
    nodeListsIndex = 0;
  visitedNodeListsIndex = 0;
    CurrListIndex = 0;
    PathLen = 0;
    //目标位置
    end.x = FoodPosition.x;
    end.y = FoodPosition.y;
    //起始位置
    start.p.x = head->postion.x;
    start.p.y = head->postion.y;
    start.father = NULL;
    start.F = Assess(start.p, start.p, end);
    //将起始点,添加到待访问点
    nodeLists[nodeListsIndex] = start;
  nodeListsIndex += 1;
    while (nodeListsIndex > 0)
  {
  Curr = (Node*)malloc(sizeof(Node));
  Curr->F = nodeLists[nodeListsIndex - 1].F;
  Curr->p = nodeLists[nodeListsIndex - 1].p;
  Curr->father = nodeLists[nodeListsIndex - 1].father;
  nodeListsIndex -= 1;
  searchNeighboor();
  visitedNodeLists[visitedNodeListsIndex] = *Curr;
  visitedNodeListsIndex += 1;
        //保存申请到的内存
        CurrList[CurrListIndex] = Curr;
  CurrListIndex += 1;
        if (Curr->p.x == end.x && Curr->p.y == end.y)  //查找到路径
        {
            //保存路径
            while (Curr->father != NULL)
            {
                PathByAStar[PathLen].x =  Curr->p.x;
                PathByAStar[PathLen].y =  Curr->p.y;
                PathLen += 1;
                printf("%d %d \r\n",Curr->p.x,Curr->p.y);
                Curr = Curr->father;
            }
            PathByAStar[PathLen].x =  Curr->p.x;
            PathByAStar[PathLen].y =  Curr->p.y;
            PathLen += 1;
            //释放申请到的内存
            for (i = 0; i < CurrListIndex; i++)
    {
    free(CurrList[i]);
    CurrList[i] = NULL;
    }
           return 0;
        }
    }
    return 1;
}

到这里A*寻路算法就差不多完成了,主要是在贪吃蛇中进行路径解析。


四. 贪吃蛇路径解析


这里解析也是非常容易的,因为在PathByAStar中已经保存到了路径值。所以只需要在每一次移动的时候,蛇头和下一个位置进行对比,就可以确定移动的方向了。代码如下,

if( PathByAStar[PathLen-1].y == head->postion.y)
 {
      if(PathByAStar[PathLen-1].x == head->postion.x -1)
          MoveDirection = MoveLeft;
      else
          MoveDirection = MoveRight;
  }
 else
  {
      if(PathByAStar[PathLen-1].y == head->postion.y -1)
          MoveDirection = MoveUp;
      else
          MoveDirection = MoveDown;
  }
  PathLen -= 1;


这样就完成。完整代码可以关注微信公众号 FPGA之旅 获取。


公众号:FPGA之旅


目录
相关文章
|
10月前
|
算法 JavaScript Java
|
存储 异构计算
|
传感器 缓存 算法
基于STM32的心率计(二)动态阈值算法获取心率值
基于STM32的心率计(二)动态阈值算法获取心率值
694 0
基于STM32的心率计(二)动态阈值算法获取心率值
|
算法 测试技术
2020电赛E题--非线性失真器程序设计--01--算法仿真与STM32FFT数据验证(附工程源码+gitee链接)
2020电赛E题--非线性失真器程序设计--01--算法仿真与STM32FFT数据验证(附工程源码+gitee链接)
326 0
2020电赛E题--非线性失真器程序设计--01--算法仿真与STM32FFT数据验证(附工程源码+gitee链接)
|
机器学习/深度学习 存储 人工智能
我在STM32单片机上跑神经网络算法—CUBE-AI
为什么可以在STM上面跑人工智能?简而言之就是通过X-Cube-AI扩展将当前比较热门的AI框架进行C代码的转化,以支持在嵌入式设备上使用,目前使用X-Cube-AI需要在STM32CubeMX版本7.0以上,目前支持转化的模型有Keras、TF lite、ONNX、Lasagne、Caffe、ConvNetJS。Cube-AI把模型转化为一堆数组,而后将这些数组内容解析成模型,和Tensorflow里的模型转数组后使用原理是一样的。
640 0
我在STM32单片机上跑神经网络算法—CUBE-AI
|
2天前
|
算法 数据安全/隐私保护 计算机视觉
基于二维CS-SCHT变换和LABS方法的水印嵌入和提取算法matlab仿真
该内容包括一个算法的运行展示和详细步骤,使用了MATLAB2022a。算法涉及水印嵌入和提取,利用LAB色彩空间可能用于隐藏水印。水印通过二维CS-SCHT变换、低频系数处理和特定解码策略来提取。代码段展示了水印置乱、图像处理(如噪声、旋转、剪切等攻击)以及水印的逆置乱和提取过程。最后,计算并保存了比特率,用于评估水印的稳健性。
|
3天前
|
存储 算法 数据可视化
基于harris角点和RANSAC算法的图像拼接matlab仿真
本文介绍了使用MATLAB2022a进行图像拼接的流程,涉及Harris角点检测和RANSAC算法。Harris角点检测寻找图像中局部曲率变化显著的点,RANSAC则用于排除噪声和异常点,找到最佳匹配。核心程序包括自定义的Harris角点计算函数,RANSAC参数设置,以及匹配点的可视化和仿射变换矩阵计算,最终生成全景图像。
|
3天前
|
算法 Serverless
m基于遗传优化的LDPC码NMS译码算法最优归一化参数计算和误码率matlab仿真
MATLAB 2022a仿真实现了遗传优化的归一化最小和(NMS)译码算法,应用于低密度奇偶校验(LDPC)码。结果显示了遗传优化的迭代过程和误码率对比。遗传算法通过选择、交叉和变异操作寻找最佳归一化因子,以提升NMS译码性能。核心程序包括迭代优化、目标函数计算及性能绘图。最终,展示了SNR与误码率的关系,并保存了关键数据。
12 1