草庐IT

汉诺塔

world-explorer 2023-03-28 原文

设计并实现一个游戏:汉诺塔。
完成这个实验,涉及C++面向对象编程以及基本的数据结构知识(如栈和队列)但具此次实现并没有使用STL库。

1. 汉诺塔问题

汉诺塔是一个著名的数学问题。它由三根杆子和若干不同大小的盘子组成。开始时,所有的盘子都在第一根杆子上,并按照从上到下大小升序排列(也就是说,最小的在最上面)。这个问题的目标是将所有盘子移到另一根杆子上,并遵守以下简单的规则:

  1. 每次只能移动一个盘子。
  2. 每次移动都是将其中一根杆子的最上面的盘子取出,放到另一根杆子上。
  3. 任何较大的盘子都不能放在较小的盘子上面。

解决这个问题的经典方法是递归。该算法可以描述为以下伪代码:

function hanoi(n, A, B, C) {  // move n disks from rod A to rod B, use rod C as a buffer
     hanoi(n - 1, A, C, B);
     move(n, A, B);  // move the nth disk from rod A to rod B
     haoni(n - 1, C, B, A);
}

2. 实验描述

在本实验中,杆子的数量总是等于3,盘子的数量可以是1~5。其中,第1根杆子为初始杆,第2根为目标杆。

本实验的任务包括以下内容:

  • 完成一个交互式的汉诺塔游戏程序,根据用户输入的指令移动相应的盘子,并在用户胜利时打印提示;
  • 通过命令行界面,将汉诺塔游戏的状态绘制出来,包括3根杆子和若干盘子;
  • 根据汉诺塔问题的递归算法,提供一个自动求解程序,能够从任一状态出发,通过若干步移动达到目标状态。

具体而言,程序的流程如下:

  1. 首先,程序打印How many disks do you want? (1 ~ 5),要求输入盘子的数量(要求为1~5)。如果输入Q,则退出程序。不合法的输入应当忽略。
  2. 接下来程序将打印汉诺塔的状态,随后打印Move a disk. Format: x y,要求用户给出指令。指令的形式是from to(例如,2 3的意思是将杆2最上面的盘子移动到杆3上),不合法的输入或是不可执行的指令应该忽略。在这之后,无论指令是否合法,程序总是重新打印一遍当前状态,并重新要求用户输入。
  3. 如果输入的指令为0 0,则进入自动模式。程序需要首先将用户已经执行的指令反过来执行一遍,复原到初始状态,然后再按照递归算法执行。每次执行时,程序通过输出Auto moving:x->y告知用户所执行的指令。注意:即使有其他方法从当前状态直接到达目标状态,也请按照先复原后执行的方式进行。这是因为自动评测的时候会直接比对输出内容。
  4. 无论是通过用户指令或是自动模式,只要达成目标状态(即所有盘子都移到杆2上),就打印游戏胜利的提示信息,然后重新回到第1步。

打印汉诺塔状态的要求:我们用|表示杆子,-表示底座,一排*表示盘子。每个盘子从小到大分别用3、5、7、9、11个*表示(最多5个盘子)。无论盘子数量多少,输出的整个画布的大小固定为11x41。

例如,一共5个盘子,均按照从小到大放在杆1上,此时输出的结果应该如下:

     |              |              |
    ***             |              |
     |              |              |
   *****            |              |
     |              |              |
  *******           |              |
     |              |              |
 *********          |              |
     |              |              |
***********         |              |
-----|--------------|--------------|-----//纵向11个|,横向-加|共41个

而如果只有3个盘子,输出如下(注意画布的大小不变):

     |              |              |
     |              |              |
     |              |              |
     |              |              |
     |              |              |
    ***             |              |
     |              |              |
   *****            |              |
     |              |              |
  *******           |              |
-----|--------------|--------------|-----

输入输出

这里给出两个样例,分别使用自动模式和手动模式。这里行首的> <代表是程序的输入还是输出。

样例1:

< How many disks do you want? (1 ~ 5)
> 2
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<     ***             |              |
<      |              |              |
<    *****            |              |
< -----|--------------|--------------|-----
< Move a disk. Format: x y
> 0 0
< Auto moving:1->3
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<    *****            |             ***
< -----|--------------|--------------|-----
< Auto moving:1->2
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |            *****           ***
< -----|--------------|--------------|-----
< Auto moving:3->2
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |             ***             |
<      |              |              |
<      |            *****            |
< -----|--------------|--------------|-----
< Congratulations! You win!
< How many disks do you want? (1 ~ 5)
> Q

样例2:

< How many disks do you want? (1 ~ 5)
> 2
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<     ***             |              |
<      |              |              |
<    *****            |              |
< -----|--------------|--------------|-----
< Move a disk. Format: x y
> 1 2
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<    *****           ***             |
< -----|--------------|--------------|-----
< Move a disk. Format: x y
> 2 3
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<    *****            |             ***
< -----|--------------|--------------|-----
< Move a disk. Format: x y
> 1 2
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |            *****           ***
< -----|--------------|--------------|-----
< Move a disk. Format: x y
> 3 2
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |              |              |
<      |             ***             |
<      |              |              |
<      |            *****            |
< -----|--------------|--------------|-----
< Congratulations! You win!
< How many disks do you want? (1 ~ 5)
> Q

具体实现:

GitHub:https://github.com/Fly0307/SEP_lab3

