diff --git a/src/engine/fan_type.py b/src/engine/fan_type.py index 50f14bd..1cdb3d3 100644 --- a/src/engine/fan_type.py +++ b/src/engine/fan_type.py @@ -1,4 +1,5 @@ from src.engine.utils import try_win,is_terminal_tile +from collections import Counter def is_basic_win(hand): # 将手牌转换为列表并按花色和数值排序 @@ -124,3 +125,41 @@ def is_full_request(hand, melds, winning_tile): # 符合全求人 return 6 +def is_dragon_seven_pairs(hand, melds): + """ + 判断是否符合龙七对的番型,并返回番数和剩余根数。 + + 条件: + - 玩家手牌为七对(14张,包含7个对子)。 + - 没有碰过或者杠过牌(melds为空)。 + - 至少一个对子升级为四张牌。 + + 参数: + - hand: Hand 对象,表示玩家当前的手牌。 + - melds: 明牌列表(碰、杠等),必须为空。 + + 返回: + - (int, int): 如果符合龙七对,返回 (12, -1) 表示 12 番和减去 1 根;否则返回 (0, 0)。 + """ + if melds: # 如果有明牌(碰或杠),不符合条件 + return 0, 0 + + # 获取手牌中每张牌的数量 + tile_counts = Counter(hand.tiles) + + # 统计对子和四张牌的数量 + pairs_count = 0 + four_of_a_kind_found = False + + for count in tile_counts.values(): + if count == 2: + pairs_count += 1 + elif count == 4: + four_of_a_kind_found = True + pairs_count += 1 + + # 检查是否符合龙七对的条件 + if pairs_count == 7 and four_of_a_kind_found: + return 12, -1 # 龙七对计为 12 番,并减少 1 根 + return 0, 0 + diff --git a/tests/test_calculate_fan.py b/tests/test_calculate_fan.py index 1bc48a6..35f9324 100644 --- a/tests/test_calculate_fan.py +++ b/tests/test_calculate_fan.py @@ -270,3 +270,4 @@ def test_self_draw(): fan = calculate_fan(hand, melds, is_self_draw=True, is_cleared=False, conditions=conditions) assert fan == 1, f"Expected 1 fan (self-draw), got {fan}" + diff --git a/tests/test_fan_type.py b/tests/test_fan_type.py index a8e7260..5e2fbe5 100644 --- a/tests/test_fan_type.py +++ b/tests/test_fan_type.py @@ -1,6 +1,6 @@ from src.engine.hand import Hand from src.engine.mahjong_tile import MahjongTile -from src.engine.fan_type import is_basic_win,is_cleared,calculate_terminal_fan,is_seven_pairs,is_full_request +from src.engine.fan_type import is_basic_win,is_cleared,calculate_terminal_fan,is_seven_pairs,is_full_request,is_dragon_seven_pairs from src.engine.meld import Meld def test_is_basic_win(): @@ -173,3 +173,73 @@ def test_is_full_request(): print("所有全求人测试通过!") +def test_is_dragon_seven_pairs(): + """测试龙七对番型计算""" + + # 示例1:符合龙七对 + hand = Hand() + hand.add_tile(MahjongTile("筒", 1)) + hand.add_tile(MahjongTile("筒", 1)) + hand.add_tile(MahjongTile("筒", 2)) + hand.add_tile(MahjongTile("筒", 2)) + hand.add_tile(MahjongTile("筒", 3)) + hand.add_tile(MahjongTile("筒", 3)) + hand.add_tile(MahjongTile("筒", 4)) + hand.add_tile(MahjongTile("筒", 4)) + hand.add_tile(MahjongTile("筒", 5)) + hand.add_tile(MahjongTile("筒", 5)) + hand.add_tile(MahjongTile("筒", 6)) + hand.add_tile(MahjongTile("筒", 6)) + hand.add_tile(MahjongTile("筒", 7)) # 四张7筒 + hand.add_tile(MahjongTile("筒", 7)) + hand.add_tile(MahjongTile("筒", 7)) + hand.add_tile(MahjongTile("筒", 7)) + + melds = [] # 没有明牌 + fan, root_adjustment = is_dragon_seven_pairs(hand, melds) + assert fan == 12 and root_adjustment == -1, "测试失败:符合龙七对,应为 12 番,并减少 1 根" + + # 示例2:不符合龙七对(只有七对,没有四张) + hand = Hand() + hand.add_tile(MahjongTile("筒", 1)) + hand.add_tile(MahjongTile("筒", 1)) + hand.add_tile(MahjongTile("筒", 2)) + hand.add_tile(MahjongTile("筒", 2)) + hand.add_tile(MahjongTile("筒", 3)) + hand.add_tile(MahjongTile("筒", 3)) + hand.add_tile(MahjongTile("筒", 4)) + hand.add_tile(MahjongTile("筒", 4)) + hand.add_tile(MahjongTile("筒", 5)) + hand.add_tile(MahjongTile("筒", 5)) + hand.add_tile(MahjongTile("筒", 6)) + hand.add_tile(MahjongTile("筒", 6)) + hand.add_tile(MahjongTile("筒", 7)) + hand.add_tile(MahjongTile("筒", 7)) + + fan, root_adjustment = is_dragon_seven_pairs(hand, melds) + assert fan == 0 and root_adjustment == 0, "测试失败:不符合龙七对,应为 0 番,根数不变" + + # 示例3:不符合龙七对(有明牌) + hand = Hand() + hand.add_tile(MahjongTile("筒", 1)) + hand.add_tile(MahjongTile("筒", 1)) + hand.add_tile(MahjongTile("筒", 2)) + hand.add_tile(MahjongTile("筒", 2)) + hand.add_tile(MahjongTile("筒", 3)) + hand.add_tile(MahjongTile("筒", 3)) + hand.add_tile(MahjongTile("筒", 4)) + hand.add_tile(MahjongTile("筒", 4)) + hand.add_tile(MahjongTile("筒", 5)) + hand.add_tile(MahjongTile("筒", 5)) + hand.add_tile(MahjongTile("筒", 6)) + hand.add_tile(MahjongTile("筒", 6)) + hand.add_tile(MahjongTile("筒", 7)) + hand.add_tile(MahjongTile("筒", 7)) + + melds = [Meld(MahjongTile("筒", 8), "碰")] # 有明牌 + fan, root_adjustment = is_dragon_seven_pairs(hand, melds) + assert fan == 0 and root_adjustment == 0, "测试失败:有明牌,不符合龙七对,应为 0 番,根数不变" + + print("所有龙七对测试通过!") + +