游戏源码
点击放大



<di="center">
<img src=" width="35%">
<br />
Accelerating Reproducible 麻将 Research
![CI]()
![Open In Colab]()
![Kaggle]()
![PyPI - ]()
![crates.io]()
!License
</div>
-----
* High Performance: Core logic implemented in Rust for lightning-fast state transitions and rollouts.
* Gym-style API: Intuiti designed specifically for reinforcement learning.
* Mortal Compatibility: Seamlessly interface with the Mortal Bot using the MJAI 协议.
* Rule Flexibility: Support for diverse rule sets, including three-player 麻将 (sanma).
* Game : Integrated replay for Jupyter Notebooks.
<di="center">
<img src=" width="42%"> <img src=" width="38%">
</div>
Currently, building from 源码 requires the Rust toolchain.
en() initializes the 游戏 state and returns the initial obser. The returned obs_dict maps each acti ID to their respective Obser object.
Use env.done() to check if the game has concluded.
By default, the en runs a single round (kyoku). For 游戏 rules supporting sudden death or standard match formats like East-only or Half-round, the en continues until the 游戏-end conditions are met.
The Obser object provides all relevant information to a player, including the current 游戏 state and a legal actions.
obs.new_events() -> list[str] returns a list of MJAI JSON events that are new for that player since their previous obser. On a player's first obser in a hand, this can include start_game, start_kyoku, and earlier events from the hand. The full history for that obser window is accessible via obs.events.
obs.legal_actions() -> list[Action] provides the list of all valid moves the player can make.
If your agent communicates via the MJAI 协议, you can easily map an MJAI response to a valid Action object using obs.select_action_from_mjai().
RiichiEnv is fully compatible with the Mortal MJAI bot processing flow. I ha that MortalAgent can execute matches without errors in over 1,000,000+ hanchan games on RiichiEnv.
RiichiEn high-level 游戏 flow configuration (Mode) from detailed 游戏 mechanics (Rules).
* Game Mode (game_mode): Configuration for 游戏 length (e.g., East-only, Hanchan), player count, and termination conditions (e.g., Tobi/bust, sudden death).
* Game Rules (rule): Configuration for specific 游戏 mechanics (e.g., handling of Chankan (Robbing the Kan) for Kokushi Musou, Kuitan a, etc.).
#### 1. Game Mode Presets (game_mode)
You can select a standard 游戏 mode using the game_mode argument in the constructor. This configures the basic flow of the 游戏.
| game_mode | Players | Mode | Mechanics |
|---|---|---|---|
| 4p-red-single | 4 | Single Round | No sudden death |
| 4p-red-east | 4 | East-only (東風; Tonpuu) | Standard (Tenhou rule) |
| 4p-red-half | 4 | Hanchan (半荘) | Standard (Tenhou rule) |
| 3p-red-single | 3 | Single Round | No sudden death |
| 3p-red-east | 3 | East-only (東風; Tonpuu) | Standard (Tenhou sanma rule) |
| 3p-red-half | 3 | Hanchan (半荘) | Standard (Tenhou sanma rule) |
#### 2. Customizing Game Rules (GameRule)
For detailed rule customization, you can pass a GameRule object to the RiichiEnv constructor. RiichiEn presets for popular platforms (Tenhou, MJSoul) and allows granular configuration.
Detailed mechanic flags (like allows_ron_on_ankan_for_kokushi_musou) are defined in the GameRule struct. See RULES.md for a full list of configurable options.
Standardize between tile formats (136-tile, MPSZ, MJAI) and easily parse hand strings.
See DATA_REPRESENTATION.md for more details.
HandE e a hand for tenpai status, waiting tiles, and winning results. Create an instance with HandE(tiles, melds) or HandE.hand_from_text(text).
* is_tenpai() — returns whether the hand is in tenpai.
* get_waits() — returns the list of winning tile IDs (34-tile format, 0–33).
* calc(win_tile, dora_indicators, ura_indicators, conditions) — e the hand with the gi tile and returns a WinResult.
The yaku field contains raw yaku IDs. Use yaku_list() to get detailed Yaku objects with Japanese/English names and platform-specific IDs.
Calculate the shanten number (minimum number of tiles away from tenpai) using lookup tables based on Cryolite/nyanten. Both 4-player and 3-player 麻将 are supported.
4-player mahjong:
3-player mahjong:
In 3-player 麻将 (sanma), tiles 2m-8m do not exist. calculate_shanten_3p correctly handles this by treating manzu tiles (1m, 9m) as honor-like tiles with no sequence potential, using the nyanten lookup tables.
Game renders an interactive 3D replay in Jupyter Notebooks. Use en() to create a from a RiichiEnv instance, or Game.from_jsonl() / Game.from_list() to load from files or event lists.
The returned Game object also provides methods for programmatic inspection:
See demos/README.md for full API details and notebook examples.
RiichiEn two methods for applying MJAI events, designed for different use cases:
| Method | Signature | Returns | Use case |
|---|---|---|---|
| apply_event | apply_event(event) | None | Replay parsing, training data generation |
| obser | obser(event, player_id) | Obser \| None | Online inference (bot play) |
Why two methods? apply_event is minimal — it only updates state, leaving obser timing to the caller. This is ideal for batch replay where all events are pre-determined. obser combines state update with obser retrieval in a single call, and encapsulates the logic of which events can produce legal actions. This avoids the caller having to manually skip non-action events (start_game, dora, hora, etc.) and separately call get_obser().
#### apply_event(event) — State update only
Applies an MJAI event dict to advance the 游戏 state. Obser must be retrie via get_obser(player_id). This is the right choice when replaying full 游戏 logs for training data generation, where all events are already known and obser timing is managed externally (e.g., by KyokuStepIterator).
#### obser(event, player_id) — State update + obser
Applies the event and returns an Obser if player_id has legal actions a. Returns None for events that ne decisions (start_game, start_kyoku, dora, hora, ryukyoku, etc.) and when the tracked player has no actions.
This is the recommended API for online inference — feed events one at a time and act whenever a non-None obser is returned.
The key ad of obser is that it handles all the complexity of determining when a player needs to act — including reaction phases (pon, chi, ron) after an opponent's discard. A simple loop o is sufficient for a fully functional bot:
For more architectural details and contribution guidelines, see CONTRIBUTING.md and DE.md.
Check our Milestones for the future roadmap and de plans.
Apache License 2.0
开发语言:Rust
项目类型:日麻高性能研究环境
Star 数:90
这是一套日麻高性能研究环境,代码结构清晰,适合开发者学习游戏的客户端渲染、服务端逻辑、场景管理与资源加载。项目涵盖了游戏的核心玩法、界面交互、地图与角色系统等模块,对理解游戏开发的完整流程具有较高的参考价值。
从技术实现角度看,游戏项目的难点在于:游戏循环与状态管理、资源加载与渲染优化、客户端与服务端的协议同步、以及多平台适配。本项目在这些方面提供了可运行的实现,开发者可以在此基础上进行二次开发或学习研究。
1. 下载源码压缩包,解压到本地开发环境。
2. 根据项目类型准备对应的运行环境(Node.js / Go / C# / Unity / Godot 等)。
3. 按照 README 中的步骤配置依赖、数据库和配置文件。
4. 先启动服务端,再运行客户端,即可进入游戏进行测试。
注意:本项目仅供学习研究使用,请勿用于商业或非法用途。
对于想进入游戏开发领域的开发者来说,这套源码是一个很好的入门参考。通过阅读代码,可以学习到游戏的核心玩法实现、场景与资源管理、网络协议设计、以及渲染优化等关键技术点。
同时,项目中的代码组织方式和模块划分,也展示了游戏项目在工程化方面的实践经验,值得开发者深入研究和借鉴。理解一个完整游戏项目的架构,对后续开发其他类型游戏也很有帮助。
本资源来源于开源社区,仅供学习研究和技术交流使用,请勿用于任何商业或违法违规用途。使用本项目产生的一切后果由使用者自行承担。若涉及第三方权益,请联系删除。
| 资源标题 | 日麻环境 - 日麻高性能研究环境 |
| 所属分类 | 游戏源码 |
| 发布作者 | admin |
| 发布时间 | 2026-10-05 21:44:56 |
| 下载权限 | 免费下载 |
| 附件数量 | 2 个下载链接 |
| 浏览次数 | 201 |
| 讨论数量 | 0 |
| 主题状态 | 正常讨论中 |