wangsiyuan 2024-12-01 00:34:47 +08:00
parent 33b1cc761a
commit 8a966890d5
3 changed files with 114 additions and 8 deletions

37
src/engine/meld.py Normal file
View File

@ -0,0 +1,37 @@
from src.engine.mahjong_tile import MahjongTile
class Meld:
def __init__(self, tile, type: str):
"""
初始化一个碰或杠的对象
:param tile: MahjongTile 对象表示碰或杠的牌
:param type: 字符串'' ''表示碰或杠
"""
if not isinstance(tile, MahjongTile):
raise TypeError("tile 必须是 MahjongTile 类型")
if type not in ['', '']:
raise ValueError("type 必须是 ''''")
self.tile = tile
self.type = type
self.count = 3 if type == '' else 4 # 碰为3张杠为4张
def __repr__(self):
return f"({self.type}: {self.tile} x{self.count})"
def __eq__(self, other):
if not isinstance(other, Meld):
return False
return self.tile == other.tile and self.type == other.type
def __hash__(self):
return hash((self.tile, self.type))
def is_triplet(self):
"""是否为碰"""
return self.type == ''
def is_kong(self):
"""是否为杠"""
return self.type == ''

38
test.py
View File

@ -1,3 +1,35 @@
import torch from src.engine.chengdu_mahjong_state import ChengduMahjongState
print(torch.cuda.is_available()) # 如果返回True说明可以使用GPU from src.engine.hand import Hand
print(torch.__version__)
from src.engine.mahjong_tile import MahjongTile
hand = Hand()
# 添加暗牌
hand.add_tile(MahjongTile("", 6))
hand.add_tile(MahjongTile("", 6))
hand.add_tile(MahjongTile("", 6))
hand.add_tile(MahjongTile("", 7))
hand.add_tile(MahjongTile("", 7))
hand.add_tile(MahjongTile("", 7))
hand.add_tile(MahjongTile("", 8))
hand.add_tile(MahjongTile("", 8))
hand.add_tile(MahjongTile("", 8))
# 添加对子
hand.add_tile(MahjongTile("", 2))
hand.add_tile(MahjongTile("", 2))
# 初始化游戏状态
state = ChengduMahjongState()
state.hands[0] = hand
# 设置明牌(杠)
melds_list = [
("", MahjongTile("", 9)), # 表示明杠了4张9筒
]
state.melds[0] = melds_list
# 设置缺门为 "万"
missing_suit = ""
print(f"\n当前手牌: {state.hands[0]}, 明牌: {state.melds[0]}")
state.can_win(state.hands[0], state.melds[0], missing_suit)

View File

@ -41,6 +41,7 @@ def test_can_win_with_pure_sequences():
hand.add_tile(MahjongTile("", 5)) hand.add_tile(MahjongTile("", 5))
state = ChengduMahjongState() state = ChengduMahjongState()
state.melds[0] = []
state.hands[0] = hand state.hands[0] = hand
# 设置缺门为 "条",因为手牌中没有 "条" # 设置缺门为 "条",因为手牌中没有 "条"
@ -48,7 +49,7 @@ def test_can_win_with_pure_sequences():
print(f"\n,state.hand[0]: {state.hands[0]}") print(f"\n,state.hand[0]: {state.hands[0]}")
# 调用 can_win 方法并断言胡牌 # 调用 can_win 方法并断言胡牌
assert state.can_win(state.hands[0], missing_suit) == True, "测试失败:纯顺子应该可以胡牌" assert state.can_win(state.hands[0], state.melds[0],missing_suit) == True, "测试失败:纯顺子应该可以胡牌"
def test_can_win_with_sequence_and_triplet(): def test_can_win_with_sequence_and_triplet():
@ -72,13 +73,14 @@ def test_can_win_with_sequence_and_triplet():
state = ChengduMahjongState() state = ChengduMahjongState()
state.hands[0] = hand state.hands[0] = hand
state.melds[0] = []
# 设置缺门为 "条",因为手牌中没有 "条" # 设置缺门为 "条",因为手牌中没有 "条"
missing_suit = "" missing_suit = ""
print(f"\n,state.hand[0]: {state.hands[0]}") print(f"\n,state.hand[0]: {state.hands[0]}")
# 调用 can_win 方法并断言胡牌 # 调用 can_win 方法并断言胡牌
assert state.can_win(state.hands[0], missing_suit) == True, "测试失败:顺子 + 刻子应该可以胡牌" assert state.can_win(state.hands[0], state.melds[0],missing_suit) == True, "测试失败:顺子 + 刻子应该可以胡牌"
def test_can_win_with_triplets_and_pair(): def test_can_win_with_triplets_and_pair():
"""测试刻子和对子胡牌""" """测试刻子和对子胡牌"""
@ -100,13 +102,13 @@ def test_can_win_with_triplets_and_pair():
state = ChengduMahjongState() state = ChengduMahjongState()
state.hands[0] = hand state.hands[0] = hand
state.melds[0] = []
# 设置缺门为 "万",因为手牌中没有 "万" # 设置缺门为 "万",因为手牌中没有 "万"
missing_suit = "" missing_suit = ""
print(f"\n,state.hand[0]: {state.hands[0]}") print(f"\n,state.hand[0]: {state.hands[0]}")
# 调用 can_win 方法并断言胡牌 # 调用 can_win 方法并断言胡牌
assert state.can_win(state.hands[0], missing_suit) == True, "测试失败:刻子和对子应该可以胡牌" assert state.can_win(state.hands[0], state.melds[0],missing_suit) == True, "测试失败:刻子和对子应该可以胡牌"
def test_can_win_with_pure_one_suit(): def test_can_win_with_pure_one_suit():
@ -130,12 +132,47 @@ def test_can_win_with_pure_one_suit():
state = ChengduMahjongState() state = ChengduMahjongState()
state.hands[0] = hand state.hands[0] = hand
state.melds[0] = []
# 设置缺门为 "万",因为手牌中只有 "筒" # 设置缺门为 "万",因为手牌中只有 "筒"
missing_suit = "" missing_suit = ""
print(f"\n,state.hand[0]: {state.hands[0]}") print(f"\n,state.hand[0]: {state.hands[0]}")
# 调用 can_win 方法并断言胡牌 # 调用 can_win 方法并断言胡牌
assert state.can_win(state.hands[0], missing_suit) == True, "测试失败:清一色不带杠应该可以胡牌" assert state.can_win(state.hands[0], state.melds[0],missing_suit) == True, "测试失败:清一色不带杠应该可以胡牌"
def test_can_win_with_pure_one_suit_and_gang():
"""测试带杠的清一色胡牌"""
hand = Hand()
# 添加暗牌
hand.add_tile(MahjongTile("", 6))
hand.add_tile(MahjongTile("", 6))
hand.add_tile(MahjongTile("", 6))
hand.add_tile(MahjongTile("", 7))
hand.add_tile(MahjongTile("", 7))
hand.add_tile(MahjongTile("", 7))
hand.add_tile(MahjongTile("", 8))
hand.add_tile(MahjongTile("", 8))
hand.add_tile(MahjongTile("", 8))
# 添加对子
hand.add_tile(MahjongTile("", 2))
hand.add_tile(MahjongTile("", 2))
# 初始化游戏状态
state = ChengduMahjongState()
state.hands[0] = hand
# 设置明牌(杠)
melds_list = [
("", MahjongTile("", 9))
]
state.melds[0] = melds_list
# 设置缺门为 "万"
missing_suit = ""
print(f"\n当前手牌: {state.hands[0]}, 明牌: {state.melds[0]}")
# 调用 can_win 方法并断言胡牌
assert state.can_win(state.hands[0], state.melds[0], missing_suit) == True, "测试失败:带杠的清一色应该可以胡牌"