有关汉诺塔的更多相关文章

  1. javascript - 在 Javascript 中可视化汉诺塔算法 - 2

    Latley我正在做一个学校项目,我必须提出一个算法,在我的例子中,这个算法是解决汉诺塔谜题的算法。由于我在HTML/CSS方面的知识,我认为使用这些+Javascript来可视化网页上的步骤会非常巧妙。我设置了站点以及基本的递归算法。functionmove(n,beg,aux,end){if(n==1){console.log(beg+'-->'+end+'\n');setTowers(beg,end);}else{move(n-1,beg,end,aux);move(1,beg,aux,end);move(n-1,aux,beg,end);}}页面布局(CSS代码在这里无济于事)

  2. C# 汉诺塔控制台应用程序。 - 2

    我会保持简洁。我正在学习C#并探索该语言的可能性。作为一名Python程序员,我对.NET领域还很陌生。我目前正在编写汉诺塔控制台应用程序。我已经理解代码的递归部分,因为这并不具有挑战性。这是我的Hook类的当前代码。namespaceTower_of_hanoi{classPegClass{privateintpegheight;privateinty=3;int[]rings=newint[0];publicPegClass(){//defaultconstructor}publicPegClass(intheight){pegheight=height;}//otherfunct

  3. 利用Python解决汉诺塔问题(递归) - 2

    熟悉一下汉诺塔python解决汉诺塔问题问题:有三个立柱A、B、C。A柱上穿有大小不等的圆盘N个,较大的圆盘在下,较小的圆盘在上。要求把A柱上的圆盘全部移到C柱上,保持大盘在下、小盘在上的规律(可借助B柱)。每次移动只能把一个柱子最上面的圆盘移到另一个柱子的最上面。请输出移动过程。问题分析(看图):以上是来自https://blog.csdn.net/qq_41282102/article/details/85061198的图片。从以上n=2时的动图中可以发现,B相当于作为放置的媒介,而最关键的问题是:交换A与C的位置,那么B处就可以直接将小圆盘再放置上就大功告成!于我而言,递归递归关键的点在

  4. java - 仅使用 int[ ][ ] 的 Java 汉诺塔(可以做到吗?) - 2

    这不是家庭作业,我没有钱上学,所以我在高速公路上的收费站轮类工作时自学(漫长的夜晚,几乎没有顾客)。我正在尝试用Java实现一个简单版本的HanoiTowers求解器。我正在使用堆栈和递归函数,没有咨询外部资源,以便有机会思考自己。我从一组数组(int[][]pegs)开始,但在“移动”步骤的实现上卡住了,特别是如何知道我需要从起始位置数组中“选择”哪个“高度”在哪个“高度”我会将光盘放在目标位置数组中。当然有Stack它是为我做这件事的数据结构,我不需要跟踪任何事情。我编写了这个版本,但对放弃感到消极懒惰;我对扩展我的大脑和理解如何用数组来完成这一切很感兴趣。是否可以使用int[][

  5. java - 汉诺塔解决方案优于 O(2^n)? - 2

    对于运行时间小于O(2n)的TowersofHanoi是否有解决方案,其中n是磁盘数移动?我的解决方案需要O(2n)时间。此外,下面的解决方案是递归的。我们可以使用具有内存概念的动态规划在更短的时间内解决这个问题吗?publicvoidtowersOfHanoi(intnum,MyStackfrom,MyStackto,MyStackspare){if(num==1){inti=from.pop();to.push(i);System.out.println("Move"+i+"from"+from.getName()+"to"+to.getName());return;}towers

  6. c++ - 汉诺塔C++(使用递归) - 2

    我写了下面的代码作为练习。当我打印目标堆栈时,我得到了不正确的输出。谁能指出我哪里出错了?//TowerofHanoiusingStacks!#include#include#includeclassStack{private:int*t;intlength,top;public:Stack(intlen){length=len;t=newint[len];top=-1;}~Stack(){delete[]t;}voidpush(intd){top++;t[top]=d;}intpop(){top--;returnt[top+1];}voidprintstack(){intcur=to

  7. c++ - 在编译时解决汉诺塔问题 - 2

    我试图在编译时解决汉诺塔问题,但我发现了一个问题:templatestructmove_disc{//memberaccesswillprintsrcanddst};templatestructhanoi{hanoibefore;typenamemove_disc::loldisc;hanoiafter;};templatestructhanoi{//recursivebasecase};hanoigo;不幸的是,theabovemetaprogram只打印六步而不是七步:prog.cpp:11:39:error:notypenamed‘lol’in‘structmove_disc’p

  8. c# - 汉诺塔 : Moving Rings from Peg to Peg - 2

    扩展我之前的帖子,我还在写汉诺塔。在解释了如何在钉子上画环的绝妙解决方案之后,我仍然有一个问题,我已经摆弄了很长一段时间了。这是我的PegClass:namespaceTowers_Of_Hanoi{classPegClass{privateintpegheight;privateinty=3;int[]rings=newint[0];publicPegClass(){//thisisthedefaultconstructor}publicPegClass(intheight){pegheight=height;}//otheruserdefinedfunctionspublicvoi

  9. 【c语言】每日一题之汉诺塔类型 - 2

    目录前言题目说明描述题目分析汉诺塔问题题目代码展示前言大佬们,我又回来了,最近也在忙自己的学业,忙着生活对线,也参加了今年的蓝桥杯其他的组,发现今年太难了,摆烂了。但我想到了读者你们,从今天开始继续更新博客。通过写一篇我随便写的有趣的题,打开今年的博客之旅。题目说明BC161大吉大利,今晚吃鸡描述糖和抖m在玩个游戏,规定谁输了就要请谁吃顿大餐:抖m给糖abc三个驻,并在a柱上放置了数量为n的圆盘,圆盘的大小从上到下依次增大,现在要做的事就是把a柱的圆盘全部移到c柱,移动的过程中保持小盘在上,大盘在下,且限定圆盘只能够移动到相邻的柱子,即a柱子上的圆盘只能够移动到b,b柱子上的圆盘只能够移动到a

  10. 【c语言】每日一题之汉诺塔类型 - 2

    目录前言题目说明描述题目分析汉诺塔问题题目代码展示前言大佬们,我又回来了,最近也在忙自己的学业,忙着生活对线,也参加了今年的蓝桥杯其他的组,发现今年太难了,摆烂了。但我想到了读者你们,从今天开始继续更新博客。通过写一篇我随便写的有趣的题,打开今年的博客之旅。题目说明BC161大吉大利,今晚吃鸡描述糖和抖m在玩个游戏,规定谁输了就要请谁吃顿大餐:抖m给糖abc三个驻,并在a柱上放置了数量为n的圆盘,圆盘的大小从上到下依次增大,现在要做的事就是把a柱的圆盘全部移到c柱,移动的过程中保持小盘在上,大盘在下,且限定圆盘只能够移动到相邻的柱子,即a柱子上的圆盘只能够移动到b,b柱子上的圆盘只能够移动到a

随机推荐