Current section
Files
Jump to
Current section
Files
README.md
# ritchie
[](https://hex.pm/packages/ritchie)
[](https://ritchie.hexdocs.pm/)
A complete **R**iichi **M**ahjong representation in Gleam. Heavily inspired by [`summivox`'s Rust riichi library](https://github.com/summivox/riichi-rs). Notable _differences_ include:
- The hand decomposition parser is entirely hand-rolled, it doesn't use lookup tables (that would be weird and hard with Gleam's restrictions)
- A separate `game` module is provided that tracks state across game rounds
- Possible actions/reactions can be listed at any point during the game, which makes it significantly easier to build upon
(the logic is already there, after all)
```sh
gleam add ritchie
```
```gleam
import ritchie/game
import ritchie/elements/tile
import ritchie/elements/wall
import ritchie/model/action
import ritchie/model/discard
pub fn main() -> Nil {
// Initialize a new game with standard rules, starting at 25000 points per player.
let g = game.new_default()
// Start a new round with a given wall (a full sorted wall, in our case)
let assert Ok(g) = game.start_round(g, wall.make_sorted_wall(#(1, 1, 1)))
// Reflect on `game.current_state` (which has the current draw, hands, melds, discards, and so on),
// and then construct an `action` from the player whose turn it is.
let ac = action.ActionDiscard(discard.Discard(
tile: tile.t("3m"), // for example
called_by: 2,
declares_riichi: False,
is_tsumogiri: True,
))
// Register the action with the game. The game checks if the action is valid, and caches it to be
// applied the next time you call `game.step`.
let assert Ok(g) = game.register_action(g, ac)
// Now, you could also construct a reaction (see `ritchie/model/reaction`), or even multiple, and
// apply them in the same way using `game.register_reaction`. When you are done...
// Process the next game step (action + reaction(s)), to produce the next state.
case game.step(g) {
Ok(game.GameStepOutcome(g, step, None)) -> {
// Congrats, the next turn has started!
}
Ok(game.GameStepOutcome(g, step, Some(_))) -> {
// Oh, the round has ended! This could potentially also
// mean that the game is over.
}
}
}
```
Further documentation can be found at <https://ritchie.hexdocs.pm/>.
## Todo
Major and minor things that need doing:
- [ ] Shuffle wall. `game.start_round` currently expects a pre-shuffled wall
- [ ] More types should be opaque, especially the ones that the player uses.
There should instead be constructors for most things
- [ ] Player bankruptcy should be handled
- [ ] Renhou is not detected
- [ ] Probably JSON serialization
- [ ] Properly implement `yaku_extra` and `yaku_block` in the ruleset
## License
Licensed under the LGPL-3.0.