🕹回憶殺 python實現 華容道(數字版)可線上玩

更新於 2024/08/27閱讀時間約 1 分鐘
raw-image

華容道(數字版)的遊戲描述


初始給定一個1~15數字隨機打散的4x4遊戲版

使用者透過移動空格來重新排列數字
最後數字排成1~15,而且空格剛好在右下角的時候,遊戲結束。


華容道(數字版)的遊戲場景


遊戲開始時,電腦為玩家建立一個4x4的板子,隨機填充0~15的數字。

數字0代表空格


玩家每回合可以移動空格一次,藉此重新排列板子上的數字


最後數字依序排成1~15,而且空格0剛好在右下角的時候,遊戲結束



上層思考邏輯與框架


建立遊戲場景,為玩家建立一個4x4的板子,隨機填充0~15的數字。

數字0代表空格


每回合都先顯示當下的板子狀態給玩家看。

玩家每回合可以選擇一個和空格相鄰的數字,接著把空格移動到對應的位置,
藉此重新排列板子上的數字


接著檢查所有數字是否已經依序排成1~15,而且空格0剛好在右下角?

如果是,則遊戲結束

如果不是,則遊戲繼續。


中層功能元件分析


1.怎麼建立4x4的遊戲版,並且填充隨機數?


透過list()建構子 和 range()先建立長度為16的list,依序填入0~15的數字。


並且使用python內建的random.shuffle()方法,

進行隨機採樣,打散所有數字的位置。


最後,透過List comprehension生成4x4的遊戲版,上面帶著隨機生成的0~15的數字。

class FifteenPuzzle:
def __init__(self):
# 生成4x4的遊戲版
self.board = self.create_board()

# 紀錄空格所在的位置
self.empty_tile = self.find_empty()

def find_empty(self):
# 找空格所在的位置
for y in range(4):
for x in range(4):
if self.board[y][x] == 0:
return y, x

return -1, -1

def create_board(self):
# 生成4x4的遊戲版
tiles = list(range(0, 16))
random.shuffle(tiles)
return [tiles[i:i+4] for i in range(0, 16, 4)]

2.怎麼顯示4x4的遊戲版當下的遊戲狀態?


用雙層迴圈去做輸出排版,印出4x4遊戲版當下的內容。


  def display_board(self):

for row in self.board:
print(' '.join(f'{tile:2}' for tile in row))
print()
return

3.怎麼移動空格(空格用特殊數字0來代表)?


先找出使用者輸入的數字,
接著把空格(用特殊數字0來代表)移動到使用者指定的數字所在的位置上。


  def move_tile(self, tile):

y, x = self.empty_tile
for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
nx, ny = x + dx, y + dy
if 0 <= nx < 4 and 0 <= ny < 4 and self.board[ny][nx] == tile:

# 移動空格
self.board[y][x], self.board[ny][nx] = self.board[ny][nx], self.board[y][x]

# 紀錄空格在移動後的新位置
self.empty_tile = (ny, nx)
return True
return False

4.怎麼判斷遊戲是否已經結束?


每回合檢查所有數字是否已經依序排成1~15,而且空格剛好在右下角?

如果是,則遊戲結束

如果不是,則遊戲繼續。


  def is_solved(self):

# 完全排好的狀態
answer = [list(range(i, i+4)) for i in range(1, 16, 4)]
answer[-1][-1] = 0

'''
[
[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[ 13, 14, 15, 0]
]
'''

# 檢查是否已經排好所有數字
return self.board == answer

5.如何建立遊戲的回合循環機制?


每回合先呼叫 is_solved()檢查是否遊戲結束

如果遊戲還沒結束,就進入while本體
等待使用者輸入數字,透過移動空格去重新排列遊戲版上的數字。



def play():

game = FifteenPuzzle()
while not game.is_solved():
game.display_board()
try:

tile = int(input("Enter the number to move (-1 to quit): "))
if tile == -1:
break

if not game.move_tile(tile):
print("Invalid move!")

except ValueError:
print("Please enter a valid number.")

print("Congratulations! You solved the puzzle!")

底層的完整實作: 華榮道(數字版)

import random

class FifteenPuzzle:
def __init__(self):
self.board = self.create_board()
self.empty_tile = self.find_empty()

def find_empty(self):
for y in range(4):
for x in range(4):
if self.board[y][x] == 0:
return y, x

return -1, -1

def create_board(self):

tiles = list(range(0, 16))
random.shuffle(tiles)
return [tiles[i:i+4] for i in range(0, 16, 4)]


def display_board(self):

for row in self.board:
print(' '.join(f'{tile:2}' for tile in row))
print()
return


def move_tile(self, tile):
y, x = self.empty_tile
for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
nx, ny = x + dx, y + dy
if 0 <= nx < 4 and 0 <= ny < 4 and self.board[ny][nx] == tile:
self.board[y][x], self.board[ny][nx] = self.board[ny][nx], self.board[y][x]
self.empty_tile = (ny, nx)
return True
return False


def is_solved(self):
answer = [list(range(i, i+4)) for i in range(1, 16, 4)]
answer[-1][-1] = 0
'''
[
[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[ 13, 14, 15, 0]
]
'''
return self.board == answer


