From 227800f0e852ab7c15ba7132134df4eba19d86b3 Mon Sep 17 00:00:00 2001 From: wangsiyuan <2392948297@qq.com> Date: Sun, 1 Dec 2024 02:12:22 +0800 Subject: [PATCH] Update calculate_fan.py --- src/engine/calculate_fan.py | 136 +++++++++++++++++------------------- 1 file changed, 65 insertions(+), 71 deletions(-) diff --git a/src/engine/calculate_fan.py b/src/engine/calculate_fan.py index c81a8e3..532e327 100644 --- a/src/engine/calculate_fan.py +++ b/src/engine/calculate_fan.py @@ -1,98 +1,92 @@ def calculate_fan(hand, melds, is_self_draw, is_cleared, conditions): """ - 根据规则动态计算番数。 + 动态计算番数,优先处理高番数。 参数: - - hand: 当前胡牌的手牌(长度为108的列表,表示每张牌的数量)。 - - melds: 碰杠等明牌列表。 + - hand: 当前胡牌的手牌(Hand 对象)。 + - melds: 玩家已明牌的列表(Meld 对象列表)。 - is_self_draw: 是否自摸。 - is_cleared: 是否清一色。 - - conditions: 其他胡牌条件的字典,例如 {'is_seven_pairs': True, 'add_self_draw': True}。 + - conditions: 字典,包含特殊胡牌条件,如 {"is_seven_pairs": True, "is_tian_hu": True}。 返回: - - fan: 总番数。 + - fan: 最大番数。 """ - fan = 0 # 初始番数 + fan = 0 # 默认番数 - # 定义番种规则 + # 定义番数规则(按优先级从高到低排序) rules = { - "is_pure_cleared": lambda: 3 if is_cleared and len(melds) == 3 and not conditions.get("is_double_pure_cleared", - False) else 0, - "is_double_pure_cleared": lambda: 4 if is_cleared and len(melds) >= 2 and conditions.get( - "is_double_pure_cleared", False) else 0, - "is_cleared": lambda: 2 if is_cleared and not (conditions.get("is_pure_cleared", False) or - conditions.get("is_double_pure_cleared", False) or - conditions.get("is_clear_seven_pairs", False)) else 0, - "is_seven_pairs": lambda: 2 if conditions.get("is_seven_pairs", False) and not conditions.get( - "is_dragon_seven_pairs", False) else 0, - "is_dragon_seven_pairs": lambda: 12 if conditions.get("is_dragon_seven_pairs", False) else 0, - "is_clear_seven_pairs": lambda: 12 if conditions.get("is_clear_seven_pairs", False) else 0, - "is_big_pairs": lambda: 2 if conditions.get("is_big_pairs", False) else 0, - "is_small_pairs": lambda: 2 if conditions.get("is_small_pairs", False) else 0, - "is_full_request": lambda: 6 if conditions.get("is_full_request", False) else 0, - "is_gang_flower": lambda: 1 if conditions.get("is_gang_flower", False) else 0, - "is_rob_gang": lambda: 1 if conditions.get("is_rob_gang", False) else 0, - "is_under_the_sea": lambda: 1 if conditions.get("is_under_the_sea", False) else 0, - "is_tian_hu": lambda: 12 if conditions.get("is_tian_hu", False) else 0, - "is_di_hu": lambda: 12 if conditions.get("is_di_hu", False) else 0, - "basic_win": lambda: 1 if not (conditions.get("is_seven_pairs", False) or - conditions.get("is_big_pairs", False) or - conditions.get("is_dragon_seven_pairs", False) or - conditions.get("is_pure_cleared", False) or - conditions.get("is_double_pure_cleared", False) or - conditions.get("is_small_pairs", False) or - conditions.get("is_clear_seven_pairs", False) or - conditions.get("is_full_request", False) or - conditions.get("is_rob_gang", False) or - conditions.get("is_under_the_sea", False) or - conditions.get("is_tian_hu", False) or - conditions.get("is_di_hu", False)) else 0, - + "tian_hu": lambda: 12 if conditions.get("is_tian_hu", False) else 0, # 天胡 + "di_hu": lambda: 12 if conditions.get("is_di_hu", False) else 0, # 地胡 + "dragon_seven_pairs": lambda: 12 if is_dragon_seven_pairs(hand) else 0, # 龙七对 + "clear_seven_pairs": lambda: 12 if is_cleared and is_seven_pairs(hand) else 0, # 清七对 + "full_request": lambda: 6 if is_full_request(hand, melds) else 0, # 全求人 + "pure_cleared": lambda: 4 if is_cleared and len(melds) >= 2 else 0, # 极品清一色 + "seven_pairs": lambda: 2 if is_seven_pairs(hand) else 0, # 七对 + "big_pairs": lambda: 2 if is_big_pairs(hand) else 0, # 大对子 + "small_pairs": lambda: 2 if is_small_pairs(hand) else 0, # 小七对 + "golden_hook": lambda: 1 if is_golden_hook(hand) else 0, # 金钩吊 + "gang_flower": lambda: 1 if conditions.get("is_gang_flower", False) else 0, # 杠上开花 + "rob_gang": lambda: 1 if conditions.get("is_rob_gang", False) else 0, # 抢杠胡 + "under_the_sea": lambda: 1 if conditions.get("is_under_the_sea", False) else 0, # 海底捞月 + "plain_win": lambda: 1 if not any(conditions.values()) else 0 # 平胡 } - print("\nCalculating fan...") # 逐一应用规则 for rule, func in rules.items(): result = func() - fan += result - print(f"Rule: {rule}, Fan: {result}") # 调试输出 + if result > fan: + fan = result # 选择当前最大番数 return fan +# 辅助函数实现 def is_seven_pairs(hand): - """ - 检查手牌是否是七对。 - """ - return sum(1 for count in hand if count == 2) == 7 + """检查是否是七对(七个对子)。""" + from collections import Counter + counter = Counter(hand.tiles) + return sum(1 for count in counter.values() if count == 2) == 7 + + +def is_dragon_seven_pairs(hand): + """检查是否是龙七对(七对中有一对是三张)。""" + from collections import Counter + counter = Counter(hand.tiles) + pairs = sum(1 for count in counter.values() if count == 2) + triplets = sum(1 for count in counter.values() if count == 3) + return pairs == 6 and triplets == 1 + + +def is_big_pairs(hand): + """检查是否是大对子(四坎牌和一对将,坎牌为刻子)。""" + from collections import Counter + counter = Counter(hand.tiles) + triplets = sum(1 for count in counter.values() if count == 3) + pairs = sum(1 for count in counter.values() if count == 2) + return triplets == 4 and pairs == 1 + + +def is_golden_hook(hand): + """检查是否是金钩吊(只剩一张牌)。""" + return len(hand.tiles) == 1 + + +def is_full_request(hand, melds): + """检查是否是全求人(所有牌通过碰、杠完成)。""" + return all(tile_count == 0 for tile_count in hand.tiles) and len(melds) > 0 def is_cleared(hand, melds): + """检查是否是清一色(所有牌同一种花色)。""" + all_tiles = hand.tiles + [meld.tile for meld in melds] + suits = {tile.suit for tile in all_tiles} + return len(suits) == 1 +def is_small_pairs(hand): """ - 检查手牌和明牌是否是清一色。 - - 参数: - - hand: 当前胡牌的手牌(长度为108的列表,表示每张牌的数量)。 - - melds: 碰杠等明牌列表。 - - 返回: - - bool: 是否为清一色。 - """ - # 获取所有牌的花色 - all_tiles = hand + [tile for meld in melds for tile in meld] - suits = [tile // 36 for tile in all_tiles if tile > 0] - - # 检查是否有多种花色 - return len(set(suits)) == 1 - -def is_big_pairs(hand): - """ - 检查手牌是否是大对子(由刻子和一对组成)。 + 检查是否是小七对(六对加一对)。 """ from collections import Counter - counter = Counter(hand) - - counts = [count for count in hand if count > 0] - result = counts.count(2) == 1 and counts.count(3) >= 3 - print(f"Big pairs check: {result}, Counter: {Counter(counts)}") - return result + counter = Counter(hand.tiles) + pairs = sum(1 for count in counter.values() if count == 2) + return pairs == 6 \ No newline at end of file