diff --git a/src/engine/chengdu_mahjong_state.py b/src/engine/chengdu_mahjong_state.py index 05d8913..23411e9 100644 --- a/src/engine/chengdu_mahjong_state.py +++ b/src/engine/chengdu_mahjong_state.py @@ -40,10 +40,11 @@ class ChengduMahjongState: raise ValueError("缺门设置无效") self.missing_suits[player] = missing_suit - def can_win(self, hand: Hand, missing_suit: str): + def can_win(self, hand: Hand, melds: list, missing_suit: str): """ 判断玩家是否能胡牌。 :param hand: 玩家手牌(Hand 对象)。 + :param melds: 玩家已明牌的列表(碰、杠)。 :param missing_suit: 玩家设置的缺门花色。 :return: True 表示能胡牌,False 表示不能胡牌。 """ @@ -61,12 +62,13 @@ class ChengduMahjongState: tiles[1].value + 1 == tiles[2].value and tiles[0].suit == tiles[1].suit == tiles[2].suit) - def try_win(remaining_tiles, depth=0): + def try_win(remaining_tiles, groups_formed=0): """ - 尝试将剩余牌分组,必须满足 n * AAA + m * ABC。 + 尝试将剩余牌分组,必须满足 n * AAA + m * ABC + DD。 """ if not remaining_tiles: - return True # 所有牌成功分组 + return groups_formed >= 4 # 至少形成 4 个合法组(包括将牌) + for i in range(len(remaining_tiles)): for j in range(i + 1, len(remaining_tiles)): for k in range(j + 1, len(remaining_tiles)): @@ -74,7 +76,7 @@ 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:] - if try_win(next_tiles, depth + 1): + if try_win(next_tiles, groups_formed + 1): return True return False @@ -88,14 +90,20 @@ class ChengduMahjongState: if any(tile.suit == missing_suit for tile in hand.tiles): return False # 仍有缺门的花色,不能胡牌 - # **第二步:寻找对子并分组** + # **第二步:合并暗牌和明牌** + all_tiles = hand.tiles[:] + for meld in melds: + if meld[0] == "碰" or meld[0] == "杠": # 将明牌的 AAA 加入检查 + all_tiles.extend([meld[1], meld[1], meld[1]]) + + # **第三步:寻找对子并分组** # 找到所有对子(至少两张相同的牌) - tile_counter = Counter(hand.tiles) + tile_counter = Counter(all_tiles) pairs = [tile for tile, count in tile_counter.items() if count >= 2] # 遍历所有对子,尝试用剩余牌分组 for pair in pairs: - temp_tiles = hand.tiles[:] + temp_tiles = all_tiles[:] temp_tiles.remove(pair) # 移除一张将牌 temp_tiles.remove(pair) # 再移除一张将牌 if try_win(temp_tiles): # 检查是否可以分组