From fbfb4b89e139fcdf4eea35ae6b0d67e4841b6bb4 Mon Sep 17 00:00:00 2001 From: wangsiyuan <2392948297@qq.com> Date: Sun, 1 Dec 2024 00:55:39 +0800 Subject: [PATCH] 1 1 --- src/engine/chengdu_mahjong_state.py | 57 ++++++++++++++++------------- test.py | 8 ++-- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/engine/chengdu_mahjong_state.py b/src/engine/chengdu_mahjong_state.py index 638886d..4f8f7f3 100644 --- a/src/engine/chengdu_mahjong_state.py +++ b/src/engine/chengdu_mahjong_state.py @@ -1,7 +1,7 @@ from collections import Counter -from .hand import Hand -from .mahjong_tile import MahjongTile -from .meld import Meld # 导入 Meld 类 +from src.engine.hand import Hand +from src.engine.mahjong_tile import MahjongTile +from src.engine.meld import Meld from loguru import logger @@ -64,13 +64,26 @@ class ChengduMahjongState: tiles[1].value + 1 == tiles[2].value and tiles[0].suit == tiles[1].suit == tiles[2].suit) - def try_win(remaining_tiles, groups_formed=0): + def try_win(remaining_tiles, pairs_found=False): """ 尝试将剩余牌分组,必须满足 n * AAA + m * ABC + DD。 """ + # 如果没有剩余牌,检查是否已经找到对子 if not remaining_tiles: - return groups_formed >= 4 # 至少形成 4 个合法组(包括将牌) + return pairs_found # 必须存在一个对子 + # 尝试找到一个对子 + if not pairs_found: + tile_counter = Counter(remaining_tiles) + for tile, count in tile_counter.items(): + if count >= 2: # 找到一个对子 + temp_tiles = remaining_tiles[:] + temp_tiles.remove(tile) + temp_tiles.remove(tile) + if try_win(temp_tiles, pairs_found=True): + return True + + # 尝试找到一个合法组(AAA 或 ABC) 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)): @@ -78,7 +91,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, groups_formed + 1): + if try_win(next_tiles, pairs_found): return True return False @@ -90,27 +103,21 @@ class ChengduMahjongState: # 检查是否打完缺门的花色 if any(tile.suit == missing_suit for tile in hand.tiles): + logger.info("仍有缺门花色,不能胡牌") return False # 仍有缺门的花色,不能胡牌 - # **第二步:合并暗牌和明牌** - all_tiles = hand.tiles[:] + # **第二步:分离明牌(杠、碰)和暗牌** + # 提取明牌(碰和杠)的组数 + groups_from_melds = 0 for meld in melds: - if meld.type == "碰": # 添加碰牌(3 张) - all_tiles.extend([meld.tile] * 3) - elif meld.type == "杠": # 添加杠牌(4 张) - all_tiles.extend([meld.tile] * 4) + if meld.type == "碰": + groups_from_melds += 1 # 碰牌构成 1 组 + elif meld.type == "杠": + groups_from_melds += 1 # 杠牌也构成 1 组 - # **第三步:寻找对子并分组** - # 找到所有对子(至少两张相同的牌) - tile_counter = Counter(all_tiles) - pairs = [tile for tile, count in tile_counter.items() if count >= 2] + # 获取所有暗牌 + remaining_tiles = hand.tiles[:] + logger.info(f"暗牌: {remaining_tiles}, 明牌: {melds}, 已构成的组数: {groups_from_melds}") - # 遍历所有对子,尝试用剩余牌分组 - for pair in pairs: - temp_tiles = all_tiles[:] - temp_tiles.remove(pair) # 移除一张将牌 - temp_tiles.remove(pair) # 再移除一张将牌 - if try_win(temp_tiles): # 检查是否可以分组 - return True - - return False # 如果没有找到符合条件的组合,则不能胡牌 \ No newline at end of file + # **第三步:检查暗牌是否满足分组条件** + return try_win(remaining_tiles, pairs_found=False) and groups_from_melds >= 0 \ No newline at end of file diff --git a/test.py b/test.py index 952f56e..4eb55d7 100644 --- a/test.py +++ b/test.py @@ -2,6 +2,7 @@ from src.engine.chengdu_mahjong_state import ChengduMahjongState from src.engine.hand import Hand from src.engine.mahjong_tile import MahjongTile +from src.engine.meld import Meld hand = Hand() @@ -25,11 +26,12 @@ state.hands[0] = hand # 设置明牌(杠) melds_list = [ - ("杠", MahjongTile("筒", 9)), # 表示明杠了4张9筒 + Meld(MahjongTile("筒", 9), "杠") # 表示明杠了4张9筒 ] -state.melds[0] = melds_list +state.melds[0] = melds_list # 确保 state.melds[0] 是一个列表 # 设置缺门为 "万" missing_suit = "万" print(f"\n当前手牌: {state.hands[0]}, 明牌: {state.melds[0]}") -state.can_win(state.hands[0], state.melds[0], missing_suit) \ No newline at end of file + +print(f"是否可以胡: {state.can_win(state.hands[0], state.melds[0], missing_suit)}")