汉诺塔

设计并实现一个游戏:汉诺塔。
完成这个实验,涉及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

posted @ 2022-04-15 00:26  O_fly_O  阅读(747)  评论(0编辑  收藏  举报