用Python實現小遊戲 河內塔 可線上玩 Tower of Hanoi

更新於 發佈於 閱讀時間約 11 分鐘

河內塔的遊戲描述

有三個柱子A柱,B柱,C柱。

A柱上有 N 個穿孔圓盤,圓盤的尺寸由下到上依次變小。
要求按下列規則透過合法移動,將所有圓盤移至 C 柱:

  1. 每次只能移動頂端的一個圓盤;
  2. 大圓盤不能疊在小圓盤上面


N=3的遊戲範例

raw-image



場景:


使用者輸入一個層數n

電腦填充A柱,讓A柱填滿n~1的正整數,每個數字就對應到圓盤的大小。

接著讓使用者扮演玩家,每次可以移動一個柱子頂端的一個盤子到另一個柱子

如果玩家最後成功把n個圓盤依序從大到小疊好,搬到終點的C柱,則玩家獲勝。
螢幕會秀出成功的提示訊息,並且顯示玩家花了幾步抵達終點。


上層思考邏輯與框架


讓使用者輸入層數n,接著讓電腦建立遊戲場景,填充A柱


遊戲開始後,讓玩家自由選擇要從哪個柱子開始移動圓盤到另一個柱子。


移動的過程中,電腦會判斷玩家的操作是否合法(也就是大圓盤不可以疊在小圓盤之上)。

如果合法,就把對應的圓盤移動過去。

過程中會統計移動步數。


若玩家最後成功把n個圓盤依序從大到小疊好,搬到終點的C柱,則玩家獲勝

螢幕會秀出成功的提示訊息,並且顯示玩家花了幾步抵達終點。


中層功能元件分析

1.怎麼接收使用者輸入?

python提供內建的input("提示訊息")的標準輸入function,

接收到的預設型別是字串。

接收層數時,記得要轉型成整數integer在儲存在變數n裡。

n = int( input("Please input level number of hanoi tower: ") )


接收移動圓盤的柱子時,直接接收字串即可。

src 代表要從哪個柱子拿起最上面的圓盤。

dest代表這個圓盤要放到哪個柱子。

src = input("Pick a tower to pick disk: ")

dest = input("Pick a tower to place disk: ")


2.怎麼建立遊戲場景,填充A柱?

遊戲場景總共有三個柱子A 柱, B柱, C柱,分別對應到三個堆疊。

# A, B, C
place = [ [], [], [] ]

# A柱對應到place[0]
# B柱對應到place[1]
# C柱對應到place[2]
mapping = {'A': 0, 'B': 1, 'C':2}


電腦根據n值,把A柱從下往上填滿n~1的正整數,
總個n個圓盤,數字的大小就代表圓盤的大小。


同時,會初始化步數為0。

之後步數會隨著玩家的操作而跟著累加上去。

def initialize(n, src):

  # 起點柱填充正整數 n ~ 1 ,代表碟子的大小
  place[ mapping[src] ] = [i for i in range(n, 0, -1) ]

  # 初始化總步數 = 0
  move_disk.step = 0

  return


3.怎麼建立C柱的解答?

目標是把所有的圓盤搬到C柱,從下往上 由大到小疊好所有的圓盤。

終點C柱的解答其實也是從下往上疊滿n~1的正整數,

我們只要把A柱一開始的樣子複製一份,就可以當作最終C柱的解答。

final_state = place[ mapping['A'] ].copy()


4.如何建立循環(相當於程式語言中迴圈的邏輯)?


如果 還有C柱還沒和解答的樣子相等:

則繼續遊戲...


對應到python的程式碼,就是while 的迴圈與流程控制

    while place[ mapping['C'] ] != final_state:

src = input("Pick a tower to pick disk: ")
dest = input("Pick a tower to place disk: ")

move_disk(src, dest)
showStatus()


5.怎麼移動圓盤到另一個柱子?


從使用者指定的src柱子移動到另一個dest柱子。

移動成功之後,步數step累加1


移動的時候,電腦會檢查是否為合法操作:

5-1.搬移的起點柱src不可以是空的。

5-2.大的圓盤不可以疊在小的圓盤之上


def move_disk(src, dest):

# src柱不可以是空的
if not place[ mapping[src] ]:
print(f"Tower {src} is empty!")
return

# 大的圓盤不可以疊在小的圓盤之上。
if place[ mapping[dest] ] and ( place[ mapping[src] ][-1] > place[ mapping[dest] ][-1] ):
print(f"Cannot place larger disk over smaller disk!")
return

