pull/1/head
parent
2a5680fae9
commit
9f7a22be7f
|
|
@ -55,7 +55,7 @@ def peng(self, tile):
|
||||||
logger.info(f"玩家 {player} 碰了一张牌: {tile_name}(索引 {tile})。当前明牌: {self.state.melds[player]}")
|
logger.info(f"玩家 {player} 碰了一张牌: {tile_name}(索引 {tile})。当前明牌: {self.state.melds[player]}")
|
||||||
|
|
||||||
|
|
||||||
def gang(self, tile, mode="ming"):
|
def gang(self, tile, mode):
|
||||||
"""
|
"""
|
||||||
当前玩家杠牌逻辑,记录杠牌类型和状态更新。
|
当前玩家杠牌逻辑,记录杠牌类型和状态更新。
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -67,13 +67,23 @@ def is_seven_pairs(hand):
|
||||||
return sum(1 for count in hand if count == 2) == 7
|
return sum(1 for count in hand if count == 2) == 7
|
||||||
|
|
||||||
|
|
||||||
def is_cleared(hand):
|
def is_cleared(hand, melds):
|
||||||
"""
|
"""
|
||||||
检查手牌是否是清一色。
|
检查手牌和明牌是否是清一色。
|
||||||
"""
|
|
||||||
suits = [tile // 36 for tile, count in enumerate(hand) if count > 0]
|
|
||||||
return len(set(suits)) == 1
|
|
||||||
|
|
||||||
|
参数:
|
||||||
|
- hand: 当前胡牌的手牌(长度为108的列表,表示每张牌的数量)。
|
||||||
|
- melds: 碰杠等明牌列表。
|
||||||
|
|
||||||
|
返回:
|
||||||
|
- bool: 是否为清一色。
|
||||||
|
"""
|
||||||
|
# 获取所有牌的花色
|
||||||
|
all_tiles = hand + [tile for meld in melds for tile in meld]
|
||||||
|
suits = [tile // 36 for tile in all_tiles if tile > 0]
|
||||||
|
|
||||||
|
# 检查是否有多种花色
|
||||||
|
return len(set(suits)) == 1
|
||||||
|
|
||||||
def is_big_pairs(hand):
|
def is_big_pairs(hand):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,9 @@ class ChengduMahjongState:
|
||||||
if missing_suit not in valid_suits:
|
if missing_suit not in valid_suits:
|
||||||
logger.error(f"玩家 {player} 尝试设置无效的缺门: {missing_suit}")
|
logger.error(f"玩家 {player} 尝试设置无效的缺门: {missing_suit}")
|
||||||
raise ValueError("缺门设置无效")
|
raise ValueError("缺门设置无效")
|
||||||
|
|
||||||
self.missing_suits[player] = missing_suit
|
self.missing_suits[player] = missing_suit
|
||||||
logger.info(f"玩家 {player} 设置缺门为: {missing_suit}")
|
logger.info(f"玩家 {player} 设置缺门为: {missing_suit}")
|
||||||
|
return self.missing_suits[player]
|
||||||
|
|
||||||
def can_win(self, hand):
|
def can_win(self, hand):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import gym
|
import gym
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from gym import spaces
|
from gym import spaces
|
||||||
|
from src.engine.actions import draw_tile, discard_tile, peng, gang, check_blood_battle
|
||||||
from src.engine.calculate_fan import calculate_fan, is_seven_pairs, is_cleared, is_big_pairs
|
from src.engine.calculate_fan import calculate_fan, is_seven_pairs, is_cleared, is_big_pairs
|
||||||
from src.engine.chengdu_mahjong_engine import ChengduMahjongEngine
|
from src.engine.chengdu_mahjong_engine import ChengduMahjongEngine
|
||||||
from src.engine.scoring import calculate_score
|
from src.engine.scoring import calculate_score
|
||||||
|
|
@ -25,19 +25,40 @@ class MahjongEnv(gym.Env):
|
||||||
return self.engine.state.hands[self.engine.state.current_player]
|
return self.engine.state.hands[self.engine.state.current_player]
|
||||||
|
|
||||||
def step(self, action):
|
def step(self, action):
|
||||||
|
"""
|
||||||
|
每一步游戏,基于玩家的动作更新游戏状态。
|
||||||
|
action:表示玩家的动作,可以是摸牌、打牌、碰牌等。
|
||||||
|
"""
|
||||||
|
done = False
|
||||||
|
reward = 0
|
||||||
|
|
||||||
|
# 根据action类型选择执行的动作
|
||||||
try:
|
try:
|
||||||
# 执行玩家动作
|
if action == 0: # 0代表摸牌
|
||||||
self.engine.discard_tile(action)
|
reward, done = draw_tile(self.engine)
|
||||||
|
elif action == 1: # 1代表打牌
|
||||||
|
tile = self.engine.state.hands[self.engine.state.current_player][0] # 假设选择第一张牌
|
||||||
|
discard_tile(self.engine, tile)
|
||||||
|
reward, done = -1, False
|
||||||
|
elif action == 2: # 2代表碰牌
|
||||||
|
tile = self.engine.state.hands[self.engine.state.current_player][0] # 假设选择第一张牌
|
||||||
|
peng(self.engine, tile)
|
||||||
|
reward, done = 0, False
|
||||||
|
elif action == 3: # 3代表杠牌
|
||||||
|
tile = self.engine.state.hands[self.engine.state.current_player][0] # 假设选择第一张牌
|
||||||
|
gang(self.engine, tile, mode="ming") # 暂时假设为明杠
|
||||||
|
reward, done = 0, False
|
||||||
|
|
||||||
# 检查是否胡牌
|
# 检查是否胡牌
|
||||||
if self.engine.state.can_win(self.engine.state.hands[self.engine.state.current_player]):
|
if self.engine.state.can_win(self.engine.state.hands[self.engine.state.current_player]):
|
||||||
reward, done = self.handle_win()
|
reward, done = self.handle_win()
|
||||||
else:
|
|
||||||
reward, done = -1, False # 默认小惩罚
|
|
||||||
|
|
||||||
# 检查是否有玩家分数 <= 0
|
# 检查游戏结束条件
|
||||||
if any(score <= 0 for score in self.scores):
|
check_blood_battle(self.engine)
|
||||||
|
|
||||||
|
if self.engine.game_over:
|
||||||
done = True
|
done = True
|
||||||
reward = -100 # 游戏结束的惩罚(可根据需求调整)
|
|
||||||
except ValueError:
|
except ValueError:
|
||||||
reward, done = -10, False # 非法操作扣分
|
reward, done = -10, False # 非法操作扣分
|
||||||
|
|
||||||
|
|
@ -62,7 +83,7 @@ class MahjongEnv(gym.Env):
|
||||||
is_self_draw = True # 假设自摸(后续可动态判断)
|
is_self_draw = True # 假设自摸(后续可动态判断)
|
||||||
|
|
||||||
conditions = {
|
conditions = {
|
||||||
"is_cleared": is_cleared(hand),
|
"is_cleared": is_cleared(hand, melds),
|
||||||
"is_seven_pairs": is_seven_pairs(hand),
|
"is_seven_pairs": is_seven_pairs(hand),
|
||||||
"is_big_pairs": is_big_pairs(hand),
|
"is_big_pairs": is_big_pairs(hand),
|
||||||
# 添加其他条件...
|
# 添加其他条件...
|
||||||
|
|
@ -79,10 +100,11 @@ class MahjongEnv(gym.Env):
|
||||||
|
|
||||||
# 奖励设置为赢家得分
|
# 奖励设置为赢家得分
|
||||||
reward = scores["winner"]
|
reward = scores["winner"]
|
||||||
done = True # 胡牌结束当前局
|
self.engine.state.winners.append(winner) # 添加赢家到列表
|
||||||
return reward, done
|
|
||||||
|
# 如果有玩家分数 <= 0,可进行其他处理,如记录惩罚或结束游戏
|
||||||
|
if any(score <= 0 for score in self.scores):
|
||||||
|
self.engine.game_over = True # 设置游戏结束标志
|
||||||
|
|
||||||
|
return reward, True # 胡牌结束当前局
|
||||||
|
|
||||||
def render(self, mode="human"):
|
|
||||||
print(f"当前轮数: {self.current_round}")
|
|
||||||
print("玩家分数:", self.scores)
|
|
||||||
print("当前玩家状态:", self.engine.state.hands[self.engine.state.current_player])
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue