汉诺塔
设计并实现一个游戏:汉诺塔。
完成这个实验,涉及C++面向对象编程以及基本的数据结构知识(如栈和队列)但具此次实现并没有使用STL库。
1. 汉诺塔问题
汉诺塔是一个著名的数学问题。它由三根杆子和若干不同大小的盘子组成。开始时,所有的盘子都在第一根杆子上,并按照从上到下大小升序排列(也就是说,最小的在最上面)。这个问题的目标是将所有盘子移到另一根杆子上,并遵守以下简单的规则:
- 每次只能移动一个盘子。
- 每次移动都是将其中一根杆子的最上面的盘子取出,放到另一根杆子上。
- 任何较大的盘子都不能放在较小的盘子上面。
解决这个问题的经典方法是递归。该算法可以描述为以下伪代码:
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根杆子和若干盘子;
- 根据汉诺塔问题的递归算法,提供一个自动求解程序,能够从任一状态出发,通过若干步移动达到目标状态。
具体而言,程序的流程如下:
- 首先,程序打印
How many disks do you want? (1 ~ 5)
,要求输入盘子的数量(要求为1~5)。如果输入Q
,则退出程序。不合法的输入应当忽略。 - 接下来程序将打印汉诺塔的状态,随后打印
Move a disk. Format: x y
,要求用户给出指令。指令的形式是from to
(例如,2 3
的意思是将杆2最上面的盘子移动到杆3上),不合法的输入或是不可执行的指令应该忽略。在这之后,无论指令是否合法,程序总是重新打印一遍当前状态,并重新要求用户输入。 - 如果输入的指令为
0 0
,则进入自动模式。程序需要首先将用户已经执行的指令反过来执行一遍,复原到初始状态,然后再按照递归算法执行。每次执行时,程序通过输出Auto moving:x->y
告知用户所执行的指令。注意:即使有其他方法从当前状态直接到达目标状态,也请按照先复原后执行的方式进行。这是因为自动评测的时候会直接比对输出内容。 - 无论是通过用户指令或是自动模式,只要达成目标状态(即所有盘子都移到杆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
具体实现:
本文来自博客园,作者:O_fly_O,转载请注明原文链接:https://www.cnblogs.com/world-explorer/p/16147254.html