Update actions.py

dev
wangsiyuan 2024-12-01 05:03:08 +08:00
parent 9e8cfe793c
commit 03fcd8203c
1 changed files with 45 additions and 29 deletions

View File

@ -18,12 +18,12 @@ def draw_tile(engine):
# 从牌堆中摸一张牌 # 从牌堆中摸一张牌
tile = engine.state.deck.pop(0) # 从牌堆抽取一张牌 tile = engine.state.deck.pop(0) # 从牌堆抽取一张牌
engine.state.remaining_tiles -= 1 # 更新剩余牌数 engine.state.remaining_tiles -= 1 # 更新剩余牌数
engine.state.hands[current_player].add_tile(tile) # 将牌加入当前玩家手牌 engine.state.hands[current_player].add_tile(tile) # 将牌对象加入当前玩家手牌
# 获取牌名 # 获取牌名
tile_name = str(tile) # 调用 MahjongTile 的 __repr__ 方法 tile_name = str(tile) # 调用 MahjongTile 的 __repr__ 方法
logger.info( logger.info(
f"玩家 {current_player} 摸到一张牌: {tile_name}(索引 {tile}" f"玩家 {current_player} 摸到一张牌: {tile_name}"
f"剩余牌堆数量: {engine.state.remaining_tiles}" f"剩余牌堆数量: {engine.state.remaining_tiles}"
) )
@ -52,27 +52,27 @@ def discard_tile(self, tile):
raise ValueError("打出的牌必须是 MahjongTile 对象") raise ValueError("打出的牌必须是 MahjongTile 对象")
# 检查是否有这张牌 # 检查是否有这张牌
if hand[tile] == 0: if hand.tile_count[tile] == 0:
logger.error(f"玩家 {current_player} 尝试打出不存在的牌: {tile}") logger.error(f"玩家 {current_player} 尝试打出不存在的牌: {tile}")
raise ValueError("玩家没有这张牌") raise ValueError("玩家没有这张牌")
# 检查缺门规则 # 检查缺门规则
missing_suit = self.state.missing_suits[current_player] missing_suit = self.state.missing_suits[current_player]
if tile.suit == missing_suit and any(t.suit == missing_suit for t in hand.tiles): if tile.suit == missing_suit and any(t.suit == missing_suit for t in hand.tiles):
logger.error(f"玩家 {current_player} 尝试打出非缺门的牌: {tile}") logger.error(f"玩家 {current_player} 仍有缺门的牌: {tile}")
raise ValueError("必须先打完缺门花色的牌") raise ValueError("必须先打完缺门花色的牌")
# 从手牌中移除 # 从手牌中移除
hand[tile] -= 1 hand.remove_tile(tile)
self.state.discards[current_player].append(tile) self.state.discards[current_player].append(tile)
# 打出的牌名 # 打出的牌名
tile_name = get_tile_name(tile) tile_name = str(tile)
# 打出牌后打印状态 # 打出牌后打印状态
logger.info( logger.info(
f"玩家 {current_player} 打出一张牌: {tile_name}(索引 {tile}" f"玩家 {current_player} 打出一张牌: {tile_name}"
f"当前牌河: {[get_tile_name(t) for t in self.state.discards[current_player]]}" f"当前牌河: {[str(t) for t in self.state.discards[current_player]]}"
) )
# 检查是否触发其他玩家的操作(碰、杠、胡牌) # 检查是否触发其他玩家的操作(碰、杠、胡牌)
@ -86,41 +86,57 @@ def peng(self, tile):
当前玩家碰牌逻辑记录碰牌操作和手牌状态 当前玩家碰牌逻辑记录碰牌操作和手牌状态
""" """
player = self.state.current_player player = self.state.current_player
if self.state.hands[player][tile] < 2: hand = self.state.hands[player]
logger.error(f"玩家 {player} 尝试碰牌失败: {get_tile_name(tile)}(索引 {tile}")
if hand.tile_count[tile] < 2:
logger.error(f"玩家 {player} 尝试碰牌失败: {tile}")
raise ValueError("碰牌条件不满足") raise ValueError("碰牌条件不满足")
self.state.hands[player][tile] -= 2 # 减去两张牌 # 从手牌中移除两张牌
hand.tile_count[tile] -= 2
self.state.melds[player].append(("peng", tile)) # 加入明牌列表 self.state.melds[player].append(("peng", tile)) # 加入明牌列表
tile_name = get_tile_name(tile) logger.info(f"玩家 {player} 碰了一张牌: {tile}。当前明牌: {self.state.melds[player]}")
logger.info(f"玩家 {player} 碰了一张牌: {tile_name}(索引 {tile})。当前明牌: {self.state.melds[player]}")
def gang(self, tile, mode): def gang(self, tile, mode):
""" """
当前玩家杠牌逻辑记录杠牌类型和状态更新 当前玩家杠牌逻辑记录杠牌类型和状态更新
""" """
player = self.state.current_player 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 if not isinstance(tile, MahjongTile):
self.state.melds[player].append(("ming_gang", tile)) logger.error(f"玩家 {player} 尝试杠牌时提供了无效的牌: {tile}")
logger.info(f"玩家 {player} 明杠: {tile_name}(索引 {tile}") raise ValueError("杠的牌必须是 MahjongTile 对象")
self.state.scores[player] += 1 # 奖励1分
logger.info(f"玩家 {player} 因明杠获得1分")
elif mode == "an" and self.state.hands[player][tile] == 4: tile_name = str(tile) # 使用 MahjongTile 的 __repr__ 方法
self.state.hands[player][tile] -= 4
self.state.melds[player].append(("an_gang", tile))
logger.info(f"玩家 {player} 暗杠: {tile_name}(索引 {tile}")
self.state.scores[player] += 1 # 奖励1分
logger.info(f"玩家 {player} 因暗杠获得1分")
if mode == "ming":
# 明杠逻辑
if self.state.hands[player].tile_count[tile] >= 3:
self.state.hands[player].tile_count[tile] -= 3 # 移除三张牌
self.state.melds[player].append(("ming_gang", tile)) # 添加到明牌
logger.info(f"玩家 {player} 明杠成功: {tile_name}")
self.state.scores[player] += 1 # 明杠奖励1分
logger.info(f"玩家 {player} 因明杠获得1分当前得分: {self.state.scores[player]}")
else: else:
logger.error(f"玩家 {player} 尝试杠牌失败: {tile_name}(索引 {tile}),条件不满足") logger.error(f"玩家 {player} 明杠失败: 手中牌数量不足")
raise ValueError("杠牌条件不满足") raise ValueError("明杠条件不满足,需要至少三张相同的牌")
elif mode == "an":
# 暗杠逻辑
if self.state.hands[player].tile_count[tile] >= 4:
self.state.hands[player].tile_count[tile] -= 4 # 移除四张牌
self.state.melds[player].append(("an_gang", tile)) # 添加到明牌
logger.info(f"玩家 {player} 暗杠成功: {tile_name}")
self.state.scores[player] += 1 # 暗杠奖励1分
logger.info(f"玩家 {player} 因暗杠获得1分当前得分: {self.state.scores[player]}")
else:
logger.error(f"玩家 {player} 暗杠失败: 手中牌数量不足")
raise ValueError("暗杠条件不满足,需要至少四张相同的牌")
else:
logger.error(f"玩家 {player} 提供了无效的杠牌类型: {mode}")
raise ValueError("无效的杠牌类型,仅支持 'ming''an''bu'")