开发者社区> Keanu_Zhang.> 正文

【兔年之兔子走迷宫】 用一个小游戏对回溯法进行实现 | C++

简介: 简单的来说,算法就是用计算机程序代码来实现数学思想的一种方法。学习算法就是为了了解它们在计算机中如何演算,以及在当今的信息时代,它们是如何在各个层面上影响我们的日常生活的,从而提高我们的逻辑思维能力和处理实际问题的能力。善用算法、巧用算法,是培养程序设计逻辑的重中之重,许多实际的问题都可用多个可行的算法来解决, 但是要从中找出最优的解决算法却是一项挑战。
+关注继续查看
福利推荐:阿里云、腾讯云、华为云等大品牌云产品全线2折优惠活动来袭,4核8G云服务器899元/3年,新老用户共享优惠,点击这里立即抢购>>>

image

前言


? ? ? ?? ?简单的来说,算法就是用计算机程序代码来实现数学思想的一种方法。学习算法就是为了了解它们在计算机中如何演算,以及在当今的信息时代,它们是如何在各个层面上影响我们的日常生活的,从而提高我们的逻辑思维能力和处理实际问题的能力。善用算法、巧用算法,是培养程序设计逻辑的重中之重,许多实际的问题都可用多个可行的算法来解决, 但是要从中找出最优的解决算法却是一项挑战。

一、回溯法是什么?


1.简要介绍

?回溯法是枚举法的一种,它是一种可以找出所有解的一般性算法。同时为了避免枚举出现不正确的数值,发现错误值就停止向下一层运行,而是回溯到上一层。为了去减短时间和提高程序代码的执行效率,回溯法一般是一种走不通就退回另寻蹊径的方法。它的特点是在搜索过程中去寻找问题的解,发现不满足的答案就去回溯,从而去避免无效搜索。

二、回溯法经典案例——兔子走迷宫游戏


1.具体情况

? ? ? ? 假如有一只兔子,我们去把它放到一个没有盖子的大迷宫盒中的起点,迷宫内有很多墙,从而使得大部分路径都被挡住而不能前行。兔子需要采用一种试错的方式去尝试走出迷宫,并且兔子需要在每次走错路时把走过的路记录下来,避免再次重复,直到最终到达终点。即①一次只能走一格;②遇到墙无法前行时回退一步去重新判断;③走过的路不会再走第二次;

?在程序中我们仿真迷宫的地图就用二维数组来抽象表示,用0去表示墙,用1表示通路。从而去创建一个12?12大小的迷宫地图。如下图所示:

image

?? ?兔子将会从起点maze[1][1]进入,从终点maze[9][10]出来,兔子当前的位置我们用maze[x][y]去表示。兔子在迷宫中可以选择的方向有四个,东、南、西、北。但并非每个位置此刻的兔子都可以去任意移动,需根据兔子所处在迷宫中的具体情况而定。从而我们可去创建一个老鼠移动的方位图。如下图所示:

image

? ? 在该过程中我们将会用链表去对兔子走过的路径进行记录,并且将兔子走过的路径标记为2,再将其放入堆栈中,再去进行下一个方向的判断。由于每次每次新加入堆栈中的位置都会在其顶端,因此堆栈顶端指针指向的编号便是当前迷宫中兔子的位置。我们会将主要的算法写到类模块中,它主要用于去判断在当前位置的四个方位上是否存在前进的表格。若找到可前进的方格,则将该方格的编号记录到堆栈并且移动,反之则回溯进行重新的判断。

2.代码展示(C++)

? ? ? ?用程序代码去实现具体情况中的兔子走迷宫游戏。

