1
This commit is contained in:
2024-11-30 14:36:32 +08:00
parent 0db865854e
commit 3c416f39be
6 changed files with 166 additions and 30 deletions

View File

@@ -1,4 +1,4 @@
from utils import get_suit, get_tile_name # 确保 get_tile_name 方法已经定义
from .utils import get_suit,get_tile_name
from loguru import logger
@@ -42,41 +42,49 @@ class ChengduMahjongState:
def can_win(self, hand):
"""
判断玩家的手牌是否满足胡牌条件。
参数:
- hand: 玩家当前的手牌长度为108的列表
返回:
- bool: 是否满足胡牌条件。
判断是否满足胡牌条件:四组(顺子或刻子)+ 一对将
"""
from collections import Counter
# 判断缺一门
suits = [get_suit(tile) for tile, count in enumerate(hand) if count > 0]
if len(set(suits)) > 2:
logger.info(f"手牌花色: {set(suits)},未满足缺一门条件")
return False # 不满足缺一门
# 判断是否满足四组+一对
def is_valid_group(tiles):
# 判断是否为顺子、刻子或对子
return len(tiles) == 3 and (tiles[0] == tiles[1] == tiles[2] or
tiles[0] + 1 == tiles[1] and tiles[1] + 1 == tiles[2])
"""
判断是否为合法的顺子或刻子。
"""
if len(tiles) != 3:
return False
tiles.sort() # 确保顺子检查按顺序排列
return (tiles[0] == tiles[1] == tiles[2]) or \
(tiles[0] + 1 == tiles[1] and tiles[1] + 1 == tiles[2])
counter = Counter(hand)
def try_win(remaining_tiles, depth=0):
"""
递归检查是否可以将剩余牌分为合法组合。
"""
if not remaining_tiles:
return depth == 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)):
group = [remaining_tiles[i], remaining_tiles[j], remaining_tiles[k]]
if is_valid_group(group):
next_tiles = remaining_tiles[:i] + remaining_tiles[i + 1:j] + \
remaining_tiles[j + 1:k] + remaining_tiles[k + 1:]
# 确保顺子检查按顺序排列
next_tiles.sort()
if try_win(next_tiles, depth + 1):
return True
return False
counter = Counter({tile: count for tile, count in enumerate(hand) if count > 0})
pairs = [tile for tile, count in counter.items() if count >= 2]
for pair in pairs:
temp_hand = hand[:]
temp_hand[pair] -= 2
# 记录尝试的对子
logger.debug(f"尝试对子: {get_tile_name(pair)}(索引 {pair}")
if is_valid_group(temp_hand):
logger.info(f"满足胡牌条件的对子: {get_tile_name(pair)}(索引 {pair}")
temp_hand[pair] -= 2 # 移除将牌
remaining_tiles = [tile for tile, count in enumerate(temp_hand) for _ in range(count)]
remaining_tiles.sort() # 确保顺子检查按顺序排列
if try_win(remaining_tiles):
return True
logger.info("未找到满足胡牌条件的组合")
return False