diff --git a/src/engine/game_state.py b/src/engine/game_state.py index d325cfa..5583202 100644 --- a/src/engine/game_state.py +++ b/src/engine/game_state.py @@ -1,23 +1,24 @@ -from .utils import get_suit,get_tile_name -from loguru import logger +from collections import Counter +from .hand import Hand +from .mahjong_tile import MahjongTile class ChengduMahjongState: def __init__(self): - # 每个玩家的手牌,使用108个索引表示 - self.hands = [[0] * 108 for _ in range(4)] # 每个玩家108张牌的计数 + # 每个玩家的手牌 + self.hands = [Hand() for _ in range(4)] # 每个玩家的手牌由 Hand 类表示 # 每个玩家的打出的牌 self.discards = [[] for _ in range(4)] # 每个玩家的弃牌列表 # 每个玩家的明牌(碰、杠) self.melds = [[] for _ in range(4)] # 剩余的牌堆 - self.deck = list(range(108)) # 0-107 表示108张牌 + self.deck = [MahjongTile(suit, value) for suit in ["条", "筒", "万"] for value in range(1, 10)] * 4 # 108张牌 # 当前玩家索引 self.current_player = 0 # 玩家分数 self.scores = [100, 100, 100, 100] # 剩余牌数量 - self.remaining_tiles = 108 + self.remaining_tiles = len(self.deck) # 胜利玩家列表 self.winners = [] # 缺门信息 @@ -39,21 +40,20 @@ class ChengduMahjongState: raise ValueError("缺门设置无效") self.missing_suits[player] = missing_suit - def can_win(self, hand): + def can_win(self, hand: Hand): """ 判断是否满足胡牌条件:四组(顺子或刻子)+ 一对将。 """ - from collections import Counter - def is_valid_group(tiles): """ 判断是否为合法的顺子或刻子。 """ if len(tiles) != 3: return False - tiles.sort() # 确保顺子检查按顺序排列 + tiles.sort(key=lambda t: (t.suit, t.value)) return (tiles[0] == tiles[1] == tiles[2]) or \ - (tiles[0] + 1 == tiles[1] and tiles[1] + 1 == tiles[2]) + (tiles[0].value + 1 == tiles[1].value and tiles[1].value + 1 == tiles[2].value and + tiles[0].suit == tiles[1].suit == tiles[2].suit) def try_win(remaining_tiles, depth=0): """ @@ -69,21 +69,22 @@ class ChengduMahjongState: if is_valid_group(group): next_tiles = remaining_tiles[:i] + remaining_tiles[i + 1:j] + \ remaining_tiles[j + 1:k] + remaining_tiles[k + 1:] - # 确保顺子检查按顺序排列 - next_tiles.sort() if try_win(next_tiles, depth + 1): return True return False - counter = Counter({tile: count for tile, count in enumerate(hand) if count > 0}) - pairs = [tile for tile, count in counter.items() if count >= 2] + # 统计每张牌的数量 + tile_counter = Counter(hand.tiles) + pairs = [tile for tile, count in tile_counter.items() if count >= 2] for pair in pairs: - temp_hand = hand[:] - temp_hand[pair] -= 2 # 移除将牌 - remaining_tiles = [tile for tile, count in enumerate(temp_hand) for _ in range(count)] - remaining_tiles.sort() # 确保顺子检查按顺序排列 - if try_win(remaining_tiles): + # 移除一对将牌 + temp_tiles = hand.tiles[:] + temp_tiles.remove(pair) + temp_tiles.remove(pair) + + # 检查剩余牌是否能分组 + if try_win(temp_tiles): return True - return False + return False \ No newline at end of file