NEW: Source Code - Help out with translating this to new languages!
Issue Tracker - You can also vote on what features you'd like to see.
You can also see a video of a strong player talking through his thoughts at this link.

This is a tile efficiency trainer for Japanese (Riichi) Mahjong. It could work for some other forms of Mahjong, but won't recognize any yaku/fan that aren't in Japanese Mahjong, so it will be somewhat inaccurate.

For every possible discard, the trainer will check how many tiles the resulting hand could draw to improve its shanten (distance from ready). If you discard a tile that isn't the best option, it will tell you the difference in efficiency. The drill completes when the hand reaches ready.

Note that playing simply for efficiency is not the optimal way to play Mahjong. It can make you easier to read. Defense is much more important. Going for high value hands often requires going against efficiency. There are many articles online that can elaborate on this. But, knowing how much efficiency you're giving up can help you better assess whether it's worth going for. This reddit comment has more info.


  • Tiles Allowed - This lets you remove certain suits from the wall.  The less suits, the less obvious the correct discard will generally be.
  • Three player rules - This removes the 2 through 8 of characters from the wall and prevents you from having the North wind as your seat wind, as if you were playing three player.
  • Red Fives - This adds the provided number of red fives to the wall. They are added in the order dots -> characters -> bamboo. If you have a suit removed, the red fives in that suit will also be removed and not be replaced, so having red fives set to 3 while having bamboo disabled will result in 2 red fives.
  • Verbose tile names - If enabled, tiles will be displayed in text as "(number) of (suit)", like "one of bamboo". If disabled, they will be written in shorthand, "(number)(character representing suit)", like "1s". "m" is for characters (manzu), "s" is for bamboo (souzu), and "p" is for circles (pinzu).
  • Concise history - Strips down the history output to something like "Discard: 1p (36 tiles). Best: 9m, with 38 tiles. Draw: 5s." Less clear for new players, but is easier to skim.
  • Show what the best option was - If enabled, the Hand History will name what the optimal tile was. As this will usually still be the optimal tile on the next draw, it can make the drill easier, if more informative.
  • Shuffle discarded tiles back into the wall after starting a new hand - If disabled, your hand will be added to the discard pile when generating a new one. The new hand will come from the tiles remaining in the wall. This can make the exercise harder, as there's more information to consider.
  • Simulate other players discarding tiles - If enabled, every time you discard a tile, three more tiles will be discarded from the wall. This gives more information to consider. Note that the ghost players don't have hands.
  • Consider exception hands - Allows the shanten calculation to consider Kokushi and Chiitoitsu. Chiitoitsu is a special hand made up of seven pairs, and Kokushi is a special hand made up of one of each terminal and honor with a pair of any. These hands tend to be slow to build so this option lets you ignore them without getting told you're being inefficient.
  • Sort hand - Whether to display the hand sorted. Uncheck this to practice reading unsorted hands.

Loading A Hand

To load a hand, enter a text representation of the hand. Enter all the values of the tiles in a suit, then a letter representing the suit, and repeat for all suits.

  • For Character tiles, use the letter "m" for man, "w" for wan, or "c" for characters/cracks.
  • For Bamboo tiles, use the letter "s" for sou, or "b" for bamboo.
  • For Circle tiles, use the letter "p" for pin.
  • For Honor tiles, use "z" or "h" for honors.
  • The Honor tiles are ordered, from 1 to 7, East, South, West, North, White, Green, Red.
  • Red fives are represented by a 0. A 0 in the Honor suit is invalid.
  • To specify the drawn tile or dora indicator, enter a number between 0 and 37, where 0~9 are characters, 10~19 are circles, 20~29 are bamboo, and 31~37 are the honors.
  • Follow this number with "t" for the drawn tile (tsumo).
  • Follow this number with "d" for the dora indicator.
  • To specify the round and seat winds, enter a number between 1 and 4, followed by "j" for the seat wind (jikaze), or by "r" or "b" for the round wind (bakaze).

For example, 340m778s236677p55z. The order of the suits doesn't matter, and you can have as few or as many as you want. Any invalid characters will be ignored, so a string like "345 man 778 sou 236677 pin 55 honor" would also (coincidentally) work, as all the extra letters don't represent suits. If you provide a hand with fewer than 14 tiles, tiles will be added at random to fill it. A hand with more than 14 tiles will result in only the last 14 tiles appearing. A hand with more than 4 of a tile will only have 4 of that tile.

See Also

Release date Feb 08, 2019
Rated 4.8 out of 5 stars
(20 total ratings)
TagsBoard Game, drills, japanese, mahjong, trainer
Code licenseGNU General Public License v3.0 (GPL)
Asset licenseCreative Commons Attribution v4.0 International
Average sessionA few minutes
LanguagesEnglish, French, Korean, Polish, Russian, Chinese, Chinese (Simplified)
InputsMouse, Touchscreen, Smartphone
AccessibilityOne button
LinksSource code, Twitter

Development log

View all posts


Log in with to leave a comment.

What about fu minipoints trainer? Calculate how much you have. Still have problems with them.

In the Defense Trainer, I've had a couple of times where I've discarded a tile that I thought was suji (e.g. 6s when the riichiing opponent had already discarded both the 3s and 9s) but wasn't, as well as a couple of times where I didn't discard a tile that I thought wasn't suji (e.g. 1m when nobody had discarded the 4m), but which I should have because they were. Am I misunderstanding suji, or is this a bug? If it's the former, is there documentation on what counts as suji and what doesn't?

I had a similar problem, but eventually figured out what I was missing.

For the former case, I assume either the 3s or the 9s was the riichi tile. Generally speaking, suji information from the riichi tile is considered less valuable; for the purposes of this trainer, the riichi tile should be ignored when determining suji by the standard "three away" method.

For the latter case, there was probably a wall on 2m or 3m. If you can see all four 2m or all four 3m, the attacking player is obviously not holding 23m; so 1m can be considered suji.

I see. Also, what's "one-shot" here?

I think one-chance is when there's three copies of a tile out or in your hand leaving only one possible for an opponent to have. So if you have a 1 and you see three 2s out, you know the chances are way slimmer they have the 2 and you'd throw the 1 hoping for the best.

That said, looking at the code, it doesn't look like detecting this is currently hooked up.

Thanks for this, it's really great. Silly question, but how do I get to the defense trainer?


There are buttons along the top of the screen to get to the other pages. "Folding" will take you to the defense trainer.

thanks so much!

Really great stuff, I'm learning a lot from your trainer, as a beginner Mahjong player. Thanks a bunch! Discovered you through DdRMaSTeRDan's YT channel.