parent
06accd20dd
commit
fbfb4b89e1
|
|
@ -1,7 +1,7 @@
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
from .hand import Hand
|
from src.engine.hand import Hand
|
||||||
from .mahjong_tile import MahjongTile
|
from src.engine.mahjong_tile import MahjongTile
|
||||||
from .meld import Meld # 导入 Meld 类
|
from src.engine.meld import Meld
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -64,13 +64,26 @@ class ChengduMahjongState:
|
||||||
tiles[1].value + 1 == tiles[2].value and
|
tiles[1].value + 1 == tiles[2].value and
|
||||||
tiles[0].suit == tiles[1].suit == tiles[2].suit)
|
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。
|
尝试将剩余牌分组,必须满足 n * AAA + m * ABC + DD。
|
||||||
"""
|
"""
|
||||||
|
# 如果没有剩余牌,检查是否已经找到对子
|
||||||
if not remaining_tiles:
|
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 i in range(len(remaining_tiles)):
|
||||||
for j in range(i + 1, len(remaining_tiles)):
|
for j in range(i + 1, len(remaining_tiles)):
|
||||||
for k in range(j + 1, len(remaining_tiles)):
|
for k in range(j + 1, len(remaining_tiles)):
|
||||||
|
|
@ -78,7 +91,7 @@ class ChengduMahjongState:
|
||||||
if is_valid_group(group):
|
if is_valid_group(group):
|
||||||
next_tiles = remaining_tiles[:i] + remaining_tiles[i + 1:j] + \
|
next_tiles = remaining_tiles[:i] + remaining_tiles[i + 1:j] + \
|
||||||
remaining_tiles[j + 1:k] + remaining_tiles[k + 1:]
|
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 True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
@ -90,27 +103,21 @@ class ChengduMahjongState:
|
||||||
|
|
||||||
# 检查是否打完缺门的花色
|
# 检查是否打完缺门的花色
|
||||||
if any(tile.suit == missing_suit for tile in hand.tiles):
|
if any(tile.suit == missing_suit for tile in hand.tiles):
|
||||||
|
logger.info("仍有缺门花色,不能胡牌")
|
||||||
return False # 仍有缺门的花色,不能胡牌
|
return False # 仍有缺门的花色,不能胡牌
|
||||||
|
|
||||||
# **第二步:合并暗牌和明牌**
|
# **第二步:分离明牌(杠、碰)和暗牌**
|
||||||
all_tiles = hand.tiles[:]
|
# 提取明牌(碰和杠)的组数
|
||||||
|
groups_from_melds = 0
|
||||||
for meld in melds:
|
for meld in melds:
|
||||||
if meld.type == "碰": # 添加碰牌(3 张)
|
if meld.type == "碰":
|
||||||
all_tiles.extend([meld.tile] * 3)
|
groups_from_melds += 1 # 碰牌构成 1 组
|
||||||
elif meld.type == "杠": # 添加杠牌(4 张)
|
elif meld.type == "杠":
|
||||||
all_tiles.extend([meld.tile] * 4)
|
groups_from_melds += 1 # 杠牌也构成 1 组
|
||||||
|
|
||||||
# **第三步:寻找对子并分组**
|
# 获取所有暗牌
|
||||||
# 找到所有对子(至少两张相同的牌)
|
remaining_tiles = hand.tiles[:]
|
||||||
tile_counter = Counter(all_tiles)
|
logger.info(f"暗牌: {remaining_tiles}, 明牌: {melds}, 已构成的组数: {groups_from_melds}")
|
||||||
pairs = [tile for tile, count in tile_counter.items() if count >= 2]
|
|
||||||
|
|
||||||
# 遍历所有对子,尝试用剩余牌分组
|
# **第三步:检查暗牌是否满足分组条件**
|
||||||
for pair in pairs:
|
return try_win(remaining_tiles, pairs_found=False) and groups_from_melds >= 0
|
||||||
temp_tiles = all_tiles[:]
|
|
||||||
temp_tiles.remove(pair) # 移除一张将牌
|
|
||||||
temp_tiles.remove(pair) # 再移除一张将牌
|
|
||||||
if try_win(temp_tiles): # 检查是否可以分组
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False # 如果没有找到符合条件的组合,则不能胡牌
|
|
||||||
8
test.py
8
test.py
|
|
@ -2,6 +2,7 @@ from src.engine.chengdu_mahjong_state import ChengduMahjongState
|
||||||
from src.engine.hand import Hand
|
from src.engine.hand import Hand
|
||||||
|
|
||||||
from src.engine.mahjong_tile import MahjongTile
|
from src.engine.mahjong_tile import MahjongTile
|
||||||
|
from src.engine.meld import Meld
|
||||||
|
|
||||||
hand = Hand()
|
hand = Hand()
|
||||||
|
|
||||||
|
|
@ -25,11 +26,12 @@ state.hands[0] = hand
|
||||||
|
|
||||||
# 设置明牌(杠)
|
# 设置明牌(杠)
|
||||||
melds_list = [
|
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 = "万"
|
missing_suit = "万"
|
||||||
print(f"\n当前手牌: {state.hands[0]}, 明牌: {state.melds[0]}")
|
print(f"\n当前手牌: {state.hands[0]}, 明牌: {state.melds[0]}")
|
||||||
state.can_win(state.hands[0], state.melds[0], missing_suit)
|
|
||||||
|
print(f"是否可以胡: {state.can_win(state.hands[0], state.melds[0], missing_suit)}")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue