## python遊戲設計 ### 範本1:井字遊戲 ```python= # 設計井字遊戲需要以下的函數 # 印出井字盤 # 檢查贏家 # 主程式 def 印出井字盤(井字盤): print(井字盤[0] + '|' + 井字盤[1] + '|' + 井字盤[2]) print('-+-+-') print(井字盤[3] + '|' + 井字盤[4] + '|' + 井字盤[5]) print('-+-+-') print(井字盤[6] + '|' + 井字盤[7] + '|' + 井字盤[8]) def 檢查贏家(井字盤, 符號): 贏的組合 = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], # 水平 [0, 3, 6], [1, 4, 7], [2, 5, 8], # 垂直 [0, 4, 8], [2, 4, 6] # 對角線 ] for 組合 in 贏的組合: if 井字盤[組合[0]] == 井字盤[組合[1]] == 井字盤[組合[2]] == 符號: return True return False def 主程式(): 井字盤 = ['1', '2', '3', '4', '5', '6', '7', '8', '9'] 玩家 = 'X' 輸贏平局 = None # while Ture = 一直跑下去 while True: 印出井字盤(井字盤) 輸入位置 = input(f'請玩家 {玩家} 輸入位置(1-9):') if 輸入位置.isdigit() and 1 <= int(輸入位置) <= 9: 輸入位置 = int(輸入位置) - 1 if 井字盤[輸入位置] == 'X' or 井字盤[輸入位置] == 'O': print('該位置已被佔據,請重新輸入。') else: 井字盤[輸入位置] = 玩家 if 檢查贏家(井字盤, 玩家): 印出井字盤(井字盤) print(f'恭喜玩家 {玩家} 獲勝!') 輸贏平局 = '贏' break # 跳出while-loop elif all(位置 == 'X' or 位置 == 'O' for 位置 in 井字盤): 印出井字盤(井字盤) print('平局!') 輸贏平局 = '平局' break # 跳出while-loop 玩家 = 'O' if 玩家 == 'X' else 'X' else: print('輸入無效,請輸入1到9之間的數字。') if 輸贏平局 is None: print('遊戲結束。') if __name__ == '__main__': 主程式() ``` 執行結果: ![image](https://hackmd.io/_uploads/BkdJhWvVp.png) ### 範本2:踩地雷 ```python= # 創造一個踩地雷遊戲呢? # 創建地雷地圖 # 顯示遊戲地圖 # 檢查合法性 # 計算周圍地雷數 # 檢查地雷 # 顯示地雷地圖 import random 中文數字 = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] def 創建地雷地圖(行數, 列數, 地雷數): 地雷地圖 = [['O' for _ in range(列數)] for _ in range(行數)] 隨機地雷位置 = random.sample(range(行數 * 列數), 地雷數) for 位置 in 隨機地雷位置: 行 = 位置 // 列數 列 = 位置 % 列數 地雷地圖[行][列] = 'X' return 地雷地圖 def 顯示遊戲地圖(遊戲地圖): for 行 in 遊戲地圖: print(' '.join(行)) def 檢查合法性(行, 列, 行數, 列數): return 0 <= 行 < 行數 and 0 <= 列 < 列數 def 計算周圍地雷數(地雷地圖, 行, 列): 周圍地雷數 = 0 鄰居方向 = [(1, 0), (-1, 0), (0, 1), (0, -1), (1, 1), (-1, -1), (1, -1), (-1, 1)] for dx, dy in 鄰居方向: 新行, 新列 = 行 + dx, 列 + dy if 檢查合法性(新行, 新列, len(地雷地圖), len(地雷地圖[0])) and 地雷地圖[新行][新列] == 'X': 周圍地雷數 += 1 return 周圍地雷數 def 檢查地雷(地雷地圖, 行, 列): if 地雷地圖[行][列] == 'X': return True return False def 顯示地雷地圖(地雷地圖): for 行 in 地雷地圖: print(' '.join(行)) def 主程式(): print('歡迎來到踩地雷遊戲!') 行數 = int(input('請輸入行數:')) 列數 = int(input('請輸入列數:')) 地雷數 = int(input('請輸入地雷數:')) 地雷地圖 = 創建地雷地圖(行數, 列數, 地雷數) 遊戲地圖 = [['□' for _ in range(列數)] for _ in range(行數)] 顯示遊戲地圖(遊戲地圖) while True: #try: # 行 = int(input('請輸入行數(1-{0}): '.format(行數))) - 1 # 列 = int(input('請輸入列數(1-{0}): '.format(列數))) - 1 #except ValueError: # print('請輸入有效的數字。') # continue 位置 = input('請輸入要檢查的位置 (例如: 1,3):') try: 行, 列 = map(int, 位置.split(',')) 行 -= 1 列 -= 1 except ValueError: print('請輸入有效的位置 (例如: 1,3)。') continue if not 檢查合法性(行, 列, 行數, 列數) or 遊戲地圖[行][列] != '□': print('請輸入有效的行數和列數。') continue if 檢查地雷(地雷地圖, 行, 列): 顯示地雷地圖(地雷地圖) print('踩到地雷,遊戲結束!') break else: 周圍地雷數 = 計算周圍地雷數(地雷地圖, 行, 列) 遊戲地圖[行][列] = 中文數字[周圍地雷數] 顯示遊戲地圖(遊戲地圖) if __name__ == "__main__": 主程式() ``` 執行結果: ![image](https://hackmd.io/_uploads/BkIM3ZwNa.png) **那我打算挑選踩地雷這個遊戲做一些修改,增加它的遊戲性。** 首先我的想法是加入一個計時系統,除了整局遊戲的計時之外,每一回合玩家思考要輸入哪一格的時 間也會受到限制(預設為五秒鐘),如果超過5秒鐘,即使輸入之後也會直接跳出遊戲顯示gameover 加入一個負責倒數的函數,最大秒數設為5秒 ```python= def 倒數(): countdown_time=5 print(f"倒數 {countdown_time} 秒") time.sleep(1) # 暫停一秒 countdown_time -= 1 ``` 再來就是在每一回合的輸入(決定要踩哪一格)中,加入 紀錄每回合開始當下時間:round_time=time.time() 紀錄每回合結束(有input)當下時間:round_end_time=time.time() 取兩者相減即是每回合所花時間 ```python= def 輸入(): #在輸入裡面再設一個回合計時 round_time=time.time() 位置 = input('請輸入要檢查的位置 (例如: 1,3):') round_end_time=time.time() spend=round_end_time-round_time return 位置,spend #回傳輸入位置跟回合花費時間' ``` 輸入()本來的功能是回傳我要踩的那一格座標,現在多了一個每回合時間 在把座標填入<font color="#f00">**之前**</font> 加入一個if判斷,如果該回合超過5秒,跳出遊戲 ```python= 位置,時間=輸入() if 時間>5: print("超時8888") #時間超過5秒,game over break ``` 最後在執行主程式一樣加入計時 記錄整局遊戲時間 ```python= if __name__ == '__main__': start_time = time.time() 主程式() end_time = time.time() elapsed_time = end_time - start_time print("遊戲時間",elapsed_time,"秒") ``` 完整code ```python= # 創建地雷地圖 # 顯示遊戲地圖 # 檢查合法性 # 計算周圍地雷數 # 檢查地雷 # 顯示地雷地圖 import random import pygame import time import multiprocessing pygame.init() 中文數字 = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] def 創建地雷地圖(行數, 列數, 地雷數): 地雷地圖 = [['O' for _ in range(列數)] for _ in range(行數)] 隨機地雷位置 = random.sample(range(行數 * 列數), 地雷數) for 位置 in 隨機地雷位置: 行 = 位置 // 列數 列 = 位置 % 列數 地雷地圖[行][列] = 'X' return 地雷地圖 def 顯示遊戲地圖(遊戲地圖): for 行 in 遊戲地圖: print(' '.join(行)) def 檢查合法性(行, 列, 行數, 列數): return 0 <= 行 < 行數 and 0 <= 列 < 列數 def 計算周圍地雷數(地雷地圖, 行, 列): 周圍地雷數 = 0 鄰居方向 = [(1, 0), (-1, 0), (0, 1), (0, -1), (1, 1), (-1, -1), (1, -1), (-1, 1)] for dx, dy in 鄰居方向: 新行, 新列 = 行 + dx, 列 + dy if 檢查合法性(新行, 新列, len(地雷地圖), len(地雷地圖[0])) and 地雷地圖[新行][新列] == 'X': 周圍地雷數 += 1 return 周圍地雷數 def 檢查地雷(地雷地圖, 行, 列): if 地雷地圖[行][列] == 'X': return True return False def 顯示地雷地圖(地雷地圖): for 行 in 地雷地圖: print(' '.join(行)) def 倒數(): countdown_time=5 print(f"倒數 {countdown_time} 秒") time.sleep(1) # 暫停一秒 countdown_time -= 1 def 輸入(): #在輸入裡面再設一個回合計時 round_time=time.time() 位置 = input('請輸入要檢查的位置 (例如: 1,3):') round_end_time=time.time() spend=round_end_time-round_time return 位置,spend #回傳輸入位置跟回合花費時間' def 主程式(): print('歡迎來到踩地雷遊戲!') 行數 = int(input('請輸入行數:')) 列數 = int(input('請輸入列數:')) 地雷數 = int(input('請輸入地雷數:')) 地雷地圖 = 創建地雷地圖(行數, 列數, 地雷數) 遊戲地圖 = [['□' for _ in range(列數)] for _ in range(行數)] 顯示遊戲地圖(遊戲地圖) while True: #try: # 行 = int(input('請輸入行數(1-{0}): '.format(行數))) - 1 # 列 = int(input('請輸入列數(1-{0}): '.format(列數))) - 1 #except ValueError: # print('請輸入有效的數字。') # continue 位置,時間=輸入() if 時間>5: print("超時8888") #時間超過5秒,game over break try: 行, 列 = map(int, 位置.split(',')) 行 -= 1 列 -= 1 except ValueError: print('請輸入有效的位置 (例如: 1,3)。') continue if not 檢查合法性(行, 列, 行數, 列數) or 遊戲地圖[行][列] != '□': print('請輸入有效的行數和列數。') continue if 檢查地雷(地雷地圖, 行, 列): 顯示地雷地圖(地雷地圖) print('踩到地雷,遊戲結束!') break else: 周圍地雷數 = 計算周圍地雷數(地雷地圖, 行, 列) 遊戲地圖[行][列] = 中文數字[周圍地雷數] 顯示遊戲地圖(遊戲地圖) if __name__ == '__main__': start_time = time.time() 主程式() end_time = time.time() elapsed_time = end_time - start_time print("遊戲時間",elapsed_time,"秒") ```