# update總步數
move_disk.step += 1

cur = place[ mapping[src] ].pop()
place[ mapping[dest] ].append( cur )

print(f"Step {move_disk.step}: Move disk {cur} from {src} to {dest}.")

return


6.怎麼顯示當前的遊戲狀態?


依序把A柱、B柱、C柱的狀態顯示在螢幕上即可。


def showStatus():

print(f"Status is shown as folloing.")
print(f"A: { place[0]} ")
print(f"B: { place[1]} ")
print(f"C: { place[2]} ")
print()
return


7.遊戲成功後,怎麼顯示玩家勝利的訊息?


當C柱的狀態等於解答,也就是玩家成功把n個圓盤從大到小疊好後,
輸出玩家獲勝的訊息,並寫顯示玩家總共用了幾步完成遊戲。


    total_step = move_disk.step         

print(f"Good job, you finish the game with {total_step} steps.")
return total_step

底層的完整實作: 小遊戲 河內塔 Tower of Hanoi

# A柱, B柱, C柱
place = [ [], [], [] ]

# A柱對應到place[0]
# B柱對應到place[1]
# C柱對應到place[2]
mapping = {'A': 0, 'B': 1, 'C':2}

def showStatus():

print(f"Status is shown as folloing.")
print(f"A: { place[0]} ")
print(f"B: { place[1]} ")
print(f"C: { place[2]} ")
print()
return

def move_disk(src, dest):

if not place[ mapping[src] ]:
print(f"Tower {src} is empty!")
return

if place[ mapping[dest] ] and ( place[ mapping[src] ][-1] > place[ mapping[dest] ][-1] ):
print(f"Cannot place larger disk over smaller disk!")
return

# update總步數
move_disk.step += 1

cur = place[ mapping[src] ].pop()
place[ mapping[dest] ].append( cur )

print(f"Step {move_disk.step}: Move disk {cur} from {src} to {dest}.")

return


def initialize(n, src):
# 起點柱填充正整數 n ~ 1 ,代表碟子的大小
place[ mapping[src] ] = [i for i in range(n, 0, -1) ]

# 初始化總步數 = 0
move_disk.step = 0
return


def play(n):

# 填滿起點A柱
initialize(n, src='A')
showStatus()

# 設定解答狀態
final_state = place[ mapping['A'] ].copy()

while place[ mapping['C'] ] != final_state:

src = input("Pick a tower to pick disk: ")
dest = input("Pick a tower to place disk: ")
move_disk(src, dest)
showStatus()

total_step = move_disk.step

print(f"Good job, you finish the game with {total_step} steps.")
return total_step


if __name__ == "__main__":
n = int( input("Please input level number of honoi tower: ") )
play(n)



試玩畫面

raw-image

線上執行 與 試玩(在新的頁面按Run開始玩)

https://bit.ly/4clCg1q


延伸思考:


如果對程式或者演算法有興趣的同學,
可以試著觀察圓盤的移動規律,想出演算法,寫個解題程式,
能夠用最少的步數,解開河內塔這個遊戲!

很有趣喔~

