Skip to content

Commit

Permalink
升级0.6.6 (#23)
Browse files Browse the repository at this point in the history
* 升级0.6.5

* 升级0.6.6

* 升级0.6.6
  • Loading branch information
ssttkkl authored Feb 28, 2024
1 parent 7d8fbda commit b5e2591
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 44 deletions.
2 changes: 1 addition & 1 deletion kt
Submodule kt updated 255 files
14 changes: 11 additions & 3 deletions mahjong_utils/bridge/lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import sys
import threading
from importlib import resources
from typing import Optional, Mapping, Any

import cffi

Expand Down Expand Up @@ -34,15 +35,22 @@ def lib_sy(self):
self._lib_sy.value = self.lib.libmahjongutils_symbols()
return self._lib_sy.value

def call(self, name: str, params: dict) -> dict:
params = json.dumps(params)
def call(self, name: str, params: dict,
params_dumps_kwargs: Optional[Mapping[str, Any]] = None,
result_loads_kwargs: Optional[Mapping[str, Any]] = None) -> dict:
if params_dumps_kwargs is None:
params_dumps_kwargs = {}
if result_loads_kwargs is None:
result_loads_kwargs = {}

params = json.dumps(params, **params_dumps_kwargs)

result = self.lib_sy.kotlin.root.mahjongutils.entry.call(
self.ffi.new("char[]", name.encode()),
self.ffi.new("char[]", params.encode()))
result = self.ffi.string(result)

result = json.loads(result)
result = json.loads(result, **result_loads_kwargs)

if result['code'] == 200:
return result['data']
Expand Down
1 change: 0 additions & 1 deletion mahjong_utils/bridge/lib/libmahjongutils_api.i
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ typedef unsigned int libmahjongutils_KUInt;
typedef unsigned long long libmahjongutils_KULong;
typedef float libmahjongutils_KFloat;
typedef double libmahjongutils_KDouble;
// typedef float __attribute__ ((__vector_size__ (16))) libmahjongutils_KVector128;
typedef void* libmahjongutils_KNativePtr;
struct libmahjongutils_KType;
typedef struct libmahjongutils_KType libmahjongutils_KType;
Expand Down
6 changes: 5 additions & 1 deletion mahjong_utils/bridge/webapi_jar/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
from urllib.error import HTTPError
from urllib.request import Request, urlopen

from ..protocol import MahjongUtilsBridge
from .path import mahjongutils_webapi_jar_path
from ..protocol import MahjongUtilsBridge


def _java_executable() -> Path:
Expand All @@ -35,6 +35,7 @@ def _java_executable() -> Path:
else:
raise RuntimeError("Cannot find java executable in your PATH environment variable. ")


def _is_port_occupied(port: int):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
code = s.connect_ex(("127.0.0.1", port))
Expand Down Expand Up @@ -112,3 +113,6 @@ def call(self, name: str, params: dict) -> dict:
def close(self):
current: Optional[Popen] = getattr(self._process, "value", None)
current.terminate()


__all__ = ("WebApiJarMahjongUtils",)
45 changes: 31 additions & 14 deletions mahjong_utils/hora/hora.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from stringcase import pascalcase

from mahjong_utils.bridge import bridge_mahjongutils
from mahjong_utils.hora.models import Hora
from mahjong_utils.hora.models import Hora, HoraOptions
from mahjong_utils.models.furo import Furo
from mahjong_utils.models.tile import Tile
from mahjong_utils.models.wind import Wind
Expand All @@ -16,7 +16,8 @@ def build_hora(
tsumo: bool,
*, dora: int = 0,
self_wind: Optional[Wind] = None, round_wind: Optional[Wind] = None,
extra_yaku: Optional[Set[Yaku]] = None
extra_yaku: Optional[Set[Yaku]] = None,
options: Optional[HoraOptions] = None
) -> Hora:
"""
和牌分析
Expand All @@ -31,16 +32,25 @@ def build_hora(
:param extra_yaku: 额外役
:return: 和牌分析结果
"""
result = bridge_mahjongutils.call("hora", {
args = {
"tiles": [str(t) for t in tiles],
"furo": [fr.__encode__() for fr in furo] if furo is not None else [],
"agari": str(agari),
"tsumo": tsumo,
"dora": dora,
"selfWind": pascalcase(self_wind.name) if self_wind is not None else None,
"roundWind": pascalcase(round_wind.name) if round_wind is not None else None,
"extraYaku": [pascalcase(yk.name) for yk in extra_yaku] if extra_yaku is not None else []
})
}
if furo is not None:
args["furo"] = [fr.__encode__() for fr in furo]
if self_wind is not None:
args["selfWind"] = pascalcase(self_wind.name)
if round_wind is not None:
args["roundWind"] = pascalcase(round_wind.name)
if furo is not None:
args["furo"] = [fr.__encode__() for fr in furo]
if extra_yaku is not None:
args["extraYaku"] = [pascalcase(yk.name) for yk in extra_yaku]
if options is not None:
args["options"] = options.__encode__()
result = bridge_mahjongutils.call("hora", args)

return Hora.__decode__(result)

Expand All @@ -51,7 +61,8 @@ def build_hora_from_shanten_result(
tsumo: bool,
*, dora: int = 0,
self_wind: Optional[Wind] = None, round_wind: Optional[Wind] = None,
extra_yaku: Optional[Set[Yaku]] = None
extra_yaku: Optional[Set[Yaku]] = None,
options: Optional[HoraOptions] = None
) -> Hora:
"""
和牌分析(根据向听分析结果)
Expand All @@ -65,15 +76,21 @@ def build_hora_from_shanten_result(
:param extra_yaku: 额外役
:return: 和牌分析结果
"""
result = bridge_mahjongutils.call("hora", {
args = {
"shantenResult": shanten_result.__encode__(),
"agari": str(agari),
"tsumo": tsumo,
"dora": dora,
"selfWind": pascalcase(self_wind.name) if self_wind is not None else None,
"roundWind": pascalcase(round_wind.name) if round_wind is not None else None,
"extraYaku": [pascalcase(yk.name) for yk in extra_yaku] if extra_yaku is not None else []
})
}
if self_wind is not None:
args["selfWind"] = pascalcase(self_wind.name)
if round_wind is not None:
args["roundWind"] = pascalcase(round_wind.name)
if extra_yaku is not None:
args["extraYaku"] = [pascalcase(yk.name) for yk in extra_yaku]
if options is not None:
args["options"] = options.__encode__()
result = bridge_mahjongutils.call("hora", args)

return Hora.__decode__(result)

Expand Down
48 changes: 42 additions & 6 deletions mahjong_utils/hora/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from pydantic import BaseModel
from pydantic import Field
from pydantic.dataclasses import dataclass
from stringcase import pascalcase, snakecase

from mahjong_utils.models.hand_pattern import RegularHandPattern, HandPattern, _BaseRegularHandPattern, \
Expand All @@ -15,10 +16,48 @@
from mahjong_utils.yaku import Yaku, get_yaku


@dataclass(frozen=True)
class HoraOptions:
aotenjou: bool = False
"""是否为青天井规则"""
allow_kuitan: bool = True
"""是否允许食断"""
has_renpuu_jyantou_hu: bool = True
"""连风雀头是否记4符(true则记4符,false则记2符)"""
has_kiriage_mangan: bool = False
"""是否有切上满贯"""
has_kazoe_yakuman: bool = True
"""是否有累计役满"""
has_multiple_yakuman: bool = True
"""是否有多倍役满"""
has_complex_yakuman: bool = True
"""是否有复合役满"""

def __encode__(self) -> dict:
return dict(aotenjou=self.aotenjou,
allowKuitan=self.allow_kuitan,
hasRenpuuJyantouHu=self.has_renpuu_jyantou_hu,
hasKiriageMangan=self.has_kiriage_mangan,
hasKazoeYakuman=self.has_kazoe_yakuman,
hasMultipleYakuman=self.has_multiple_yakuman,
hasComplexYakuman=self.has_complex_yakuman)

@classmethod
def __decode__(cls, data: dict) -> "HoraOptions":
return HoraOptions(
aotenjou=data["aotenjou"],
allow_kuitan=data["allowKuitan"],
has_renpuu_jyantou_hu=data["hasRenpuuJyantouHu"],
has_kiriage_mangan=data["hasKiriageMangan"],
has_kazoe_yakuman=data["hasKazoeYakuman"],
has_multiple_yakuman=data["hasMultipleYakuman"],
has_complex_yakuman=data["hasComplexYakuman"],
)


class HoraHandPattern(HandPattern, ABC):
agari: Tile
tsumo: bool
hu: int
self_wind: Optional[Wind]
round_wind: Optional[Wind]

Expand Down Expand Up @@ -61,7 +100,6 @@ def __decode__(cls, data: dict) -> "RegularHoraHandPattern":
self_wind=Wind[snakecase(data["selfWind"])] if data["selfWind"] is not None else None,
round_wind=Wind[snakecase(data["roundWind"])] if data["roundWind"] is not None else None,
agari_tatsu=Tatsu.__decode__(data["agariTatsu"]) if data["agariTatsu"] is not None else None,
hu=data["hu"],
**RegularHandPattern.__decode__(data["pattern"]).dict()
)

