1
1
This commit is contained in:
@@ -2,6 +2,7 @@ from random import random
|
||||
|
||||
from loguru import logger
|
||||
from src.engine.mahjong_tile import MahjongTile
|
||||
from src.engine.calculate_fan import calculate_fan
|
||||
|
||||
|
||||
def draw_tile(engine):
|
||||
@@ -204,21 +205,21 @@ def check_other_players(self, tile):
|
||||
# 优先检查胡牌
|
||||
if self.can_win(self.state.hands[player], self.state.melds[player], self.state.missing_suits[player]):
|
||||
logger.info(f"玩家 {player} 可以胡玩家 {current_player} 的牌: {tile}")
|
||||
self.handle_win(player, current_player, tile)
|
||||
handle_win(player, current_player, tile)
|
||||
actions_taken = True
|
||||
break # 胡牌后结束
|
||||
|
||||
# 检查是否可以杠牌
|
||||
if self.state.hands[player].tile_count[tile] >= 3:
|
||||
logger.info(f"玩家 {player} 可以杠玩家 {current_player} 的牌: {tile}")
|
||||
if self.handle_gang(player, tile, mode="ming"): # 执行明杠逻辑
|
||||
if handle_gang(player, tile, mode="ming"): # 执行明杠逻辑
|
||||
actions_taken = True
|
||||
break # 杠牌后不检查其他玩家
|
||||
|
||||
# 检查是否可以碰牌
|
||||
if self.state.hands[player].tile_count[tile] >= 2:
|
||||
logger.info(f"玩家 {player} 可以碰玩家 {current_player} 的牌: {tile}")
|
||||
if self.handle_peng(player, tile): # 执行碰牌逻辑
|
||||
if handle_peng(player, tile): # 执行碰牌逻辑
|
||||
actions_taken = True
|
||||
break # 碰牌后不检查其他玩家
|
||||
|
||||
@@ -241,22 +242,10 @@ def handle_peng(self, player, tile):
|
||||
|
||||
logger.info(f"玩家 {player} 碰了牌: {tile}。当前明牌: {self.state.melds[player]}")
|
||||
|
||||
# 设置出牌顺序为碰牌的玩家
|
||||
self.state.current_player = player
|
||||
|
||||
# 提供玩家手牌信息,等待玩家选择打出的牌
|
||||
chosen_tile = self.get_player_discard_choice(player)
|
||||
|
||||
# 验证玩家选择的牌是否合法
|
||||
if chosen_tile not in self.state.hands[player].tiles:
|
||||
logger.error(f"玩家 {player} 选择了不合法的牌: {chosen_tile}")
|
||||
raise ValueError("打出的牌必须存在于玩家的手牌中")
|
||||
|
||||
# 玩家选择打出这张牌
|
||||
self.discard_tile(player, chosen_tile)
|
||||
return True
|
||||
|
||||
|
||||
|
||||
def get_player_discard_choice(self, player):
|
||||
"""
|
||||
模拟获取玩家打牌的选择。
|
||||
@@ -273,28 +262,53 @@ def get_player_discard_choice(self, player):
|
||||
|
||||
def handle_gang(self, player, tile, mode):
|
||||
"""
|
||||
处理玩家杠牌逻辑并更新状态。
|
||||
处理玩家杠牌逻辑、计算分数并更新状态。
|
||||
:param player: 杠牌玩家索引
|
||||
:param tile: 杠牌的那张牌
|
||||
:param mode: 杠牌的类型 ("ming" 或 "an")
|
||||
:return: True 如果操作成功,否则 False
|
||||
"""
|
||||
if mode == "ming" and self.state.hands[player].tile_count[tile] < 3:
|
||||
logger.error(f"玩家 {player} 无法明杠: {tile}")
|
||||
return False
|
||||
base_score = self.state.bottom_score # 底分
|
||||
|
||||
# 减少牌数量并更新明牌
|
||||
if mode == "ming":
|
||||
if mode == "ming": # 明杠逻辑
|
||||
if self.state.hands[player].tile_count[tile] < 3:
|
||||
logger.error(f"玩家 {player} 无法明杠: {tile}")
|
||||
return None
|
||||
|
||||
# 减少牌数量并更新明牌
|
||||
self.state.hands[player].tile_count[tile] -= 3
|
||||
self.state.melds[player].append(("ming_gang", tile))
|
||||
self.state.melds[player].append(("杠", tile))
|
||||
logger.info(f"玩家 {player} 明杠了牌: {tile}")
|
||||
elif mode == "an":
|
||||
|
||||
# 明杠分数计算
|
||||
gang_score = base_score * 2 # 明杠的分数倍率
|
||||
for i in range(4):
|
||||
if i != player:
|
||||
self.state.scores[i] -= gang_score # 每个其他玩家扣分
|
||||
self.state.scores[player] += gang_score * 3 # 杠牌玩家得总分
|
||||
|
||||
logger.info(f"玩家 {player} 明杠,总分变化: +{gang_score * 3},其他玩家每人扣分: -{gang_score}")
|
||||
return True
|
||||
|
||||
elif mode == "an": # 暗杠逻辑
|
||||
if self.state.hands[player].tile_count[tile] < 4:
|
||||
logger.error(f"玩家 {player} 无法暗杠: {tile}")
|
||||
return False
|
||||
|
||||
# 减少牌数量并更新暗牌
|
||||
self.state.hands[player].tile_count[tile] -= 4
|
||||
self.state.melds[player].append(("an_gang", tile))
|
||||
logger.info(f"玩家 {player} 暗杠了牌: {tile}")
|
||||
|
||||
# 杠牌后玩家补摸一张牌
|
||||
self.draw_tile_for_player(player)
|
||||
return True
|
||||
# 暗杠分数计算
|
||||
gang_score = base_score * 4 # 暗杠的分数倍率
|
||||
for i in range(4):
|
||||
if i != player:
|
||||
self.state.scores[i] -= gang_score # 每个其他玩家扣分
|
||||
self.state.scores[player] += gang_score * 3 # 杠牌玩家得总分
|
||||
|
||||
logger.info(f"玩家 {player} 暗杠,总分变化: +{gang_score * 3},其他玩家每人扣分: -{gang_score}")
|
||||
return True
|
||||
|
||||
|
||||
def random_discard_tile(engine):
|
||||
@@ -401,3 +415,40 @@ def select_discard_tile(self, player):
|
||||
return tile
|
||||
# 如果没有缺门牌,随机打出一张
|
||||
return hand.tiles[0]
|
||||
|
||||
|
||||
|
||||
def handle_win(self, player, current_player, tile):
|
||||
"""
|
||||
处理胡牌逻辑,包括判断地胡,计算番数和分数。
|
||||
:param player: 胡牌玩家索引
|
||||
:param current_player: 打出牌的玩家索引
|
||||
:param tile: 胡牌的那张牌
|
||||
"""
|
||||
logger.info(f"玩家 {player} 胡牌!胡的牌是: {tile}")
|
||||
|
||||
# 判断是否地胡
|
||||
is_dihu = self.state.draw_counts[player] == 0 and player != self.state.current_player
|
||||
if is_dihu:
|
||||
logger.info(f"玩家 {player} 地胡!")
|
||||
else:
|
||||
logger.info(f"玩家 {player} 不是地胡")
|
||||
|
||||
# 计算分数
|
||||
fan_count = 5 # 按你逻辑固定番数为5
|
||||
base_score = self.state.bottom_score # 底分
|
||||
win_score = base_score * (2 ** fan_count)
|
||||
|
||||
self.state.scores[player] += win_score * 3 # 胡牌玩家得总分
|
||||
self.state.scores[current_player] -= win_score # 点炮玩家扣除分数
|
||||
|
||||
# 更新赢家状态
|
||||
self.state.winners.append(player)
|
||||
self.state.print_game_state(player)
|
||||
|
||||
# 输出日志
|
||||
logger.info(f"玩家 {player} 胡牌类型: {'地胡' if is_dihu else '普通胡牌'}")
|
||||
logger.info(f"玩家 {player} 总番数: {fan_count}")
|
||||
logger.info(f"玩家 {current_player} 点炮,扣分: {win_score}")
|
||||
logger.info(f"玩家 {player} 加分: {win_score * 3}")
|
||||
logger.info(f"当前分数: {self.state.scores}")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import random
|
||||
from loguru import logger
|
||||
from src.engine.actions import set_missing_suit
|
||||
from src.engine.actions import set_missing_suit, check_other_players
|
||||
from src.engine.chengdu_mahjong_state import ChengduMahjongState
|
||||
from src.engine.actions import draw_tile, discard_tile, peng, gang, check_blood_battle,should_gang,random_choice
|
||||
|
||||
@@ -84,7 +84,7 @@ class ChengduMahjongEngine:
|
||||
logger.info(f"玩家 {self.current_player} 杠牌,类型: {gang_type}")
|
||||
else:
|
||||
random_choice(self.state.hands[self.current_player], self.state.missing_suits[self.current_player])
|
||||
|
||||
check_other_players(self.state.hands[self.current_player], self.state.missing_suits[self.current_player])
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user