留言
avatar-img
留言分享你的想法!
avatar-img
小松鼠的演算法樂園
96會員
427內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
2024/09/27
井字遊戲(OOXX)的遊戲描述 Tic Tac Toe(井字遊戲)是經典的雙人棋盤遊戲,在一個3x3的方格中進行。 每回合兩個玩家輪流選一個位置,先讓自己的符號(是 X 或 O)在 水平線、垂直線或對角線上連成一線的玩家宣告獲勝。
Thumbnail
2024/09/27
井字遊戲(OOXX)的遊戲描述 Tic Tac Toe(井字遊戲)是經典的雙人棋盤遊戲,在一個3x3的方格中進行。 每回合兩個玩家輪流選一個位置,先讓自己的符號(是 X 或 O)在 水平線、垂直線或對角線上連成一線的玩家宣告獲勝。
Thumbnail
2024/08/27
華容道(數字版)的遊戲描述 初始給定一個1~15數字隨機打散的4x4遊戲版, 讓使用者透過移動空格來重新排列數字, 最後數字排成1~15,而且空格剛好在右下角的時候,遊戲結束。
Thumbnail
2024/08/27
華容道(數字版)的遊戲描述 初始給定一個1~15數字隨機打散的4x4遊戲版, 讓使用者透過移動空格來重新排列數字, 最後數字排成1~15,而且空格剛好在右下角的時候,遊戲結束。
Thumbnail
2024/08/13
從範例學python的目標讀者: 針對剛進入的初學者,想學習Python語言。 有基礎本數學邏輯基礎即可。 從小遊戲學python的目標讀者: 針對已經有經驗的C/C++, Python, 或其他有程式基礎的讀者。 想實作一些小專案,從實做中學習如何分析需求、元件分拆、到底層實作
Thumbnail
2024/08/13
從範例學python的目標讀者: 針對剛進入的初學者,想學習Python語言。 有基礎本數學邏輯基礎即可。 從小遊戲學python的目標讀者: 針對已經有經驗的C/C++, Python, 或其他有程式基礎的讀者。 想實作一些小專案,從實做中學習如何分析需求、元件分拆、到底層實作
Thumbnail
看更多
你可能也想看
Thumbnail
2025 vocus 推出最受矚目的活動之一——《開箱你的美好生活》,我們跟著創作者一起「開箱」各種故事、景點、餐廳、超值好物⋯⋯甚至那些讓人會心一笑的生活小廢物;這次活動不僅送出了許多獎勵,也反映了「內容有價」——創作不只是分享、紀錄,也能用各種不同形式變現、帶來實際收入。
Thumbnail
2025 vocus 推出最受矚目的活動之一——《開箱你的美好生活》,我們跟著創作者一起「開箱」各種故事、景點、餐廳、超值好物⋯⋯甚至那些讓人會心一笑的生活小廢物;這次活動不僅送出了許多獎勵,也反映了「內容有價」——創作不只是分享、紀錄,也能用各種不同形式變現、帶來實際收入。
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
Thumbnail
河內塔的遊戲描述 有三個柱子A柱,B柱,C柱。 A柱上有 N 個 (N>1) 穿孔圓盤,盤的尺寸由下到上依次變小。 要求按下列規則透過合法移動,將所有圓盤移至 C 柱: 1. 每次只能移動頂端的一個圓盤; 2. 大圓盤不能疊在小圓盤上面。
Thumbnail
河內塔的遊戲描述 有三個柱子A柱,B柱,C柱。 A柱上有 N 個 (N>1) 穿孔圓盤,盤的尺寸由下到上依次變小。 要求按下列規則透過合法移動,將所有圓盤移至 C 柱: 1. 每次只能移動頂端的一個圓盤; 2. 大圓盤不能疊在小圓盤上面。
Thumbnail
中國跳棋的棋盤有6個角,最多可供6人進行遊戲,每個人把各自同顏色的棋子擺滿一個角,按照規則輪流走棋,以最早全部抵達並擺滿對角為優勝。 若是2人或4人對局,那麼將棋子放在相對的角上;3人對局則將棋子互相間隔一個角擺放以平均分布;6人對局為將所有角擺滿。因為平衡性要求,不宜進行5人遊戲。 每方棋
Thumbnail
中國跳棋的棋盤有6個角,最多可供6人進行遊戲,每個人把各自同顏色的棋子擺滿一個角,按照規則輪流走棋,以最早全部抵達並擺滿對角為優勝。 若是2人或4人對局,那麼將棋子放在相對的角上;3人對局則將棋子互相間隔一個角擺放以平均分布;6人對局為將所有角擺滿。因為平衡性要求,不宜進行5人遊戲。 每方棋
Thumbnail
本週桌遊活動再起,玩了三國殺、犯人在跳舞、UNO疊疊樂、推倒提基、誰是內鬼、奶烙大盜......等。歡樂整個早上。 這些桌遊有些是歡樂的、是派對的,有些是邏輯推理思考的。這一團孩子比較大一點,可以玩些比較難的桌遊,所以就推了不少邏輯思考的桌遊。 看她們的思維還不錯,推了一款很新的桌遊-
Thumbnail
本週桌遊活動再起,玩了三國殺、犯人在跳舞、UNO疊疊樂、推倒提基、誰是內鬼、奶烙大盜......等。歡樂整個早上。 這些桌遊有些是歡樂的、是派對的,有些是邏輯推理思考的。這一團孩子比較大一點,可以玩些比較難的桌遊,所以就推了不少邏輯思考的桌遊。 看她們的思維還不錯,推了一款很新的桌遊-
Thumbnail
塔羅的祕密,塔羅的遊戲規則,塔羅的神祕原理.....
Thumbnail
塔羅的祕密,塔羅的遊戲規則,塔羅的神祕原理.....
Thumbnail
星盤棋 雙方各只有用十五枚基本棋。起始布置雙方各有三子環狀交錯放在六頂角上。雙方的基本棋子則各剩下十二枚,放在玩家旁作為棋庫。 每回合玩家從棋庫取一己子,將之從棋盤外黑點推入一棋格。該行方向緊密的棋子也會隨此動作一起移動一棋格。要是該行已充滿棋子,則無法推入。 當己方棋子有四枚以上緊密連線,
Thumbnail
星盤棋 雙方各只有用十五枚基本棋。起始布置雙方各有三子環狀交錯放在六頂角上。雙方的基本棋子則各剩下十二枚,放在玩家旁作為棋庫。 每回合玩家從棋庫取一己子,將之從棋盤外黑點推入一棋格。該行方向緊密的棋子也會隨此動作一起移動一棋格。要是該行已充滿棋子,則無法推入。 當己方棋子有四枚以上緊密連線,
Thumbnail
曼哈坦 第一次玩覺得規則不會到很難,但又很需要思考及合作,因為是四人一組,所以玩到後面就變成二打二,非常的有趣。 一開始大家都很和平,我也想說先放比較小的建築,並且以多為主,但到了第二回合,就開始互相比誰的比較高,所以這時後就變成一打一,也從這時後開始,分數就越來越少,後來也變最少分,但中間玩的
Thumbnail
曼哈坦 第一次玩覺得規則不會到很難,但又很需要思考及合作,因為是四人一組,所以玩到後面就變成二打二,非常的有趣。 一開始大家都很和平,我也想說先放比較小的建築,並且以多為主,但到了第二回合,就開始互相比誰的比較高,所以這時後就變成一打一,也從這時後開始,分數就越來越少,後來也變最少分,但中間玩的
Thumbnail
曼哈頓 規則https://punchboardgame.pixnet.net/blog/post/463394453 這是一款老桌遊,規則和計分方式相對簡單,但整體的遊玩體驗是很好的。 我所遊玩的是新版的擴充版本,增加了額外的計分規則,也會讓每一次的策略都有所變化,最後呈現出完全不同的結果。
Thumbnail
曼哈頓 規則https://punchboardgame.pixnet.net/blog/post/463394453 這是一款老桌遊,規則和計分方式相對簡單,但整體的遊玩體驗是很好的。 我所遊玩的是新版的擴充版本,增加了額外的計分規則,也會讓每一次的策略都有所變化,最後呈現出完全不同的結果。
Thumbnail
W5 3/18 《曼哈頓》 雖然遊戲規則感覺很簡單,但很重策略(對我來說),要一直思考如何分佈建築才能得高分,還有目標針對誰之類的,但我覺得設計的不錯,很有趣。 《機密代碼》 這款遊戲學校有,我也玩過,但是老師有改一個規則分攤隊長的壓力,我覺得很不錯,是很有效的規則,我們玩了兩局,都是紅隊贏
Thumbnail
W5 3/18 《曼哈頓》 雖然遊戲規則感覺很簡單,但很重策略(對我來說),要一直思考如何分佈建築才能得高分,還有目標針對誰之類的,但我覺得設計的不錯,很有趣。 《機密代碼》 這款遊戲學校有,我也玩過,但是老師有改一個規則分攤隊長的壓力,我覺得很不錯,是很有效的規則,我們玩了兩局,都是紅隊贏
Thumbnail
桌遊的魅力真的很特別,即使是現在大家都習慣滑手機的時代,有時候在聚會時特地玩一款桌遊或紙牌遊戲,還是能帶給大家很多的歡笑。 特別記錄自己在過年時玩到的一款撲克接龍,它有一些數學的概念很適合作為教具使用,當然本身也簡單好上手,遊玩的人數也算多,推薦給大家!
Thumbnail
桌遊的魅力真的很特別,即使是現在大家都習慣滑手機的時代,有時候在聚會時特地玩一款桌遊或紙牌遊戲,還是能帶給大家很多的歡笑。 特別記錄自己在過年時玩到的一款撲克接龍,它有一些數學的概念很適合作為教具使用,當然本身也簡單好上手,遊玩的人數也算多,推薦給大家!
Thumbnail
一分鐘就融入,不會格格不入—— 線上也能玩。
Thumbnail
一分鐘就融入,不會格格不入—— 線上也能玩。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News