Update game_state.py

dev
wangsiyuan 2024-11-30 22:47:44 +08:00
parent b2d9514d2a
commit f8fadb435c
1 changed files with 22 additions and 21 deletions

View File

@ -1,23 +1,24 @@
from .utils import get_suit,get_tile_name from collections import Counter
from loguru import logger from .hand import Hand
from .mahjong_tile import MahjongTile
class ChengduMahjongState: class ChengduMahjongState:
def __init__(self): def __init__(self):
# 每个玩家的手牌使用108个索引表示 # 每个玩家的手牌
self.hands = [[0] * 108 for _ in range(4)] # 每个玩家108张牌的计数 self.hands = [Hand() for _ in range(4)] # 每个玩家的手牌由 Hand 类表示
# 每个玩家的打出的牌 # 每个玩家的打出的牌
self.discards = [[] for _ in range(4)] # 每个玩家的弃牌列表 self.discards = [[] for _ in range(4)] # 每个玩家的弃牌列表
# 每个玩家的明牌(碰、杠) # 每个玩家的明牌(碰、杠)
self.melds = [[] for _ in range(4)] self.melds = [[] for _ in range(4)]
# 剩余的牌堆 # 剩余的牌堆
self.deck = list(range(108)) # 0-107 表示108张牌 self.deck = [MahjongTile(suit, value) for suit in ["", "", ""] for value in range(1, 10)] * 4 # 108张牌
# 当前玩家索引 # 当前玩家索引
self.current_player = 0 self.current_player = 0
# 玩家分数 # 玩家分数
self.scores = [100, 100, 100, 100] self.scores = [100, 100, 100, 100]
# 剩余牌数量 # 剩余牌数量
self.remaining_tiles = 108 self.remaining_tiles = len(self.deck)
# 胜利玩家列表 # 胜利玩家列表
self.winners = [] self.winners = []
# 缺门信息 # 缺门信息
@ -39,21 +40,20 @@ class ChengduMahjongState:
raise ValueError("缺门设置无效") raise ValueError("缺门设置无效")
self.missing_suits[player] = missing_suit self.missing_suits[player] = missing_suit
def can_win(self, hand): def can_win(self, hand: Hand):
""" """
判断是否满足胡牌条件四组顺子或刻子+ 一对将 判断是否满足胡牌条件四组顺子或刻子+ 一对将
""" """
from collections import Counter
def is_valid_group(tiles): def is_valid_group(tiles):
""" """
判断是否为合法的顺子或刻子 判断是否为合法的顺子或刻子
""" """
if len(tiles) != 3: if len(tiles) != 3:
return False return False
tiles.sort() # 确保顺子检查按顺序排列 tiles.sort(key=lambda t: (t.suit, t.value))
return (tiles[0] == tiles[1] == tiles[2]) or \ return (tiles[0] == tiles[1] == tiles[2]) or \
(tiles[0] + 1 == tiles[1] and tiles[1] + 1 == tiles[2]) (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)
def try_win(remaining_tiles, depth=0): def try_win(remaining_tiles, depth=0):
""" """
@ -69,21 +69,22 @@ 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:]
# 确保顺子检查按顺序排列
next_tiles.sort()
if try_win(next_tiles, depth + 1): if try_win(next_tiles, depth + 1):
return True return True
return False 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] tile_counter = Counter(hand.tiles)
pairs = [tile for tile, count in tile_counter.items() if count >= 2]
for pair in pairs: for pair in pairs:
temp_hand = hand[:] # 移除一对将牌
temp_hand[pair] -= 2 # 移除将牌 temp_tiles = hand.tiles[:]
remaining_tiles = [tile for tile, count in enumerate(temp_hand) for _ in range(count)] temp_tiles.remove(pair)
remaining_tiles.sort() # 确保顺子检查按顺序排列 temp_tiles.remove(pair)
if try_win(remaining_tiles):
# 检查剩余牌是否能分组
if try_win(temp_tiles):
return True return True
return False return False