This commit is contained in:
2024-12-01 02:58:09 +08:00
parent 227800f0e8
commit 29592cd05b
4 changed files with 192 additions and 15 deletions

43
src/engine/fan_type.py Normal file
View File

@@ -0,0 +1,43 @@
from src.engine.utils import try_win
def is_basic_win(hand):
# 将手牌转换为列表并按花色和数值排序
all_tiles = hand.tiles[:]
all_tiles.sort(key=lambda t: (t.suit, t.value))
# 调用递归函数检查是否符合平胡
if try_win(all_tiles):
return 1
return 0
def is_cleared(hand, melds):
"""
检查手牌和明牌是否符合清一色的番型。
"""
# 获取手牌和明牌的所有牌
all_tiles = hand.tiles[:]
for meld in melds:
if meld.is_triplet():
all_tiles.extend([meld.tile] * 3)
elif meld.is_kong():
all_tiles.extend([meld.tile] * 4)
# 检查是否只有一种花色
suits = {tile.suit for tile in all_tiles}
if len(suits) != 1:
return 0 # 不是清一色
# 检查杠的数量
gang_count = sum(1 for meld in melds if meld.is_kong())
# 根据杠的数量和是否符合基本胡规则确定番数
sorted_tiles = sorted(all_tiles, key=lambda t: (t.suit, t.value))
if try_win(sorted_tiles): # 检查是否符合基本胡(四坎牌加一对将)
if gang_count == 0:
return 2 # 素清
elif gang_count == 1:
return 3 # 极品
elif gang_count >= 2:
return 4 # 极中极
return 0

View File

@@ -11,9 +11,59 @@ def get_suit(tile_index):
else:
raise ValueError(f"无效的牌索引: {tile_index}")
def get_tile_name(tile_index):
"""
根据牌的索引返回牌名例如1条2筒等
"""
suit = get_suit(tile_index)
return f"{tile_index % 36 + 1}{suit}"
def is_valid_group(tiles):
"""
判断是否是合法的刻子AAA或顺子ABC
"""
if len(tiles) != 3:
return False
tiles.sort(key=lambda t: (t.suit, t.value)) # 按花色和数值排序
# 判断是否为刻子
if tiles[0].value == tiles[1].value == tiles[2].value and \
tiles[0].suit == tiles[1].suit == tiles[2].suit:
return True
# 判断是否为顺子
if 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:
return True
return False
def try_win(remaining_tiles, groups_formed=0):
"""
尝试将剩余牌分组为合法的刻子或顺子,并检查是否有一对将牌。
"""
# 如果没有剩余牌,检查是否形成了四坎牌
if not remaining_tiles:
return groups_formed == 4
# 检查是否可以找到一对将牌
for i in range(len(remaining_tiles) - 1):
if remaining_tiles[i] == remaining_tiles[i + 1]: # 找到对子
temp_tiles = remaining_tiles[:i] + remaining_tiles[i + 2:] # 移除对子
# 尝试分组剩余牌
if try_win(temp_tiles, groups_formed):
return True
# 检查是否可以形成合法组(刻子或顺子)
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)):
group = [remaining_tiles[i], remaining_tiles[j], remaining_tiles[k]]
if is_valid_group(group):
temp_tiles = remaining_tiles[:i] + remaining_tiles[i + 1:j] + \
remaining_tiles[j + 1:k] + remaining_tiles[k + 1:]
if try_win(temp_tiles, groups_formed + 1):
return True
return False