1
This commit is contained in:
2024-11-30 18:28:19 +08:00
parent 14c811f6b9
commit 2a5680fae9
3 changed files with 92 additions and 122 deletions

View File

@@ -2,57 +2,87 @@ from loguru import logger
from utils import get_tile_name
def draw_tile(state):
def draw_tile(self):
"""
当前玩家摸牌的动作逻辑。
参数:
- state: ChengduMahjongState 实例,表示当前游戏状态。
返回:
- tile: 当前玩家摸到的牌的索引。
异常:
- ValueError: 如果牌堆已经空了(流局条件)。
当前玩家摸牌逻辑,记录牌的详细信息和游戏状态
"""
if state.remaining_tiles == 0:
logger.warning("牌堆已空,无法摸牌")
raise ValueError("牌堆已空") # 牌堆为空时不能摸牌
if self.state.remaining_tiles == 0:
logger.warning("牌堆已空,游戏结束")
self.game_over = True
return "牌堆已空"
tile = state.deck.pop(0) # 从牌堆取出一张牌
state.remaining_tiles -= 1 # 更新牌堆剩余数量
state.hands[state.current_player][tile] += 1 # 将摸到的牌添加到当前玩家手牌
tile = self.state.deck.pop(0) # 从牌堆取出一张牌
self.state.remaining_tiles -= 1 # 更新剩余牌数
self.state.hands[self.state.current_player][tile] += 1 # 加入当前玩家手牌
tile_name = get_tile_name(tile) # 获取牌的具体名称
tile_name = get_tile_name(tile) # 获取具体的牌名
logger.info(
f"玩家 {state.current_player} 摸到一张牌: {tile_name}(索引 {tile})。剩余牌堆数量: {state.remaining_tiles}"
f"玩家 {self.state.current_player} 摸到一张牌: {tile_name}(索引 {tile})。剩余牌堆数量: {self.state.remaining_tiles}"
)
return tile
def discard_tile(state, tile):
def discard_tile(self, tile):
"""
当前玩家打出一张牌的动作逻辑
参数:
- state: ChengduMahjongState 实例,表示当前游戏状态。
- tile: 玩家想要打出的牌的索引。
操作:
- 从当前玩家手牌中移除指定的牌。
- 将指定牌添加到当前玩家的牌河中。
异常:
- ValueError: 如果当前玩家的手牌中没有这张牌。
当前玩家打牌逻辑,记录打出的牌和当前牌河信息
"""
if state.hands[state.current_player][tile] == 0:
logger.error(f"玩家 {state.current_player} 尝试打出不存在的牌: 索引 {tile}")
raise ValueError("玩家没有这张牌") # 防止打出不存在的牌
if self.state.hands[self.state.current_player][tile] == 0:
logger.error(f"玩家 {self.state.current_player} 尝试打出不存在的牌: 索引 {tile}")
raise ValueError("玩家没有这张牌")
state.hands[state.current_player][tile] -= 1 # 从手牌中移除该牌
state.discards[state.current_player].append(tile) # 将牌添加到牌河
self.state.hands[self.state.current_player][tile] -= 1 # 从手牌中移除
self.state.discards[self.state.current_player].append(tile) # 加入牌河
tile_name = get_tile_name(tile) # 获取牌的具体名称
tile_name = get_tile_name(tile) # 获取具体的牌名
logger.info(
f"玩家 {state.current_player} 打出一张牌: {tile_name}(索引 {tile})。当前牌河: {[get_tile_name(t) for t in state.discards[state.current_player]]}"
f"玩家 {self.state.current_player} 打出一张牌: {tile_name}(索引 {tile})。当前牌河: {[get_tile_name(t) for t in self.state.discards[self.state.current_player]]}"
)
def peng(self, tile):
"""
当前玩家碰牌逻辑,记录碰牌操作和手牌状态。
"""
player = self.state.current_player
if self.state.hands[player][tile] < 2:
logger.error(f"玩家 {player} 尝试碰牌失败: {get_tile_name(tile)}(索引 {tile}")
raise ValueError("碰牌条件不满足")
self.state.hands[player][tile] -= 2 # 减去两张牌
self.state.melds[player].append(("peng", tile)) # 加入明牌列表
tile_name = get_tile_name(tile)
logger.info(f"玩家 {player} 碰了一张牌: {tile_name}(索引 {tile})。当前明牌: {self.state.melds[player]}")
def gang(self, tile, mode="ming"):
"""
当前玩家杠牌逻辑,记录杠牌类型和状态更新。
"""
player = self.state.current_player
tile_name = get_tile_name(tile)
if mode == "ming" and self.state.hands[player][tile] == 3:
self.state.hands[player][tile] -= 3
self.state.melds[player].append(("ming_gang", tile))
logger.info(f"玩家 {player} 明杠: {tile_name}(索引 {tile}")
elif mode == "an" and self.state.hands[player][tile] == 4:
self.state.hands[player][tile] -= 4
self.state.melds[player].append(("an_gang", tile))
logger.info(f"玩家 {player} 暗杠: {tile_name}(索引 {tile}")
else:
logger.error(f"玩家 {player} 尝试杠牌失败: {tile_name}(索引 {tile}),条件不满足")
raise ValueError("杠牌条件不满足")
def check_blood_battle(self):
"""
检查游戏是否流局或血战结束,记录状态。
"""
if any(score <= 0 for score in self.state.scores):
logger.info(f"游戏结束某玩家分数小于等于0: {self.state.scores}")
self.game_over = True
if len(self.state.winners) >= 3 or self.state.remaining_tiles == 0:
logger.info(f"游戏结束,赢家列表: {self.state.winners}")
self.game_over = True

View File

@@ -1,6 +1,4 @@
from .game_state import ChengduMahjongState
from .utils import get_tile_name # 确保 utils 中有 get_tile_name 定义
from loguru import logger
class ChengduMahjongEngine:
@@ -8,79 +6,3 @@ class ChengduMahjongEngine:
self.state = ChengduMahjongState()
self.game_over = False
def draw_tile(self):
"""
当前玩家摸牌逻辑,记录牌的详细信息和游戏状态。
"""
if self.state.remaining_tiles == 0:
logger.warning("牌堆已空,游戏结束!")
self.game_over = True
return "牌堆已空"
tile = self.state.deck.pop(0) # 从牌堆中取出一张牌
self.state.remaining_tiles -= 1 # 更新剩余牌数
self.state.hands[self.state.current_player][tile] += 1 # 加入当前玩家手牌
tile_name = get_tile_name(tile) # 获取具体的牌名
logger.info(
f"玩家 {self.state.current_player} 摸到一张牌: {tile_name}(索引 {tile})。剩余牌堆数量: {self.state.remaining_tiles}"
)
return tile
def discard_tile(self, tile):
"""
当前玩家打牌逻辑,记录打出的牌和当前牌河信息。
"""
if self.state.hands[self.state.current_player][tile] == 0:
logger.error(f"玩家 {self.state.current_player} 尝试打出不存在的牌: 索引 {tile}")
raise ValueError("玩家没有这张牌")
self.state.hands[self.state.current_player][tile] -= 1 # 从手牌中移除
self.state.discards[self.state.current_player].append(tile) # 加入牌河
tile_name = get_tile_name(tile) # 获取具体的牌名
logger.info(
f"玩家 {self.state.current_player} 打出一张牌: {tile_name}(索引 {tile})。当前牌河: {[get_tile_name(t) for t in self.state.discards[self.state.current_player]]}"
)
def peng(self, tile):
"""
当前玩家碰牌逻辑,记录碰牌操作和手牌状态。
"""
player = self.state.current_player
if self.state.hands[player][tile] < 2:
logger.error(f"玩家 {player} 尝试碰牌失败: {get_tile_name(tile)}(索引 {tile}")
raise ValueError("碰牌条件不满足")
self.state.hands[player][tile] -= 2 # 减去两张牌
self.state.melds[player].append(("peng", tile)) # 加入明牌列表
tile_name = get_tile_name(tile)
logger.info(f"玩家 {player} 碰了一张牌: {tile_name}(索引 {tile})。当前明牌: {self.state.melds[player]}")
def gang(self, tile, mode="ming"):
"""
当前玩家杠牌逻辑,记录杠牌类型和状态更新。
"""
player = self.state.current_player
tile_name = get_tile_name(tile)
if mode == "ming" and self.state.hands[player][tile] == 3:
self.state.hands[player][tile] -= 3
self.state.melds[player].append(("ming_gang", tile))
logger.info(f"玩家 {player} 明杠: {tile_name}(索引 {tile}")
elif mode == "an" and self.state.hands[player][tile] == 4:
self.state.hands[player][tile] -= 4
self.state.melds[player].append(("an_gang", tile))
logger.info(f"玩家 {player} 暗杠: {tile_name}(索引 {tile}")
else:
logger.error(f"玩家 {player} 尝试杠牌失败: {tile_name}(索引 {tile}),条件不满足")
raise ValueError("杠牌条件不满足")
def check_blood_battle(self):
"""
检查游戏是否流局或血战结束,记录状态。
"""
if len(self.state.winners) >= 3 or self.state.remaining_tiles == 0:
logger.info(f"游戏结束,赢家列表: {self.state.winners}")
self.game_over = True