設計并實作一個游戲:漢諾塔,
完成這個實驗,涉及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
具體實作:
GitHub:https://github.com/Fly0307/SEP_lab3
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/458194.html
標籤:C++
