1
This commit is contained in:
2024-12-01 04:48:55 +08:00
parent af5721992d
commit b9a2b3bc31
5 changed files with 175 additions and 147 deletions

View File

@@ -97,28 +97,37 @@ def check_blood_battle(self):
self.game_over = True
def set_missing_suit(player, missing_suit, game_state):
def set_missing_suit(player, game_state):
"""
玩家设置缺门的动作
玩家自动根据手牌选择缺门
参数:
- player: 玩家索引0-3
- missing_suit: 玩家选择的缺门("""""")。
- game_state: 当前的游戏状态(`ChengduMahjongState` 实例)。
异常:
- ValueError: 如果缺门设置无效
返回:
- str: 玩家设置的缺门花色
"""
valid_suits = ["", "", ""]
if missing_suit not in valid_suits:
logger.error(f"玩家 {player} 尝试设置无效的缺门: {missing_suit}")
raise ValueError("缺门设置无效")
hand = game_state.hands[player] # 获取玩家手牌
# 统计每种花色的牌数量
suit_counts = {suit: 0 for suit in valid_suits}
for tile in hand.tiles:
suit_counts[tile.suit] += 1
# 找到数量最少的花色
missing_suit = min(suit_counts, key=suit_counts.get)
# 检查是否已经设置过缺门
if game_state.missing_suits[player] is not None:
logger.error(f"玩家 {player}设置缺门,不能重复设置")
logger.warning(f"玩家 {player} 已设置缺门,不能重复设置")
raise ValueError("缺门已经设置,不能重复设置")
# 设置缺门并记录日志
game_state.missing_suits[player] = missing_suit
logger.info(f"玩家 {player} 设置缺门为: {missing_suit}")
logger.info(
f"玩家 {player} 手牌花色分布: {suit_counts}。缺门设置为: {missing_suit}"
)
return game_state.missing_suits[player]
return missing_suit

View File

@@ -1,47 +1,99 @@
import random
from loguru import logger
from .chengdu_mahjong_state import ChengduMahjongState
from src.engine.actions import set_missing_suit
from src.engine.chengdu_mahjong_state import ChengduMahjongState
from src.engine.actions import draw_tile, discard_tile, peng, gang, check_blood_battle
class ChengduMahjongEngine:
def __init__(self):
self.state = ChengduMahjongState() # 创建游戏状态
self.state = ChengduMahjongState()
self.game_over = False
self.game_started = False # 游戏是否已开始
self.deal_tiles() # 发牌
self.game_started = False
self.current_player = 0
def initialize_game(self):
"""
初始化游戏,确定庄家,发牌并设置缺门。
"""
logger.info("游戏初始化...")
# 确定庄家(掷骰子)
self.state.current_player = random.randint(0, 3)
logger.info(f"庄家确定为玩家 {self.state.current_player}")
logger.info("游戏初始化完成,准备开始!")
def deal_tiles(self):
""" 发牌,每个玩家13张牌,并设置缺门 """
logger.info("发牌...")
""" 发牌庄家摸14张其余玩家13张 """
logger.info("开始发牌...")
random.shuffle(self.state.deck) # 洗牌
# 洗牌(随机打乱牌堆)
random.shuffle(self.state.deck)
# 随机发牌给每个玩家
for player in range(4):
for _ in range(13): # 每个玩家13张牌
tile = self.state.deck.pop() # 从牌堆抽取一张牌
self.state.hands[player][tile] += 1 # 增加玩家手牌的计数
tiles_to_draw = 14 if player == self.state.current_player else 13
for _ in range(tiles_to_draw):
tile = self.state.deck.pop()
self.state.hands[player].add_tile(tile)
# 设置缺门:每个玩家定缺(这里假设我们让每个玩家的缺门都为“条”)
for player in range(4):
missing_suit = "" # 这里可以通过其他方式设置缺门,比如随机选择
self.state.set_missing_suit(player, missing_suit)
# 自动设置缺门
set_missing_suit(player, self.state)
def start_game(self):
""" 开始游戏 """
if not self.game_started:
self.game_started = True
logger.info("游戏开始!")
else:
logger.warning("游戏已经开始,不能重复启动!")
logger.info("发牌结束并完成缺门设置!")
def play_turn(self):
"""
进行一回合的操作:当前玩家摸牌、出牌。
"""
logger.info(f"轮到玩家 {self.state.current_player} 行动")
# 玩家摸牌
reward, done = draw_tile(self)
if done:
logger.info("游戏因牌堆摸空而结束!")
return
# 玩家打牌(逻辑可扩展为选择最佳牌)
tile_to_discard = self.select_discard_tile(self.state.current_player)
discard_tile(self, tile_to_discard)
# 检查游戏是否结束
self.check_game_over()
# 切换到下一位玩家
self.state.current_player = (self.state.current_player + 1) % 4
def select_discard_tile(self, player):
"""
选择要打出的牌(此处为简单示例,可接入 AI 策略)。
"""
hand = self.state.hands[player]
# 优先打出缺门牌
for tile in hand.tiles:
if tile.suit == self.state.missing_suits[player]:
return tile
# 如果没有缺门牌,随机打出一张
return hand.tiles[0]
def check_game_over(self):
""" 检查游戏是否结束 """
# 你可以根据游戏规则检查是否有玩家胡牌或其他结束条件
if len(self.state.deck) == 0:
"""
检查游戏是否结束。
"""
# 检查是否已无牌可摸
if self.state.remaining_tiles == 0:
self.game_over = True
logger.info("游戏结束")
logger.info("游戏结束:牌堆已空")
return
# 检查是否满足血战结束条件
check_blood_battle(self)
def run(self):
"""
运行游戏主循环。
"""
self.initialize_game()
self.game_started = True
while not self.game_over:
self.play_turn()
logger.info("游戏已结束")

View File

@@ -163,3 +163,5 @@ def is_dragon_seven_pairs(hand, melds):
return 12, -1 # 龙七对计为 12 番,并减少 1 根
return 0, 0