Files
henan-backend/mahjong-py/mahjong/models.py
T
2026-09-22 15:39:53 +08:00

59 lines
2.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""麻将胡了 · 数据模型(frozen dataclass,母本 olympus/models.py 同风格)。"""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Dict, List, Optional, Tuple
@dataclass(frozen=True)
class Win:
"""一笔奖 = 某符号的一条前缀链。"""
symbol: str
run: int # 链长 3/4/5(从第 1 轴起连续的轴数)
counts: Tuple[int, ...] # 链内各轴的格数(百搭计入)
ways: int # counts 的乘积
loc: Tuple[int, ...] # 本笔涉及的全部格位(1 基,含金色格与百搭)
pay_base: float # 赔付表[符号][链长] × ways,单位 = 倍投注总额
@dataclass(frozen=True)
class Rotation:
"""一波 = 一次消除结算。"""
seq: int # 本旋内第几波(= 阶梯序号)
rotation_mul: int # 本波阶梯倍率
wins: Tuple[Win, ...]
base_mul: float # Σ pay_base
win_mul: float # base_mul × rotation_mul
converted: Tuple[Tuple[int, str], ...] # (格位1基, 原自然符号):金色就地转百搭
drops: Tuple[Tuple[int, int], ...] # (from1基, to1基)
fills: Tuple[Tuple[int, str], ...] # (格位1基, 新符号)
grid: Tuple[Optional[str], ...] # 本波结算+补位后的盘面(20 格短码)
@dataclass(frozen=True)
class Spin:
"""一旋。"""
index: int # 0 = 基础旋(触发盘),>0 = 第 N 次免费旋转
is_fs: bool
rotations: Tuple[Rotation, ...]
mul: float # 本旋倍率
scatters: int # 本旋**落定盘面**上的胡数(补位产生的不算触发)
fs_awarded: int = 0 # 本旋触发的赠送旋数(0 = 没触发)
retrigger: bool = False
@dataclass
class Round:
"""一局 = 基础旋 + 免费旋转(可重触发),受 500x 封顶。"""
box_id: int
spins: List[Spin] = field(default_factory=list)
raw_mul: float = 0.0 # 封顶前的总倍率
actual_mul: float = 0.0 # min(raw_mul, 500) —— 落桶/发奖用这个
capped: bool = False
near_miss: bool = False # 基础旋恰好 2 个胡且第 5 轴无胡
free_spins: int = 0 # 本局发放的免费旋数
@property
def has_fs(self) -> bool:
return self.free_spins > 0