#include<iostream>
using namespace std;
#define north maze[x-1][y]   //北
#define south maze[x+1][y]   //南
#define west maze[x][y-1]    //西
#define east maze[x][y+1]  //东
int maze[12][12] = { {0,0,0,0,0,0,0,0,0,0,0,0},
      {0,1,1,1,0,0,0,0,0,0,0,0},
      {0,0,0,1,0,0,1,1,1,1,0,0},
      {0,0,0,1,0,0,1,0,0,1,0,0},
      {0,0,0,1,1,1,1,0,0,1,0,0},
      {0,0,0,1,0,0,1,0,0,1,0,0},
      {0,0,0,1,0,0,1,0,0,1,0,0},
      {0,0,0,1,0,0,1,0,0,1,0,0},
      {0,0,0,0,0,0,1,0,0,1,0,0},
      {0,0,1,1,1,1,1,1,0,1,1,0},
      {0,0,1,0,0,0,0,0,0,0,0,0},
      {0,0,0,0,0,0,0,0,0,0,0,0} };  //二维数组迷宫图,0表示墙,1表示通路
const int exitx = 9, exity = 10;   //出口端在数组迷宫中的位置,9行10列
//链表的定义及其记录使用
struct list {
    int x, y;
    struct list* next;
};
typedef struct list node;
typedef node* link;
link push(link stack,int x,int y)
{
    link newnode;
    newnode = new node;
    if (!newnode)
    {
  return NULL;
    }
    newnode->x = x;
    newnode->y = y;
    newnode->next = stack;
    stack = newnode;
    return stack;
}
link pop(link stack, int *x, int *y)
{
    link top;
    if (stack != NULL)
    {
  top = stack;
  stack=stack->next;
  *x= top->x;
  *y = top->y;
  delete top;
  return stack;
    }
    else
    {
  *x = -1;
    }
    return stack;
}
//
int checkexit(int x,int y)  //检查是否到达终点
{
    if (x == exitx && y == exity)
  return 1;
    else
  return 0;
}
class maze_data {
public:
    int x;
    int y;
    void walk_judgement()
    {
  link path = NULL;   //初始化路径
  while (x <= exitx && y <= exity)   //while循环中进行东南西北四个方位移动的判断
  {
    maze[x][y] = 2;
    if (north == 1)  //上一格可走
    {
    x--;  //往上走
    path = push(path, x, y);  //加入方格编号到对堆栈
    }
    else if (south == 1)  //下一个可走
    {
    x++;   //往下走
    path = push(path, x, y); //加入方格编号到对堆栈
    }
    else if (west == 1)   //左一格可走
    {
    y--;   //往左走
    path = push(path, x, y); //加入方格编号到对堆栈
    }
    else if (east == 1)    //右一格可走
    {
    y++;   //往右走
    path = push(path, x, y); //加入方格编号到对堆栈
    }
    else if (checkexit(x, y) == 1)  //如果判断到已经到达终点,从而跳出循环
    break; 
    else    //记录走过的位置
    {
    maze[x][y] = 2;
    path = pop(path, &x, &y);
    }
  }
    }
};
void text1()
{
    cout << "-----------------------" << endl;
    for (int i = 0; i < 12; i++)
    {
  for (int j = 0; j < 12; j++)
  {
    cout << maze[i][j] << " ";
  }
  cout << endl;
    }
    cout << "-----------------------" << endl;
}
void text2()
{
    maze_data md;
    md.x = 1;
    md.y = 1;
    md.walk_judgement();
}
int main()
{
    text1();  //输出初始的迷宫矩阵
    text2();  
    text1();  //输出最终老鼠走过路径的迷宫矩阵
}

3.结果展示?

imageimage

总结


? 在以上我们通过一个兔子走迷宫游戏案例,对回溯法进行了实现。其实回溯法应该很广泛的运用到我们的程序代码中,它是一种很好的算法编程思想。大家也可以对我上面的代码进行二次修改,从而去实现一个更大的迷宫地图、更复杂路径和过程的迷宫小游戏。今天刚好是大年除夕,博主在这里给大家拜年了!祝福大家阖家欢乐,兔年大吉!事业“兔”飞猛进,财富“兔”然斗增!身体蹦蹦跳跳健康平安。

————————————————

版权声明:本文为CSDN博主「Keanu_Zhang.」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/zzc18247189868/article/details/128733079

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【力扣·每日一题】1036. 逃离大迷宫 (C++ bfs 思维)
【力扣·每日一题】1036. 逃离大迷宫 (C++ bfs 思维)
14 0
数据结构 (栈)迷宫求解(c++版本)
理解栈的抽象数据类型定义及操作特点。 掌握顺序栈的存储结构的描述。 掌握顺序栈的基本操作的实现方法。 理解栈的广泛应用。
77 0
【数据结构】10分钟教你用栈求解迷宫老鼠问题超详细教程附C++源代码
【数据结构】10分钟教你用栈求解迷宫老鼠问题超详细教程附C++源代码
197 0
迷宫求解(回溯思想,栈实现c++,数据结构)
一开始做这个事觉得很简单,写了之后,发现不对劲,程序陷入了死循环。绝对是有的细节出现的问题,在网上找了找,有的呢是只写了一部分,有的呢是还写错了。最后找到的是c语言版。
930 0
C++ STL学习之【vector的使用】
vector 是表示可变大小数组的序列 容器,其使用的是一块 连续 的空间,因为是动态增长的数组,所以 vector 在空间不够时会扩容;vector 优点之一是支持 下标的随机访问,缺点也很明显,头插或中部插入效率很低,这和我们之前学过的 顺序表 性质很像,不过在结构设计上,两者是截然不同的
32 0
C++ STL学习之【string类的模拟实现】
string 本质上就是一个专注于存储字符的顺序表,使用起来很方便;但在模拟实现 string 时,有许多值得注意的点,下面就来看看 string 类是如何诞生的吧
52 0
C++ STL 学习之【string】
STL 是 C++ 的重要组成部分,由六大部分构成:伪函数、空间配置器、算法、容器、迭代器 和 配接器,其中各种各样的 容器 可以很好的辅助我们写程序,比如今天要介绍的 string,有了它之后,我们对字符串的操作就能变得行云流水
45 0
【查找算法】解析学习四大常用的计算机查找算法 | C++
在数据处理的过程中,能否在最短时间内去找到目的数据,是编程开发人员非常值得关心的一个问题。所谓查找,也被称为搜索,它是指从数据文件中找出满足某些条件的记录。在数据结构中描述算法时习惯用“查找”,而在搜索引擎中找信息或资料时习惯用“搜索”。我们在电话簿中查找某人的电话号码,电话簿就像是数据文件库,而姓名就是去查找电话号码的键值。我们经常使用的搜索引擎所设计的Spider程序(网页抓取程序爬虫)会主动经由网站上的超链接“爬行”到另一个网站,搜集每个网站上的信息并且收录到数据库中,这其中就涉及到了今天要讲的查找算法。
23 0
【奇妙的数据结构世界】用图像和代码对堆栈的使用进行透彻学习 | C++
简单来说,数据结构是一种辅助程序设计并且进行优化的方法论,它不仅讨论数据的存储与处理的方法,同时也考虑到了数据彼此之间的关系与运算,从而极大程度的提高程序执行的效率,减少对内存空间的占用等。不同种类的数据结构适用于不同的程序应用,选择合适正确的数据结构,可以让算法发挥出更大的性能,给设计的程序带来更高效率的算法。
21 0
+关注
清风君
人生是一场旅程,经历着欢乐和悲哀,得失与成败。生的价值,就在于思考和觉醒的能力,人生也是一场虔诚的生命体验,风雨坎坷,沧桑炎凉,内敛不张扬,朴素不退缩,一场坚强的恬淡,一场无畏的从容,云卷云舒,是生命的风景,也是生命的本来。
文章
问答
文章排行榜
最热
最新
相关电子书
更多
继承与功能组合
立即下载
对象的生命期管理
立即下载
移动与复制
立即下载


http://www.vxiaotou.com