嗨,各位程式碼冒險家!歡迎來到我的「順著感覺走!從零開始的 Python & Vibe Coding 遊戲創作
」第二十三天。一場精彩的卡牌對決,不僅要有刺激的攻防,還需要一套穩定可靠的底層機制來維持遊戲的節奏,並在關鍵時刻宣告最終的勝者。今天,我們將深入 GameManager
類別,剖析兩個扮演著遊戲心跳與終局裁判角色的核心方法:advance_turn
與 check_game_over
。
advance_turn
負責處理回合結束後的所有結算與準備工作,確保戰局流暢推進。而 check_game_over
則像一位時刻關注戰場的裁判,不斷檢查各種結束條件,隨時準備做出最終的裁決。
advance_turn
方法當一方玩家結束其所有行動後,advance_turn
方法會被呼叫,它就像一個自動化的場務總管,有條不紊地執行一系列至關重要的任務,為下一回合的開始鋪平道路。
為了維持遊戲的平衡性與續航力,卡牌資源的管理至關重要。
advance_turn
會檢查當前回合結束的玩家,其手牌數是否超過上限 (max_hand_size
,預設為 10 張)。如果超過,系統會使用 while
迴圈與 random.randint
,隨機棄掉多餘的牌直到符合上限為止。remaining_deck
) 中補充 2 張新牌。center_pile
) 是戰術互動的核心。若桌面牌數低於最低門檻 (min_center_cards
,預設為 5 張),系統會呼叫 draw_card_to_center
方法,從牌組翻開新牌進行補充,確保戰場始終充滿機會。完成所有牌堆管理後,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
health
屬性,一旦任何一方的生命值降至 0 或以下,遊戲立即結束,並返回對應的勝負結果。self.remaining_deck
的長度變為 0 時,代表牌組已抽完。此時,遊戲會比較雙方當前的生命值,血量較高者獲勝;若血量相同,則為平局。self.max_rounds
(預設為 15 回合) 的上限,以防止戰局無限延長。當 self.turn_count
超過這個數值時,同樣會依據生命值高低來裁定勝負。透過 advance_turn
的流暢推進與 check_game_over
的多重精密判斷,我們成功地為《奇幻卡牌競技場》建立了一套完整且穩定的遊戲循環與終局機制。這套系統確保了遊戲的節奏感、策略性以及明確的勝負目標,讓玩家可以完全沉浸在卡牌對決的樂趣之中。
明天,我們將踏入視覺化的世界,學習如何使用 Pygame 點亮我們的冒險舞台!敬請期待!