### Setup Rust Environment Source: https://github.com/smly/riichienv/blob/main/docs/DEVELOPMENT_GUIDE.md Downloads and installs the Rust toolchain using rustup. ```bash curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh ``` -------------------------------- ### Start UI Development Server Source: https://github.com/smly/riichienv/blob/main/docs/DEVELOPMENT_GUIDE.md Start a local development server with hot-reloading for UI development. ```bash cd riichienv-ui npm run dev ``` -------------------------------- ### Install Development Dependencies Source: https://github.com/smly/riichienv/blob/main/docs/DEVELOPMENT_GUIDE.md Installs development dependencies using uv. ```bash uv sync --dev ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/smly/riichienv/blob/main/riichienv-ui/DEVELOPMENT_GUIDE.md Navigate to the project directory and install Node.js dependencies using npm. ```bash cd riichienv-ui npm install ``` -------------------------------- ### Start Development Server Source: https://github.com/smly/riichienv/blob/main/riichienv-ui/DEVELOPMENT_GUIDE.md Run a local development server with hot-reloading for rapid development. ```bash npm run dev ``` -------------------------------- ### Install UI Dependencies and Build Source: https://github.com/smly/riichienv/blob/main/docs/DEVELOPMENT_GUIDE.md Install Node.js dependencies and build the UI project. This runs the full build pipeline. ```bash cd riichienv-ui npm install npm run build ``` -------------------------------- ### Train PPO Algorithm Source: https://github.com/smly/riichienv/blob/main/riichienv-ml/README.md Starts training using the PPO algorithm with a specified configuration file. ```sh uv run python scripts/train_ppo.py -c src/riichienv_ml/configs/4p/ppo.yml ``` -------------------------------- ### Install RiichiEnv from source with Rust Source: https://github.com/smly/riichienv/blob/main/README.md If building from source, ensure you have the Rust toolchain installed. This command synchronizes development dependencies and builds the Rust core. ```bash uv sync --dev uv run maturin develop --release ``` -------------------------------- ### Train BC with PPO Source: https://github.com/smly/riichienv/blob/main/riichienv-ml/README.md Starts training using BC with PPO, using a specified configuration file. Requires an online teacher, which is not included in the repository. ```sh uv run python scripts/train_ppo.py -c src/riichienv_ml/configs/4p/bc_ppo.yml ``` -------------------------------- ### Train CQL Algorithm Source: https://github.com/smly/riichienv/blob/main/riichienv-ml/README.md Starts training using the CQL algorithm with a specified configuration file. ```sh uv run python scripts/train_cql.py -c src/riichienv_ml/configs/4p/cql.yml ``` -------------------------------- ### Train Grouping Algorithm Source: https://github.com/smly/riichienv/blob/main/riichienv-ml/README.md Starts training using the Grouping algorithm with a specified configuration file. ```sh uv run python scripts/train_grp.py -c src/riichienv_ml/configs/4p/grp.yml ``` -------------------------------- ### Train BC Model Source: https://github.com/smly/riichienv/blob/main/riichienv-ml/README.md Starts training a BC model with a specified configuration file. Requires an online teacher, which is not included in the repository. ```sh uv run python scripts/train_bc.py -c src/riichienv_ml/configs/4p/bc_model.yml ``` -------------------------------- ### Commit Message Examples Source: https://github.com/smly/riichienv/blob/main/docs/DEVELOPMENT_GUIDE.md Examples of commit messages following the Conventional Commits format. ```text feat(env): add Kyoku.events serialization fix(score): correct ura dora calculation docs(readme): update installation instructions ``` -------------------------------- ### Build Python Extension Source: https://github.com/smly/riichienv/blob/main/docs/DEVELOPMENT_GUIDE.md Builds and installs the Python extension into the virtual environment using maturin. ```bash uv run maturin develop ``` -------------------------------- ### Install RiichiEnv using uv or pip Source: https://github.com/smly/riichienv/blob/main/README.md Install the RiichiEnv package using either the uv or pip package manager. This is the primary method for adding the library to your project. ```bash uv add riichienv # Or pip install riichienv ``` -------------------------------- ### Get Game Summary Source: https://github.com/smly/riichienv/blob/main/riichienv-ui/demos/README.md Retrieve a list of dictionaries, each summarizing a round (kyoku) of the game. ```python >>> viewer.summary() [ {'round_idx': 0, 'bakaze': 'E', 'kyoku': 1, 'honba': 0, 'oya': 0, 'scores': [25000, 25000, 25000, 25000]}, {'round_idx': 1, 'bakaze': 'E', 'kyoku': 2, 'honba': 0, 'oya': 1, 'scores': [33000, 25000, 17000, 25000]}, ... ] ``` -------------------------------- ### Build Optimized Python Extension Source: https://github.com/smly/riichienv/blob/main/docs/DEVELOPMENT_GUIDE.md Builds and installs an optimized release version of the Python extension using maturin. ```bash uv run maturin develop --release ``` -------------------------------- ### Observe Discard Event for Player Actions (Pon/Ron) Source: https://github.com/smly/riichienv/blob/main/README.md This example demonstrates how `observe_event` can detect if a player has legal actions (like 'pon' or 'ron') after an opponent's discard. The observation will be non-`None` if the player can react to the discard. ```python # 4P example: P1 can pon after P0's discard env = RiichiEnv(game_mode="default") env.observe_event({"type": "start_game"}, player_id=1) env.observe_event({"type": "start_kyoku", ...}, player_id=1) env.observe_event({"type": "tsumo", "actor": 0, "pai": "?"}, player_id=1) obs = env.observe_event( {"type": "dahai", "actor": 0, "pai": "5m", "tsumogiri": True}, player_id=1, ) # obs is not None if player 1 can pon/ron the discarded tile if obs is not None: for a in obs.legal_actions(): print(a.to_mjai()) # e.g. pon, pass ``` -------------------------------- ### Control Game Visualization Display Source: https://github.com/smly/riichienv/blob/main/README.md Shows how to display a specific step of the game or change the camera perspective in the 3D viewer. Also shows how to get round summary and results. ```python viewer = env.get_viewer() viewer.show(step=100, perspective=0) # show() accepts optional display parameters viewer.summary() # list of round info dicts (bakaze, kyoku, honba, oya, scores) viewer.get_results(0) # list[WinResult] for round 0 ``` -------------------------------- ### Reset Environment and Get Initial Observations Source: https://github.com/smly/riichienv/blob/main/README.md Resets the RiichiEnv environment to its initial state and retrieves the observations for all active players. The output shows the structure of the observation dictionary. ```python from riichienv import RiichiEnv env = RiichiEnv() obs_dict = env.reset() print(obs_dict) ``` -------------------------------- ### Get Legal Actions for a Player Source: https://github.com/smly/riichienv/blob/main/README.md Retrieves a list of all valid actions a player can take in the current game state. Actions are represented by an `Action` object. ```python obs.legal_actions() ``` -------------------------------- ### Simulate a Mahjong Game Turn in Rust Source: https://github.com/smly/riichienv/blob/main/riichienv-core/README.md Initializes a game state with Tenhou rules, gets the current player's observation and legal actions, and advances the game state by one step. Requires `riichienv_core::state::GameState` and `riichienv_core::rule::GameRule`. ```rust use riichienv_core::state::GameState; use riichienv_core::rule::GameRule; use std::collections::HashMap; // Create a new game with Tenhou rules // GameState::new(game_mode, skip_mjai_logging, seed, round_wind, rule) let rule = GameRule::default_tenhou(); let mut state = GameState::new(0, true, None, 0, rule); // Get observation for the current player let obs = state.get_observation(0); let legal_actions = obs.legal_actions_method(); // Advance the game state (actions is a HashMap) let mut actions = HashMap::new(); actions.insert(0, legal_actions[0].clone()); state.step(&actions); ``` -------------------------------- ### Apply MJAI Event and Get Observation Source: https://github.com/smly/riichienv/blob/main/README.md Use `observe_event` for online inference, feeding events one at a time and acting when a non-`None` observation is returned. This method handles the complexity of determining when a player needs to act, including reaction phases. ```python env = RiichiEnv(game_mode="3p-red-half") my_seat = 0 for event in mjai_events: obs = env.observe_event(event, my_seat) if obs is not None: # This player needs to act action = select_action(obs) # your model logic ... ``` -------------------------------- ### Get New MJAI Events for a Player Source: https://github.com/smly/riichienv/blob/main/README.md Retrieves a list of new MJAI JSON events for a specific player since their last observation. This can include game start, round start, and tile draws. ```python obs = obs_dict[0] obs.new_events() ``` -------------------------------- ### Switch Branch and Run Benchmark Source: https://github.com/smly/riichienv/blob/main/docs/DEVELOPMENT_GUIDE.md Checkout a feature branch and run benchmarks against a baseline. ```bash git checkout feature-branch cargo bench --bench agari_bench -- --baseline main ``` -------------------------------- ### Initialize RiichiViewer (Recommended API) Source: https://github.com/smly/riichienv/blob/main/riichienv-ui/README.md Mount the RiichiViewer to a container element and configure its behavior. The viewer emits events for various game state changes. ```typescript import { RiichiViewer } from 'riichienv-ui'; const viewer = RiichiViewer.mount('container-id', { log: events, // MjaiEvent[] renderer: '3d', // '2d' or '3d' (default: '3d') perspective: 0, // player viewpoint (0-3) freeze: false, // disable controls initialPosition: { kyoku: 0 }, }); viewer.on('positionChange', ({ kyokuIndex, step }) => { ... }); viewer.on('kyokuChange', ({ kyokuIndex, round, honba }) => { ... }); viewer.on('viewpointChange', ({ viewpoint }) => { ... }); viewer.destroy(); ``` -------------------------------- ### Initialize and Run a Game with Random Agent Source: https://github.com/smly/riichienv/blob/main/README.md Demonstrates initializing the RiichiEnv environment and using a RandomAgent to play through a game. The environment resets, and the agent selects actions until the game is done. Finally, it prints the scores and ranks. ```python from riichienv import RiichiEnv from riichienv.agents import RandomAgent agent = RandomAgent() env = RiichiEnv() obs_dict = env.reset() while not env.done(): actions = {player_id: agent.act(obs) for player_id, obs in obs_dict.items()} obs_dict = env.step(actions) scores, ranks = env.scores(), env.ranks() print(scores, ranks) ``` -------------------------------- ### Initialize and Run a Mahjong Game with Random Agent Source: https://github.com/smly/riichienv/blob/main/README.md Initializes a RiichiEnv environment and a RandomAgent, then runs a game until completion. The game state is observed at each step. ```python from riichienv import RiichiEnv from riichienv.agents import RandomAgent agent = RandomAgent() env = RiichiEnv(game_mode="4p-red-half") obs_dict = env.reset() while not env.done(): actions = {pid: agent.act(obs) for pid, obs in obs_dict.items()} obs_dict = env.step(actions) env.get_viewer().show() # displays the 3D viewer in Jupyter ``` -------------------------------- ### Direct Constructors (via script tag) Source: https://github.com/smly/riichienv/blob/main/riichienv-ui/README.md When the viewer is loaded via a script tag, several global constructors are exposed on the `window` object, allowing direct instantiation of 2D, 3D, and live viewers. ```APIDOC ## Direct Constructors (via script tag) ### Description When `dist/viewer.js` is included directly in an HTML file via a `