iT邦幫忙

2025 iThome 鐵人賽

DAY 23
0
自我挑戰組

順著感覺走!從零開始的 Python & Vibe Coding 遊戲創作系列 第 23

第23天:勝負的懸念:回合推進與遊戲結束的精密判斷

  • 分享至 

  • xImage
  •  

嗨,各位程式碼冒險家!歡迎來到我的「順著感覺走!從零開始的 Python & Vibe Coding 遊戲創作
」第二十三天。一場精彩的卡牌對決,不僅要有刺激的攻防,還需要一套穩定可靠的底層機制來維持遊戲的節奏,並在關鍵時刻宣告最終的勝者。今天,我們將深入 GameManager 類別,剖析兩個扮演著遊戲心跳與終局裁判角色的核心方法:advance_turncheck_game_over

advance_turn 負責處理回合結束後的所有結算與準備工作,確保戰局流暢推進。而 check_game_over 則像一位時刻關注戰場的裁判,不斷檢查各種結束條件,隨時準備做出最終的裁決。


一、回合推進的藝術:advance_turn 方法

當一方玩家結束其所有行動後,advance_turn 方法會被呼叫,它就像一個自動化的場務總管,有條不紊地執行一系列至關重要的任務,為下一回合的開始鋪平道路。

1. 手牌與桌面牌堆的平衡管理

為了維持遊戲的平衡性與續航力,卡牌資源的管理至關重要。

  • 手牌上限處理 (強制棄牌):為防止玩家無限囤積手牌,advance_turn 會檢查當前回合結束的玩家,其手牌數是否超過上限 (max_hand_size,預設為 10 張)。如果超過,系統會使用 while 迴圈與 random.randint隨機棄掉多餘的牌直到符合上限為止。
  • 手牌補充:為了確保玩家在下個回合有足夠的戰術選項,如果手牌數量低於 5 張,系統會自動從牌組 (remaining_deck) 中補充 2 張新牌。
  • 桌面牌堆補充:桌面 (center_pile) 是戰術互動的核心。若桌面牌數低於最低門檻 (min_center_cards,預設為 5 張),系統會呼叫 draw_card_to_center 方法,從牌組翻開新牌進行補充,確保戰場始終充滿機會。
2. 回合與玩家的精妙切換

完成所有牌堆管理後,advance_turn 會執行回合的切換與狀態重置。

程式碼實現 (gamemanager.py)
def advance_turn(self):
    current_player = self.get_current_player()

    # ... (手牌與桌面牌的補充與棄牌邏輯) ...

    # 1. 重置玩家當回合的臨時狀態
    current_player.reset_for_turn()

    # 2. 切換當前玩家索引
    self.current_player_index = 1 - self.current_player_index

    # 3. 如果輪到玩家 (索引為 0),則增加回合數
    if self.current_player_index == 0:
        self.turn_count += 1
    
    # 4. 記錄新回合開始的日誌
    self.add_to_log(f"--- 第 {self.turn_count} 回合開始 ---")

    # 5. 重置新回合的行動計數器
    self.action_count = 0
    
    # 6. 檢查遊戲是否結束
    game_over_result = self.check_game_over()
    if game_over_result:
        self.game_state = "GAME_OVER"
        # ... (處理遊戲結束後的音效與日誌) ...
    elif self.current_player_index == 0:
        self.game_state = "PLAYER_TURN"
    else:
        self.game_state = "ENEMY_TURN"
  • 技術細節解析
    • self.current_player_index = 1 - self.current_player_index:這行程式碼是個非常巧妙的技巧。它利用簡單的數學運算,在 0 (玩家) 和 1 (敵人) 之間來回切換,精準地實現了回合交替。
    • self.turn_count += 1:只有當索引切換回玩家 (0) 時,回合數才會增加,這確保了一次完整的「玩家回合 + 敵人回合」才算一個大回合。
    • self.action_count = 0:在切換玩家後,立即將行動計數器歸零,為新回合的玩家提供完整的 5 次行動機會。

二、最終的裁決:check_game_over 方法

在每次回合推進後,advance_turn 都會呼叫 check_game_over 方法來檢查是否觸發了任何遊戲結束條件。這個方法是遊戲的最終裁判,確保戰鬥能在適當時機劃下句點。

程式碼實現 (gamemanager.py)
def check_game_over(self):
    """檢查遊戲是否結束,並返回結果。"""
    # 1. 檢查玩家是否戰敗
    if self.players.health <= 0:
        return "lose"  # 代表玩家輸了
        
    # 2. 檢查敵方是否戰敗
    if self.players.health <= 0:
        return "win"   # 代表玩家贏了

    # 3. 檢查牌組是否耗盡
    if len(self.remaining_deck) == 0:
        if self.players.health > self.players.health:
            return "win"
        elif self.players.health < self.players.health:
            return "lose"
        else: # 血量相等
            return "tie"
            
    # 4. 檢查是否達到最大回合數 (此邏輯在 advance_turn 內觸發)
    if self.turn_count > self.max_rounds:
        # ... (比較血量高低,返回 "win", "lose", 或 "tie")
        
    # 如果所有條件都不滿足,遊戲繼續
    return None
遊戲結束條件解析
  1. 生命值歸零:這是最直接的勝負條件。程式會逐一檢查玩家與敵人的 health 屬性,一旦任何一方的生命值降至 0 或以下,遊戲立即結束,並返回對應的勝負結果。
  2. 牌組耗盡:當 self.remaining_deck 的長度變為 0 時,代表牌組已抽完。此時,遊戲會比較雙方當前的生命值,血量較高者獲勝;若血量相同,則為平局
  3. 最大回合數:遊戲設有 self.max_rounds (預設為 15 回合) 的上限,以防止戰局無限延長。當 self.turn_count 超過這個數值時,同樣會依據生命值高低來裁定勝負。

透過 advance_turn 的流暢推進與 check_game_over 的多重精密判斷,我們成功地為《奇幻卡牌競技場》建立了一套完整且穩定的遊戲循環與終局機制。這套系統確保了遊戲的節奏感、策略性以及明確的勝負目標,讓玩家可以完全沉浸在卡牌對決的樂趣之中。

明天,我們將踏入視覺化的世界,學習如何使用 Pygame 點亮我們的冒險舞台!敬請期待!


上一篇
第二十二天:智慧的對決:敵人 AI 的回合行動與配對策略 (下)
下一篇
第二十四天:點亮冒險世界:Pygame 遊戲視窗與背景的藝術
系列文
順著感覺走!從零開始的 Python & Vibe Coding 遊戲創作25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言