def play():

game = FifteenPuzzle()
while not game.is_solved():
game.display_board()
try:

tile = int(input("Enter the number to move (-1 to quit): "))
if tile == -1:
break

if not game.move_tile(tile):
print("Invalid move!")

except ValueError:
print("Please enter a valid number.")

print("Congratulations! You solved the puzzle!")

if __name__ == "__main__":
play()

試玩畫面

raw-image

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


延伸思考:


如果對程式或者演算法有興趣的同學,

可以試著觀察華榮道移動數字的規律,

開發更強的解題演算法嘗試用最少的移動步數去重新排好所有的數字

很有趣喔~

avatar-img
90會員
425內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
從範例學python的目標讀者: 針對剛進入的初學者,想學習Python語言。 有基礎本數學邏輯基礎即可。 從小遊戲學python的目標讀者: 針對已經有經驗的C/C++, Python, 或其他有程式基礎的讀者。 想實作一些小專案,從實做中學習如何分析需求、元件分拆、到底層實作
賓果的遊戲描述 在一個5x5的方陣上隨機填充1~25的數字。 玩家(使用者) 和 電腦(AI)輪流叫一個號碼,最先占據一整條直線連線的獲勝。 就像小時候玩的bingo 賓果連線遊戲一樣! (可以是占據兩條對角線,可以是占據水平直線,可以是占據垂直直線)
河內塔的遊戲描述 有三個柱子A柱,B柱,C柱。 A柱上有 N 個 (N>1) 穿孔圓盤,盤的尺寸由下到上依次變小。 要求按下列規則透過合法移動,將所有圓盤移至 C 柱: 1. 每次只能移動頂端的一個圓盤; 2. 大圓盤不能疊在小圓盤上面。
今天要實作和體驗的是拼單字的小遊戲,類似小時候在報紙、英文童書、或著電子辭典的小遊戲,一開始都是空白,隨著使用者拼對而逐漸顯示原本的單字樣貌,直到整個單字拼出來為止。 場景: 電腦隨機從單字庫裡面撈一個單字出來。 讓使用者扮演玩家去玩拼單字的遊戲。
相信大家小時候都有和朋友或玩伴玩過一個猜數字的小遊戲,一個人先在1~100裡面設定一個隱藏數字,其他的人去猜,看誰是最後一個猜中的就算輸,或者看誰最快猜中就算贏。 今天要示範如何用Python寫一個猜數字遊戲, 並且會從上層的思考邏輯開始,一步步構建出這個猜數字的小遊戲。
從範例學python的目標讀者: 針對剛進入的初學者,想學習Python語言。 有基礎本數學邏輯基礎即可。 從小遊戲學python的目標讀者: 針對已經有經驗的C/C++, Python, 或其他有程式基礎的讀者。 想實作一些小專案,從實做中學習如何分析需求、元件分拆、到底層實作
賓果的遊戲描述 在一個5x5的方陣上隨機填充1~25的數字。 玩家(使用者) 和 電腦(AI)輪流叫一個號碼,最先占據一整條直線連線的獲勝。 就像小時候玩的bingo 賓果連線遊戲一樣! (可以是占據兩條對角線,可以是占據水平直線,可以是占據垂直直線)
河內塔的遊戲描述 有三個柱子A柱,B柱,C柱。 A柱上有 N 個 (N>1) 穿孔圓盤,盤的尺寸由下到上依次變小。 要求按下列規則透過合法移動,將所有圓盤移至 C 柱: 1. 每次只能移動頂端的一個圓盤; 2. 大圓盤不能疊在小圓盤上面。
今天要實作和體驗的是拼單字的小遊戲,類似小時候在報紙、英文童書、或著電子辭典的小遊戲,一開始都是空白,隨著使用者拼對而逐漸顯示原本的單字樣貌,直到整個單字拼出來為止。 場景: 電腦隨機從單字庫裡面撈一個單字出來。 讓使用者扮演玩家去玩拼單字的遊戲。
相信大家小時候都有和朋友或玩伴玩過一個猜數字的小遊戲,一個人先在1~100裡面設定一個隱藏數字,其他的人去猜,看誰是最後一個猜中的就算輸,或者看誰最快猜中就算贏。 今天要示範如何用Python寫一個猜數字遊戲, 並且會從上層的思考邏輯開始,一步步構建出這個猜數字的小遊戲。
你可能也想看
Google News 追蹤
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
回憶殺!韓國男團「F.CUZ」即將於7月13日登陸台北,去年原已退團成員李唯重新合流,6位成員JINON、李唯、大建、來炫、KAN、藝浚全員到齊,完整體海外首場FANCON〔GOTCHA OPPA〕更選定於出道後第一個海外行程的台北舉辦,門票於本週六5月18日中午11點在KKTIX全面啟售。
Thumbnail
在小時候的記憶裡,最受喜愛的就是甜甜圈了。每當拿起那圓滾滾的麵包體,就會想起童年時的無憂無慮,單純而快樂的感覺,總是回味無窮。 隨著年齡的增長,發現這個甜點不僅僅是一種美食,更是一種文化的象徵。甜甜圈起源於荷蘭,並由荷蘭移民帶入美國,發展成為一種國民級的美食。
Thumbnail
哇~很熱血的觀賞跨年場,我們2023年(am12:10) 的首場電影「灌籃高手 THE FIRST SLAM DUNK 」原音版。 距劇集版首播逾25年,期間都忘記總共刷幾次了,幾乎所有劇情都券牢記腦海,所以這次觀賞,一切氛圍的非常熟悉。 電影改編自原作最終章《全國大賽篇—湘北VS山王工業》,加以類
Thumbnail
〈庫洛魔法使-動畫播放 25 年閃耀派對〉特展中,除了有人物的人形立牌,以及各式的畫稿外,最吸睛的地方就是有超搶眼的主題情境裝置,讓庫洛可以一秒化身為動漫中的角色。
Thumbnail
最近回憶殺這個詞彙不停的出現在新聞裡,因為歌手王心凌參加了一個節目,表演了20年前的歌曲,勾起很多人的回憶,也勾起了我的回憶。 不過這次因為看到了王心凌的表演片段,透過這個契機我也開始回憶起20年前的自己,當時的自己是什麼樣子,那個時候的自己正經歷著什麼?(20年前我也買過王心凌的CD耶,笑)
Thumbnail
《音速小子2》好看於否,其實很大因素取決於你的童年有沒有藍色刺蝟的存在,否則可能很多人都要開始黑超級索尼克抄襲了。 瘋狂的玩梗,滿滿的回憶殺,《音速小子2》或是說這個系列就是一個100%獻給粉絲的電影,另外附贈一個金凱瑞,我的天,真的很超值。
Thumbnail
這次徵文就決定獻給孤味這部了 它可能不是最好,卻讓我久久無法忘懷
Thumbnail
-寫於2020/11/08      Hi there, 先前分享過楊丞琳及王心凌兩大教主的合作歌曲〈女孩們〉( 兩大天后合體,〈女孩們〉還不快來朝聖!), 最近發現兩人這陣子都祭出回憶殺攻勢,讓歌迷粉絲整個感動到不行,現在就來看看他們最近都有什麼新作品出現吧。
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
回憶殺!韓國男團「F.CUZ」即將於7月13日登陸台北,去年原已退團成員李唯重新合流,6位成員JINON、李唯、大建、來炫、KAN、藝浚全員到齊,完整體海外首場FANCON〔GOTCHA OPPA〕更選定於出道後第一個海外行程的台北舉辦,門票於本週六5月18日中午11點在KKTIX全面啟售。
Thumbnail
在小時候的記憶裡,最受喜愛的就是甜甜圈了。每當拿起那圓滾滾的麵包體,就會想起童年時的無憂無慮,單純而快樂的感覺,總是回味無窮。 隨著年齡的增長,發現這個甜點不僅僅是一種美食,更是一種文化的象徵。甜甜圈起源於荷蘭,並由荷蘭移民帶入美國,發展成為一種國民級的美食。
Thumbnail
哇~很熱血的觀賞跨年場,我們2023年(am12:10) 的首場電影「灌籃高手 THE FIRST SLAM DUNK 」原音版。 距劇集版首播逾25年,期間都忘記總共刷幾次了,幾乎所有劇情都券牢記腦海,所以這次觀賞,一切氛圍的非常熟悉。 電影改編自原作最終章《全國大賽篇—湘北VS山王工業》,加以類
Thumbnail
〈庫洛魔法使-動畫播放 25 年閃耀派對〉特展中,除了有人物的人形立牌,以及各式的畫稿外,最吸睛的地方就是有超搶眼的主題情境裝置,讓庫洛可以一秒化身為動漫中的角色。
Thumbnail
最近回憶殺這個詞彙不停的出現在新聞裡,因為歌手王心凌參加了一個節目,表演了20年前的歌曲,勾起很多人的回憶,也勾起了我的回憶。 不過這次因為看到了王心凌的表演片段,透過這個契機我也開始回憶起20年前的自己,當時的自己是什麼樣子,那個時候的自己正經歷著什麼?(20年前我也買過王心凌的CD耶,笑)
Thumbnail
《音速小子2》好看於否,其實很大因素取決於你的童年有沒有藍色刺蝟的存在,否則可能很多人都要開始黑超級索尼克抄襲了。 瘋狂的玩梗,滿滿的回憶殺,《音速小子2》或是說這個系列就是一個100%獻給粉絲的電影,另外附贈一個金凱瑞,我的天,真的很超值。
Thumbnail
這次徵文就決定獻給孤味這部了 它可能不是最好,卻讓我久久無法忘懷
Thumbnail
-寫於2020/11/08      Hi there, 先前分享過楊丞琳及王心凌兩大教主的合作歌曲〈女孩們〉( 兩大天后合體,〈女孩們〉還不快來朝聖!), 最近發現兩人這陣子都祭出回憶殺攻勢,讓歌迷粉絲整個感動到不行,現在就來看看他們最近都有什麼新作品出現吧。