Expand Down Expand Up @@ -125,6 +163,7 @@ def __decode__(cls, data: dict) -> "KokushiHoraHandPattern":
class Hora(BaseModel):
pattern: HoraHandPattern
han: int
hu: int
dora: int
yaku: Set[Yaku]
extra_yaku: Set[Yaku]
Expand All @@ -137,6 +176,7 @@ def __decode__(cls, data: dict) -> "Hora":
return Hora(
pattern=HoraHandPattern.__decode__(data["pattern"]),
han=data["han"],
hu=data["hu"],
dora=data["dora"],
yaku=set(get_yaku(snakecase(yk)) for yk in data["yaku"]),
extra_yaku=set(get_yaku(snakecase(yk)) for yk in data["extraYaku"]),
Expand All @@ -145,10 +185,6 @@ def __decode__(cls, data: dict) -> "Hora":
child_point=ChildPoint.__decode__(data["childPoint"]),
)

@property
def hu(self) -> int:
return self.pattern.hu

@property
def tsumo(self) -> bool:
return self.pattern.tsumo
Expand Down
25 changes: 25 additions & 0 deletions mahjong_utils/point_by_han_hu/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
from typing import NamedTuple

from pydantic.dataclasses import dataclass


@dataclass(frozen=True)
class HanHuOptions:
aotenjou: bool = False
"""是否为青天井规则"""
has_kiriage_mangan: bool = False
"""是否有切上满贯"""
has_kazoe_yakuman: bool = True
"""是否有累计役满"""

