Skip to content

Commit

Permalink
暗槓に対する国士無双の槍槓をチェックする.
Browse files Browse the repository at this point in the history
  • Loading branch information
shinkuan committed Aug 14, 2023
1 parent 65c08a9 commit 0cba7cb
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 3 deletions.
17 changes: 15 additions & 2 deletions _kanachan.py
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,14 @@
)


_TILE34TILE37 = (
1, 2, 3, 4, 5, 6, 7, 8, 9,
11,12,13,14,15,16,17,18,19,
21,22,23,24,25,26,27,28,29,
30,31,32,33,34,35,36
)


class GameState:
def __init__(
self, *, my_name: str, room: int, game_style: int, my_grade: int,
Expand Down Expand Up @@ -1170,8 +1178,13 @@ def on_angang(
self.__progression.append(1881 + actor * 34 + angang)

if seat != actor:
# TODO: 暗槓に対する国士無双の槍槓をチェックする.
return None
# 暗槓に対する国士無双の槍槓をチェックする.
player_wind = (seat + 4 - self.__index) % 4
can_ron_kokushi = self.__hand_calculator.check_kokushi(
self.__chang, player_wind, self.__my_hand, self.__my_fulu_list,
_TILE34TILE37[angang], rong=False)
if not can_ron_kokushi:
return None

if self.__zimo_pai is None:
raise RuntimeError('TODO: (A suitable error message)')
Expand Down
53 changes: 52 additions & 1 deletion hand_calculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from mahjong.meld import Meld
from mahjong.hand_calculating.hand_config import (OptionalRules, HandConfig,)
from mahjong.hand_calculating.hand import HandCalculator as Impl
from mahjong.hand_calculating.yaku_list import yakuman


_FULU2MELD = {
Expand Down Expand Up @@ -307,7 +308,7 @@ def has_yihan(
melds = []

# `tiles` には副露牌も含めなければならない.
# ただし,槓は3枚としてカウントする
# ただし,槓は4枚としてカウントする
for fulu in fulu_list:
if 148 <= fulu and fulu <= 181:
meld = _FULU2MELD[fulu]
Expand Down Expand Up @@ -397,3 +398,53 @@ def has_yihan(
raise e

return response.han >= 1

def check_kokushi(
self, chang: int, player_wind: int, hand: List[int],
fulu_list: List[int], hupai: int, rong: bool):
options = OptionalRules(has_open_tanyao=True, has_aka_dora=True)
config = HandConfig(
is_tsumo=not rong, player_wind=27 + player_wind,
round_wind=27 + chang, options=options)

hand_calculator = Impl()

if len(fulu_list) > 0 or len(hand) != 13:
return False

tiles = []
for tile in hand:
flag = False
first, last = _TILE_OFFSET_RANGE[tile]
for t in range(first, last):
if t not in tiles:
tiles.append(t)
flag = True
break
if not flag:
raise RuntimeError('TODO: (A suitable error message)')
flag = False
first, last = _TILE_OFFSET_RANGE[hupai]
for t in range(first, last):
if t not in tiles:
tiles.append(t)
flag = True
break
if not flag:
raise RuntimeError('TODO: (A suitable error message)')
tiles.sort()
hupai = _TILE_OFFSET_RANGE[hupai][0]

try:
response = hand_calculator.estimate_hand_value(
tiles=tiles, win_tile=hupai, config=config)
if response.error is not None:
if response.error == 'no_yaku':
return False
raise RuntimeError(response.error)
except Exception as e:
import sys
print(f'tiles = {tiles}', file=sys.stderr)
print(f'hupai = {hupai}', file=sys.stderr)
raise e
return any([isinstance(yaku, yakuman.DaburuKokushiMusou) or isinstance(yaku, yakuman.KokushiMusou) for yaku in response.yaku])

0 comments on commit 0cba7cb

Please sign in to comment.