def __encode__(self) -> dict:
return dict(aotenjou=self.aotenjou,
hasKiriageMangan=self.has_kiriage_mangan,
hasKazoeYakuman=self.has_kazoe_yakuman)

@classmethod
def __decode__(cls, data: dict) -> "HanHuOptions":
return HanHuOptions(
aotenjou=data["aotenjou"],
has_kiriage_mangan=data["hasKiriageMangan"],
has_kazoe_yakuman=data["hasKazoeYakuman"],
)


class ParentPoint(NamedTuple):
ron: int
Expand Down
23 changes: 16 additions & 7 deletions mahjong_utils/point_by_han_hu/point_by_han_hu.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,44 @@
from .models import ParentPoint, ChildPoint
from typing import Optional

from .models import ParentPoint, ChildPoint, HanHuOptions
from ..bridge import bridge_mahjongutils


def get_parent_point_by_han_hu(han: int, hu: int) -> ParentPoint:
def get_parent_point_by_han_hu(han: int, hu: int, options: Optional[HanHuOptions] = None) -> ParentPoint:
"""
获取亲家X番Y符的点数
:param han: 番
:param hu: 符
:param options: 计算点数时应用的选项
:return: (荣和点数, 自摸各家点数)
"""
result = bridge_mahjongutils.call("getParentPointByHanHu", {
args = {
"han": han,
"hu": hu
})
}
if options is not None:
args["options"] = options.__encode__()
result = bridge_mahjongutils.call("getParentPointByHanHu", args)

return ParentPoint.__decode__(result)


def get_child_point_by_han_hu(han: int, hu: int) -> ChildPoint:
def get_child_point_by_han_hu(han: int, hu: int, options: Optional[HanHuOptions] = None) -> ChildPoint:
"""
获取子家X番Y符的点数
:param han: 番
:param hu: 符
:return: (荣和点数, 自摸庄家点数, 自摸闲家点数)
"""
result = bridge_mahjongutils.call("getChildPointByHanHu", {
args = {
"han": han,
"hu": hu
})
}
if options is not None:
args["options"] = options.__encode__()
result = bridge_mahjongutils.call("getChildPointByHanHu", args)

return ChildPoint.__decode__(result)

Expand Down
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def get_kt_build_dir(self, build_info):
subproject = build_info.get("subproject", None)
if subproject is not None:
build_dir = build_dir / subproject
build_dir = build_dir / "build" / "bin" / "native" / "releaseShared"
build_dir = build_dir / "build" / "bin" / "currentOs" / "releaseShared"
return build_dir

def build_sharedlib(self):
Expand All @@ -70,7 +70,7 @@ def build_sharedlib(self):
subproject = build_info.get("subproject", None)
if subproject is not None:
task += f":{subproject}:"
task += "linkReleaseSharedNative"
task += "linkReleaseSharedForCurrentOs"

run_gradle_task(root, task)

Expand Down Expand Up @@ -120,7 +120,7 @@ def run(self):

setup(
name="mahjong-utils",
version="0.6.1",
version="0.6.6",
author="ssttkkl",
author_email="[email protected]",
license="MIT",
Expand Down
6 changes: 5 additions & 1 deletion tests/test_han_hu.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest

from mahjong_utils.point_by_han_hu import get_parent_point_by_han_hu, get_child_point_by_han_hu
from mahjong_utils.point_by_han_hu import get_parent_point_by_han_hu, get_child_point_by_han_hu, HanHuOptions


def test_get_parent_point_by_han_hu():
Expand All @@ -18,6 +18,8 @@ def test_get_parent_point_by_han_hu():
with pytest.raises(ValueError):
get_parent_point_by_han_hu(114, 514)

assert get_parent_point_by_han_hu(4, 30, HanHuOptions(has_kiriage_mangan=True)) == (12000, 4000)


def test_get_child_point_by_han_hu():
assert get_child_point_by_han_hu(2, 30) == (2000, 1000, 500)
Expand All @@ -33,3 +35,5 @@ def test_get_child_point_by_han_hu():

with pytest.raises(ValueError):
get_child_point_by_han_hu(114, 514)

assert get_child_point_by_han_hu(4, 30, HanHuOptions(has_kiriage_mangan=True)) == (8000, 4000, 2000)
Loading

0 comments on commit b5e2591

Please sign in to comment.