Mortal

GitHub Workflow Status GitHub Workflow Status dependency status GitHub top language Lines of code GitHub code size in bytes license

Donate

Mortal (ňçíňĄź) is a free and open source AI for Japanese mahjong, powered by deep reinforcement learning.

The development of Mortal is hosted on GitHub at https://github.com/Equim-chan/Mortal.

Features

  • A strong mahjong AI that is compatible with Tenhou's standard ranked rule for four-player mahjong.
  • A blazingly fast mahjong emulator written in Rust with a Python interface. Up to 40K hanchans per hour1 can be achieved using the Rust emulator combined with Python neural network inference.
  • An easy-to-use mjai interface.
  • Serve as a backend for mjai-reviewer (previously known as akochan-reviewer).
  • Free and open source.

About this doc

This doc is work in progress, so most pages are empty right now.

Okay cool now give me the weights!

Read this post for details regarding this topic.

License

Code

AGPL-3.0-or-later

Copyright (C) 2021-2022 Equim

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/.

Logo and Other Assets

CC BY-SA 4.0

1

Evaluated on NVIDIA GeForce RTX 4090 with AMD Ryzen 9 7950X, game batch size 2000.

Online Service

Mahjong AI Utilities - Review your game, play with you

Strength

Simulation environment

The simulation uses a 1v3 duplicate mahjong setting as follows

TableEast startSouth startWest startNorth start
1ChallengerChampionChampionChampion
2ChampionChallengerChampionChampion
3ChampionChampionChallengerChampion
4ChampionChampionChampionChallenger

In this setting, every 4 games are initialized with same random seed. The emulator guarantees that with the same (seed, kyoku, honba) tuple, the yama, haipai, dora/ura indicators and rinshan tiles are deterministic and reproducible.

The emulator is implemented in libriichi::arena.

The "rank pt" in all the tables are calculated using a distribution of [90, 45, 0, -135].

The name of the current best model is highlighted.

Mortal vs akochan (jun_pt = [90, 45, 0, -135])

Challenger is akochan and Champion is Mortal.

mortal1-b40c192-t22040618

akochan (x1)mortal1-b40c192-t22040618 (x3)
Games2343270296
Rounds250168750504
Rounds as dealer61330188838
1st (rate)5582 (0.238221)17850 (0.253926)
2nd (rate)5521 (0.235618)17911 (0.254794)
3rd (rate)5894 (0.251536)17538 (0.249488)
4th (rate)6435 (0.274624)16997 (0.241792)
Tobi(rate)1916 (0.081769)4426 (0.062962)
Avg rank2.5625642.479145
Total rank pt-117900117900
Avg rank pt-5.0315811.677194 ­čĹĹ
Total Δscore-2869440028694400
Avg game Δscore-1224.581769408.193923
Avg round Δscore-114.70052138.233507
Win rate0.1959520.213570
Deal-in rate0.1319070.114841
Call rate0.3332080.296321
Riichi rate0.2159230.181443
Ryukyoku rate0.1683350.168335
Avg winning Δscore6747.2838176483.038962
Avg winning Δscore as dealer8812.3317018439.922489
Avg winning Δscore as non-dealer5996.3782025727.687944
Avg riichi winning Δscore8271.6974898079.942256
Avg open winning Δscore4976.7548394976.946811
Avg dama winning Δscore7745.2574536515.832517
Avg ryukyoku Δscore77.555091-25.851697
Avg winning turn11.18288111.129126
Avg riichi winning turn11.24984511.126644
Avg open winning turn11.11743811.086393
Avg dama winning turn11.12040311.264727
Avg deal-in turn11.61726111.485306
Avg deal-in Δscore-5334.579836-5332.635255
Avg deal-in Δscore to dealer-7075.531317-7104.268622
Avg deal-in Δscore to non-dealer-4692.321414-4716.800350
Chasing riichi rate0.1488420.180357
Riichi chased rate0.1823500.175775
Winning rate after riichi0.4474700.485805
Deal-in rate after riichi0.1599130.149147
Avg riichi turn7.9444437.798390
Avg riichi Δscore2916.1837943207.900187
Avg number of calls1.4336001.449355
Winning rate after call0.2671250.317703
Deal-in rate after call0.1453370.131733
Avg call Δscore562.586674907.807905
Dealer wins/all dealer rounds0.2131420.236388
Dealer wins/all wins0.2666610.278498
Deal-in to dealer/all deal-ins0.2694930.257945
Yakuman (rate)21 (0.000083944)112 (0.000149233)
Nagashi mangan (rate)0 (0.000000000)20 (0.000026649)

mortal3-b24c512-t22122709

akochan (x1)mortal3-b24c512-t22122709 (x3)
Games1315239456
Rounds140132420396
Rounds as dealer34602105530
1st (rate)3121 (0.237302)10031 (0.254233)
2nd (rate)3116 (0.236922)10036 (0.254359)
3rd (rate)3243 (0.246578)9909 (0.251141)
4th (rate)3672 (0.279197)9480 (0.240268)
Tobi(rate)1028 (0.078163)2439 (0.061816)
Avg rank2.5676702.477443
Total rank pt-7461074610
Avg rank pt-5.6729011.890967 ­čĹĹ
Total Δscore-1460150014601500
Avg game Δscore-1110.211375370.070458
Avg round Δscore-104.19818534.732728
Win rate0.1953520.212157
Deal-in rate0.1304200.112613
Call rate0.3300750.293685
Riichi rate0.2153040.189110
Ryukyoku rate0.1728010.172801
Avg winning Δscore6807.6164386510.059424
Avg winning Δscore as dealer9027.8347738508.379567
Avg winning Δscore as non-dealer5983.8884165760.331190
Avg riichi winning Δscore8404.1282368146.596125
Avg open winning Δscore4985.0478574842.311007
Avg dama winning Δscore7606.3417896749.915065
Avg ryukyoku Δscore90.192030-30.064010
Avg winning turn11.14385411.182128
Avg riichi winning turn11.24204111.182500
Avg open winning turn11.05549711.142524
Avg dama winning turn10.99599511.320519
Avg deal-in turn11.71432511.457247
Avg deal-in Δscore-5299.611512-5284.607748
Avg deal-in Δscore to dealer-6995.398902-7088.703069
Avg deal-in Δscore to non-dealer-4706.123504-4674.846678
Chasing riichi rate0.1573700.180702
Riichi chased rate0.1832550.179620
Winning rate after riichi0.4455930.485013
Deal-in rate after riichi0.1595570.149470
Avg riichi turn7.9547587.815939
Avg riichi Δscore2979.5300123245.600684
Avg number of calls1.4419081.435309
Winning rate after call0.2687980.319494
Deal-in rate after call0.1452850.124854
Avg call Δscore592.184460914.366131
Dealer wins/all dealer rounds0.2140920.230579
Dealer wins/all wins0.2706120.272822
Deal-in to dealer/all deal-ins0.2592470.252609
Yakuman (rate)16 (0.000114178)49 (0.000116557)
Nagashi mangan (rate)0 (0.000000000)46 (0.000109421)

Mortal vs akochan (jun_pt = [90, 30, -30, -90])

mortal1-b40c192-t22040618

akochan (x1)mortal1-b40c192-t22040618 (x3)
Games2438873164
Rounds259986779958
Rounds as dealer63936196050
1st (rate)6047 (0.247950)18341 (0.250683)
2nd (rate)5887 (0.241389)18501 (0.252870)
3rd (rate)5470 (0.224291)18918 (0.258570)
4th (rate)6984 (0.286370)17404 (0.237877)
Tobi(rate)2058 (0.084386)4580 (0.062599)
Avg rank2.5490822.483639
Total rank pt-133695133695
Avg rank pt-5.4819991.827333 ­čĹĹ
Total Δscore-2408500024085000
Avg game Δscore-987.575857329.191952
Avg round Δscore-92.63960430.879868
Win rate0.1971260.213935
Deal-in rate0.1385310.114030
Call rate0.3312760.296377
Riichi rate0.2255780.180537
Ryukyoku rate0.1661470.166147
Avg winning Δscore6887.4536596442.207240
Avg winning Δscore as dealer9107.6883048355.842889
Avg winning Δscore as non-dealer6097.5291665710.956124
Avg riichi winning Δscore8426.1188848015.720543
Avg open winning Δscore5089.0796114977.606459
Avg dama winning Δscore7552.7495776456.614746
Avg ryukyoku Δscore168.024817-56.008272
Avg winning turn11.22911211.082213
Avg riichi winning turn11.29531611.068438
Avg open winning turn11.17325711.056963
Avg dama winning turn11.04822311.199211
Avg deal-in turn11.61911411.451006
Avg deal-in Δscore-5321.343292-5345.643643
Avg deal-in Δscore to dealer-6970.939034-7139.180226
Avg deal-in Δscore to non-dealer-4706.768293-4734.051536
Chasing riichi rate0.1669990.176882
Riichi chased rate0.1735810.183203
Winning rate after riichi0.4411820.488023
Deal-in rate after riichi0.1593090.150216
Avg riichi turn8.0464477.780905
Avg riichi Δscore2947.6546113181.566071
Avg number of calls1.4444251.453448
Winning rate after call0.2671870.320407
Deal-in rate after call0.1538080.131492
Avg call Δscore564.244662914.957043
Dealer wins/all dealer rounds0.2103510.235312
Dealer wins/all wins0.2624200.276477
Deal-in to dealer/all deal-ins0.2714350.254287
Yakuman (rate)31 (0.000119237)163 (0.000208986)
Nagashi mangan (rate)0 (0.000000000)15 (0.000019232)

Mortal vs Mortal

mortal2-b75c256-t22092920 and mortal1-b40c192-t22040618

mortal2-b75c256-t22092920 (x1)mortal1-b40c192-t22040618 (x3)
Games4260001278000
Rounds456848513705455
Rounds as dealer11305063437979
1st (rate)107160 (0.251549)318840 (0.249484)
2nd (rate)106427 (0.249829)319573 (0.250057)
3rd (rate)105945 (0.248697)320055 (0.250434)
4th (rate)106468 (0.249925)319532 (0.250025)
Tobi(rate)27006 (0.063394)87330 (0.068333)
Avg rank2.4969982.501001
Total rank pt60435-60435
Avg rank pt0.141866 ­čĹĹ-0.047289
Total Δscore18652900-18652900
Avg game Δscore43.786150-14.595383
Avg round Δscore4.082951-1.360984
Win rate0.2011000.210842
Deal-in rate0.1134770.119711
Call rate0.2883140.295943
Riichi rate0.1737970.182667
Ryukyoku rate0.1708370.170837
Avg winning Δscore6624.8155056436.649081
Avg winning Δscore as dealer8550.2705458377.695608
Avg winning Δscore as non-dealer5882.6723015698.101070
Avg riichi winning Δscore8235.6615568026.424142
Avg open winning Δscore5149.9890084928.198868
Avg dama winning Δscore6460.7371736446.738607
Avg ryukyoku Δscore-67.45888422.486295
Avg winning turn11.07320411.143723
Avg riichi winning turn11.08784611.151681
Avg open winning turn11.01051511.089835
Avg dama winning turn11.22520611.282352
Avg deal-in turn11.50201511.482273
Avg deal-in Δscore-5235.412861-5323.966492
Avg deal-in Δscore to dealer-6947.785537-7033.802381
Avg deal-in Δscore to non-dealer-4646.055777-4717.602231
Chasing riichi rate0.1633320.164827
Riichi chased rate0.1741740.168552
Winning rate after riichi0.4835050.479043
Deal-in rate after riichi0.1479380.149382
Avg riichi turn7.7511647.814533
Avg riichi Δscore3278.8167093131.209817
Avg number of calls1.4680831.444199
Winning rate after call0.3073610.312322
Deal-in rate after call0.1351900.136126
Avg call Δscore920.822027858.670427
Dealer wins/all dealer rounds0.2260890.231663
Dealer wins/all wins0.2782070.275619
Deal-in to dealer/all deal-ins0.2560500.261793
Yakuman (rate)657 (0.000143811)2103 (0.000153443)
Nagashi mangan (rate)92 (0.000020138)403 (0.000029404)

Swapping Challenger and Champion.

mortal1-b40c192-t22040618 (x1)mortal2-b75c256-t22092920 (x3)
Games4040001212000
Rounds436406113092183
Rounds as dealer11033443260717
1st (rate)100909 (0.249775)303091 (0.250075)
2nd (rate)101357 (0.250884)302643 (0.249705)
3rd (rate)101105 (0.250260)302895 (0.249913)
4th (rate)100629 (0.249082)303371 (0.250306)
Tobi(rate)29033 (0.071864)81611 (0.067336)
Avg rank2.4986492.500450
Total rank pt57960-57960
Avg rank pt0.143465 ­čĹĹ-0.047822
Total Δscore13969900-13969900
Avg game Δscore34.578960-11.526320
Avg round Δscore3.201124-1.067041
Win rate0.2126210.201806
Deal-in rate0.1180690.112019
Call rate0.2961540.287104
Riichi rate0.1852610.176752
Ryukyoku rate0.1862100.186210
Avg winning Δscore6468.7798126662.244567
Avg winning Δscore as dealer8402.9763328583.978730
Avg winning Δscore as non-dealer5726.7917935914.078352
Avg riichi winning Δscore8071.1020888282.872970
Avg open winning Δscore4920.2546455141.249336
Avg dama winning Δscore6487.7260566499.767462
Avg ryukyoku Δscore69.193852-23.064617
Avg winning turn11.22686811.165918
Avg riichi winning turn11.21928811.171787
Avg open winning turn11.18464811.112177
Avg dama winning turn11.36959611.309909
Avg deal-in turn11.52401211.554706
Avg deal-in Δscore-5461.129451-5379.466500
Avg deal-in Δscore to dealer-7145.173422-7080.005371
Avg deal-in Δscore to non-dealer-4849.924613-4777.221692
Chasing riichi rate0.1620700.159654
Riichi chased rate0.1621650.166870
Winning rate after riichi0.4782680.481330
Deal-in rate after riichi0.1460500.145433
Avg riichi turn7.8644157.809567
Avg riichi Δscore3166.4344643293.847974
Avg number of calls1.4352261.459294
Winning rate after call0.3108970.304871
Deal-in rate after call0.1335520.132994
Avg call Δscore859.858175912.474713
Dealer wins/all dealer rounds0.2331670.227058
Dealer wins/all wins0.2772560.280223
Deal-in to dealer/all deal-ins0.2662910.261529
Yakuman (rate)675 (0.000154672)1843 (0.000140771)
Nagashi mangan (rate)140 (0.000032080)300 (0.000022914)

mortal2-b75c256-t22100115 and mortal1-b40c192-t22040618

mortal2-b75c256-t22100115 (x1)mortal1-b40c192-t22040618 (x3)
Games88000264000
Rounds9387392816217
Rounds as dealer232809705930
1st (rate)23142 (0.262977)64858 (0.245674)
2nd (rate)21440 (0.243636)66560 (0.252121)
3rd (rate)20580 (0.233864)67420 (0.255379)
4th (rate)22838 (0.259523)65162 (0.246826)
Tobi(rate)6158 (0.069977)18546 (0.070250)
Avg rank2.4899322.503356
Total rank pt-3555035550
Avg rank pt-0.4039770.134659 ­čĹĹ
Total Δscore17452400-17452400
Avg game Δscore198.322727-66.107576
Avg round Δscore18.591323-6.197108
Win rate0.2013960.211725
Deal-in rate0.1206110.118825
Call rate0.2523370.297869
Riichi rate0.2148960.181350
Ryukyoku rate0.1678980.167898
Avg winning Δscore6895.2808136456.797252
Avg winning Δscore as dealer8896.5403538411.978003
Avg winning Δscore as non-dealer6126.6632995708.054700
Avg riichi winning Δscore8226.2344458055.765599
Avg open winning Δscore5268.1986574950.033985
Avg dama winning Δscore6817.0699246493.118161
Avg ryukyoku Δscore33.715707-11.238569
Avg winning turn11.18197111.112885
Avg riichi winning turn11.22761511.129407
Avg open winning turn11.09025411.056002
Avg dama winning turn11.30741111.238720
Avg deal-in turn11.50921211.491703
Avg deal-in Δscore-5268.248220-5371.322657
Avg deal-in Δscore to dealer-6986.856002-7088.977424
Avg deal-in Δscore to non-dealer-4661.518881-4764.608616
Chasing riichi rate0.1833380.173439
Riichi chased rate0.1676140.188733
Winning rate after riichi0.4608960.482050
Deal-in rate after riichi0.1573040.149767
Avg riichi turn7.9706797.798867
Avg riichi Δscore3023.1888013154.216686
Avg number of calls1.4412971.447179
Winning rate after call0.3168030.313935
Deal-in rate after call0.1397720.135112
Avg call Δscore997.837715861.855676
Dealer wins/all dealer rounds0.2253440.233891
Dealer wins/all wins0.2774920.276910
Deal-in to dealer/all deal-ins0.2609210.261023
Yakuman (rate)155 (0.000165115)510 (0.000181094)
Nagashi mangan (rate)29 (0.000030893)94 (0.000033378)

Swapping Challenger and Champion.

mortal1-b40c192-t22040618 (x1)mortal2-b75c256-t22100115 (x3)
Games184000552000
Rounds19492675847801
Rounds as dealer4908081458459
1st (rate)43859 (0.238364)140141 (0.253879)
2nd (rate)46785 (0.254266)137215 (0.248578)
3rd (rate)49108 (0.266891)134892 (0.244370)
4th (rate)44248 (0.240478)139752 (0.253174)
Tobi(rate)13951 (0.075821)42533 (0.077053)
Avg rank2.5094842.496839
Total rank pt79155-79155
Avg rank pt0.430190 ­čĹĹ-0.143397
Total Δscore-2721070027210700
Avg game Δscore-147.88423949.294746
Avg round Δscore-13.9594524.653151
Win rate0.2144270.203815
Deal-in rate0.1145370.116552
Call rate0.2988790.252706
Riichi rate0.1823240.216687
Ryukyoku rate0.1786740.178674
Avg winning Δscore6536.8502906979.860891
Avg winning Δscore as dealer8484.6208948965.835300
Avg winning Δscore as non-dealer5789.7268106209.649582
Avg riichi winning Δscore8147.5366268309.278377
Avg open winning Δscore5020.3294735337.498028
Avg dama winning Δscore6549.6324676890.664374
Avg ryukyoku Δscore-27.2392659.079755
Avg winning turn11.15559511.208098
Avg riichi winning turn11.16061711.252630
Avg open winning turn11.10297411.112422
Avg dama winning turn11.29921011.347049
Avg deal-in turn11.55710511.590087
Avg deal-in Δscore-5644.898169-5536.106677
Avg deal-in Δscore to dealer-7381.606863-7276.555470
Avg deal-in Δscore to non-dealer-5026.326180-4916.529358
Chasing riichi rate0.1905360.200899
Riichi chased rate0.2251790.203861
Winning rate after riichi0.4859060.464404
Deal-in rate after riichi0.1479020.154747
Avg riichi turn7.8235728.000077
Avg riichi Δscore3201.6435103069.475433
Avg number of calls1.4451381.438486
Winning rate after call0.3157080.317395
Deal-in rate after call0.1293630.135622
Avg call Δscore892.8754971007.683110
Dealer wins/all dealer rounds0.2360960.228368
Dealer wins/all wins0.2772370.279448
Deal-in to dealer/all deal-ins0.2626320.262530
Yakuman (rate)317 (0.000162625)913 (0.000156127)
Nagashi mangan (rate)57 (0.000029242)203 (0.000034714)

mortal2-b75c256-t22092920 and mortal2-b75c256-t22100115

mortal2-b75c256-t22100115 (x1)mortal2-b75c256-t22092920 (x3)
Games186000558000
Rounds20009046002712
Rounds as dealer5026011498303
1st (rate)49051 (0.263715)136949 (0.245428)
2nd (rate)45866 (0.246591)140134 (0.251136)
3rd (rate)43639 (0.234618)142361 (0.255127)
4th (rate)47444 (0.255075)138556 (0.248308)
Tobi(rate)14221 (0.076457)39735 (0.071210)
Avg rank2.4810542.506315
Total rank pt73620-73620
Avg rank pt0.395806 ­čĹĹ-0.131935
Total Δscore52811900-52811900
Avg game Δscore283.934946-94.644982
Avg round Δscore26.394020-8.798007
Win rate0.2037440.202917
Deal-in rate0.1174730.109930
Call rate0.2509550.288268
Riichi rate0.2210430.177158
Ryukyoku rate0.1916110.191611
Avg winning Δscore6968.2862696705.932998
Avg winning Δscore as dealer8960.6252958626.184921
Avg winning Δscore as non-dealer6189.8077335950.988887
Avg riichi winning Δscore8293.5445258325.528002
Avg open winning Δscore5273.4550005181.309799
Avg dama winning Δscore6928.6917416573.246859
Avg ryukyoku Δscore96.472055-32.157352
Avg winning turn11.31186611.193509
Avg riichi winning turn11.33946811.191932
Avg open winning turn11.23709811.142963
Avg dama winning turn11.44298811.348828
Avg deal-in turn11.59046311.601442
Avg deal-in Δscore-5483.272283-5512.258725
Avg deal-in Δscore to dealer-7189.870072-7213.092520
Avg deal-in Δscore to non-dealer-4861.026769-4901.751503
Chasing riichi rate0.1782470.167947
Riichi chased rate0.1583360.185398
Winning rate after riichi0.4588520.481619
Deal-in rate after riichi0.1523950.145284
Avg riichi turn8.0684447.821574
Avg riichi Δscore3062.5708253297.736095
Avg number of calls1.4257411.457532
Winning rate after call0.3138370.305507
Deal-in rate after call0.1356660.129938
Avg call Δscore1003.224226928.448665
Dealer wins/all dealer rounds0.2278910.229417
Dealer wins/all wins0.2809560.282201
Deal-in to dealer/all deal-ins0.2671910.264136
Yakuman (rate)357 (0.000178419)898 (0.000149599)
Nagashi mangan (rate)83 (0.000041481)157 (0.000026155)

Swapping Challenger and Champion.

mortal2-b75c256-t22092920 (x1)mortal2-b75c256-t22100115 (x3)
Games4680001404000
Rounds497064114911923
Rounds as dealer12387153731926
1st (rate)111524 (0.238299)356476 (0.253900)
2nd (rate)118662 (0.253551)349338 (0.248816)
3rd (rate)124344 (0.265692)343656 (0.244769)
4th (rate)113470 (0.242457)354530 (0.252514)
Tobi(rate)34046 (0.072748)111105 (0.079135)
Avg rank2.5123082.495897
Total rank pt58500-58500
Avg rank pt0.125000 ­čĹĹ-0.041667
Total Δscore-8719630087196300
Avg game Δscore-186.31688062.105627
Avg round Δscore-17.5422655.847422
Win rate0.2044510.204526
Deal-in rate0.1079860.115582
Call rate0.2899770.252561
Riichi rate0.1756600.218852
Ryukyoku rate0.1863540.186354
Avg winning Δscore6743.2289866999.379451
Avg winning Δscore as dealer8653.3900688978.546069
Avg winning Δscore as non-dealer5997.6529086231.775811
Avg riichi winning Δscore8362.7783358330.640680
Avg open winning Δscore5249.7647255334.895698
Avg dama winning Δscore6589.9440506939.807426
Avg ryukyoku Δscore-89.13555829.711853
Avg winning turn11.13341711.256085
Avg riichi winning turn11.14878611.294117
Avg open winning turn11.07034711.167886
Avg dama winning turn11.28137611.394572
Avg deal-in turn11.62801211.622673
Avg deal-in Δscore-5636.075222-5611.253453
Avg deal-in Δscore to dealer-7372.437410-7336.220817
Avg deal-in Δscore to non-dealer-5024.106218-4989.261629
Chasing riichi rate0.1872020.200789
Riichi chased rate0.2289460.202108
Winning rate after riichi0.4864710.462388
Deal-in rate after riichi0.1465650.153587
Avg riichi turn7.7995008.029891
Avg riichi Δscore3316.0852423065.027878
Avg number of calls1.4654611.434810
Winning rate after call0.3091840.317169
Deal-in rate after call0.1280320.134245
Avg call Δscore948.5641801011.617646
Dealer wins/all dealer rounds0.2303230.228383
Dealer wins/all wins0.2807420.279457
Deal-in to dealer/all deal-ins0.2605970.265020
Yakuman (rate)731 (0.000147064)2437 (0.000163426)
Nagashi mangan (rate)137 (0.000027562)575 (0.000038560)

mortal3-b24c512-t22122709 and mortal1-b40c192-t22040618

Seed: nonce=range(10000, 260000), key=0xd5dfaa4cef265cd7

mortal3-b24c512-t22122709 (x1)mortal1-b40c192-t22040618 (x3)
Games10000003000000
Rounds1069563432086902
Rounds as dealer26588288036806
1st (rate)252650 (0.252650)747350 (0.249117)
2nd (rate)247931 (0.247931)752069 (0.250690)
3rd (rate)248607 (0.248607)751393 (0.250464)
4th (rate)250812 (0.250812)749188 (0.249729)
Tobi(rate)67045 (0.067045)197266 (0.065755)
Avg rank2.4975812.500806
Total rank pt35775-35775
Avg rank pt0.035775 ­čĹĹ-0.011925
Total Δscore-6264120062641200
Avg game Δscore-62.64120020.880400
Avg round Δscore-5.8567081.952236
Win rate0.2080910.210464
Deal-in rate0.1194490.119959
Call rate0.2942220.295577
Riichi rate0.1889560.181209
Ryukyoku rate0.1650810.165081
Avg winning Δscore6449.1303486424.322248
Avg winning Δscore as dealer8419.5838238363.884227
Avg winning Δscore as non-dealer5712.7762865688.908765
Avg riichi winning Δscore8035.0324748015.259869
Avg open winning Δscore4824.7077714921.858157
Avg dama winning Δscore6693.9771606439.002502
Avg ryukyoku Δscore-7.3967142.465571
Avg winning turn11.11962211.091341
Avg riichi winning turn11.13880511.108040
Avg open winning turn11.08887711.028942
Avg dama winning turn11.16308011.233838
Avg deal-in turn11.40189311.469167
Avg deal-in Δscore-5218.971087-5258.480211
Avg deal-in Δscore to dealer-6911.768558-6973.255171
Avg deal-in Δscore to non-dealer-4626.232841-4661.005910
Chasing riichi rate0.1619100.168683
Riichi chased rate0.1736070.171993
Winning rate after riichi0.4793580.481873
Deal-in rate after riichi0.1501730.150826
Avg riichi turn7.8061757.789729
Avg riichi Δscore3134.2179283145.470729
Avg number of calls1.4323391.449045
Winning rate after call0.3135020.313821
Deal-in rate after call0.1339320.136927
Avg call Δscore848.863432861.857731
Dealer wins/all dealer rounds0.2277180.231012
Dealer wins/all wins0.2720380.274923
Deal-in to dealer/all deal-ins0.2593430.258395
Yakuman (rate)1399 (0.000130801)5116 (0.000159442)
Nagashi mangan (rate)753 (0.000070403)927 (0.000028890)

Swapping Challenger and Champion.

Seed: nonce=range(10000, 260000), key=0xd5dfaa4cef265cd7

mortal1-b40c192-t22040618 (x1)mortal3-b24c512-t22122709 (x3)
Games10000003000000
Rounds1068184632045538
Rounds as dealer26865427995304
1st (rate)247830 (0.247830)752170 (0.250723)
2nd (rate)251678 (0.251678)748322 (0.249441)
3rd (rate)250287 (0.250287)749713 (0.249904)
4th (rate)250205 (0.250205)749795 (0.249932)
Tobi(rate)64486 (0.064486)196291 (0.065430)
Avg rank2.5028672.499044
Total rank pt-147465147465
Avg rank pt-0.1474650.049155 ­čĹĹ
Total Δscore66038200-66038200
Avg game Δscore66.038200-22.012733
Avg round Δscore6.182283-2.060761
Win rate0.2104700.208555
Deal-in rate0.1186830.118394
Call rate0.2948010.293244
Riichi rate0.1814260.188990
Ryukyoku rate0.1682190.168219
Avg winning Δscore6441.7411076463.110036
Avg winning Δscore as dealer8389.1780648435.434308
Avg winning Δscore as non-dealer5701.8324215725.629723
Avg riichi winning Δscore8040.7954958056.487760
Avg open winning Δscore4921.7994284821.942178
Avg dama winning Δscore6452.4322586720.265364
Avg ryukyoku Δscore15.347898-5.115966
Avg winning turn11.08357911.110649
Avg riichi winning turn11.11133511.143880
Avg open winning turn11.00624611.056852
Avg dama winning turn11.23782511.186742
Avg deal-in turn11.49514311.425903
Avg deal-in Δscore-5268.128750-5226.544027
Avg deal-in Δscore to dealer-7013.511667-6942.419782
Avg deal-in Δscore to non-dealer-4666.693040-4631.493791
Chasing riichi rate0.1747010.168081
Riichi chased rate0.1743290.175712
Winning rate after riichi0.4827190.480700
Deal-in rate after riichi0.1504220.150047
Avg riichi turn7.7933207.812665
Avg riichi Δscore3172.1623603159.695391
Avg number of calls1.4499191.434968
Winning rate after call0.3132660.314411
Deal-in rate after call0.1357240.132926
Avg call Δscore866.934708856.788630
Dealer wins/all dealer rounds0.2304080.227492
Dealer wins/all wins0.2753310.272153
Deal-in to dealer/all deal-ins0.2562770.257494
Yakuman (rate)1715 (0.000160553)4260 (0.000132936)
Nagashi mangan (rate)346 (0.000032391)2298 (0.000071710)

mortal3-b24c512-t22122709 and mortal2-b75c256-t22092920

Seed: nonce=range(10000, 260000), key=0xd5dfaa4cef265cd7

mortal3-b24c512-t22122709 (x1)mortal2-b75c256-t22092920 (x3)
Games10000003000000
Rounds1079407432382222
Rounds as dealer27141898079885
1st (rate)253921 (0.253921)746079 (0.248693)
2nd (rate)249095 (0.249095)750905 (0.250302)
3rd (rate)248901 (0.248901)751099 (0.250366)
4th (rate)248083 (0.248083)751917 (0.250639)
Tobi(rate)71932 (0.071932)199836 (0.066612)
Avg rank2.4911462.502951
Total rank pt570960-570960
Avg rank pt0.570960 ­čĹĹ-0.190320
Total Δscore12519600-12519600
Avg game Δscore12.519600-4.173200
Avg round Δscore1.159859-0.386620
Win rate0.2108180.201898
Deal-in rate0.1169020.111598
Call rate0.2934370.286838
Riichi rate0.1934490.176785
Ryukyoku rate0.1875810.187581
Avg winning Δscore6505.4884036667.890829
Avg winning Δscore as dealer8477.9825758596.257317
Avg winning Δscore as non-dealer5759.3862985917.334229
Avg riichi winning Δscore8093.9321568287.397743
Avg open winning Δscore4822.2539675141.377214
Avg dama winning Δscore6779.9768146514.201122
Avg ryukyoku Δscore61.932587-20.644196
Avg winning turn11.26404911.163706
Avg riichi winning turn11.27015311.175177
Avg open winning turn11.24030411.104653
Avg dama winning turn11.32382811.306526
Avg deal-in turn11.48556211.574023
Avg deal-in Δscore-5426.145463-5381.267182
Avg deal-in Δscore to dealer-7103.013105-7091.845074
Avg deal-in Δscore to non-dealer-4818.004676-4781.601931
Chasing riichi rate0.1572520.162370
Riichi chased rate0.1635920.167532
Winning rate after riichi0.4773780.481816
Deal-in rate after riichi0.1453690.145891
Avg riichi turn7.8974617.814115
Avg riichi Δscore3168.9738523300.285237
Avg number of calls1.4182841.459495
Winning rate after call0.3119550.304760
Deal-in rate after call0.1301340.132450
Avg call Δscore856.123294914.165276
Dealer wins/all dealer rounds0.2300940.226703
Dealer wins/all wins0.2744440.280171
Deal-in to dealer/all deal-ins0.2661440.259568
Yakuman (rate)1464 (0.000135630)4806 (0.000148415)
Nagashi mangan (rate)926 (0.000085788)768 (0.000023717)

Swapping Challenger and Champion.

Seed: nonce=range(10000, 260000), key=0xd5dfaa4cef265cd7

mortal2-b75c256-t22092920 (x1)mortal3-b24c512-t22122709 (x3)
Games10000003000000
Rounds1070991732129751
Rounds as dealer26642038045714
1st (rate)247855 (0.247855)752145 (0.250715)
2nd (rate)251110 (0.251110)748890 (0.249630)
3rd (rate)249961 (0.249961)750039 (0.250013)
4th (rate)251074 (0.251074)748926 (0.249642)
Tobi(rate)61718 (0.061718)202260 (0.067420)
Avg rank2.5042542.498582
Total rank pt-288090288090
Avg rank pt-0.2880900.096030 ­čĹĹ
Total Δscore38611300-38611300
Avg game Δscore38.611300-12.870433
Avg round Δscore3.605191-1.201730
Win rate0.2007280.209391
Deal-in rate0.1118550.117746
Call rate0.2865400.293106
Riichi rate0.1737870.190548
Ryukyoku rate0.1753530.175353
Avg winning Δscore6646.7976206478.638827
Avg winning Δscore as dealer8583.4766038452.863873
Avg winning Δscore as non-dealer5898.7619215738.410751
Avg riichi winning Δscore8278.2090058074.388079
Avg open winning Δscore5138.4028034818.069187
Avg dama winning Δscore6476.6117846737.745891
Avg ryukyoku Δscore-56.75371618.917905
Avg winning turn11.06542011.159526
Avg riichi winning turn11.08783811.186097
Avg open winning turn10.98382811.111529
Avg dama winning turn11.25060911.235839
Avg deal-in turn11.54509311.457348
Avg deal-in Δscore-5254.747624-5286.519366
Avg deal-in Δscore to dealer-6997.933170-6998.560141
Avg deal-in Δscore to non-dealer-4664.630758-4688.125901
Chasing riichi rate0.1712270.166480
Riichi chased rate0.1765730.172225
Winning rate after riichi0.4848990.479996
Deal-in rate after riichi0.1484620.148330
Avg riichi turn7.7498687.842133
Avg riichi Δscore3313.9325023172.073099
Avg number of calls1.4690391.430194
Winning rate after call0.3068400.313696
Deal-in rate after call0.1336310.131876
Avg call Δscore921.151061856.316664
Dealer wins/all dealer rounds0.2248280.228026
Dealer wins/all wins0.2786280.272699
Deal-in to dealer/all deal-ins0.2529110.258996
Yakuman (rate)1576 (0.000147153)4308 (0.000134081)
Nagashi mangan (rate)218 (0.000020355)2543 (0.000079148)

mortal3-b24c512-t22122709 and mortal2-b75c256-t22100115

Seed: nonce=range(10000, 260000), key=0xd5dfaa4cef265cd7

mortal3-b24c512-t22122709 (x1)mortal2-b75c256-t22100115 (x3)
Games10000003000000
Rounds1058018031740540
Rounds as dealer26503207929860
1st (rate)240497 (0.240497)759503 (0.253168)
2nd (rate)252350 (0.252350)747650 (0.249217)
3rd (rate)266247 (0.266247)733753 (0.244584)
4th (rate)240906 (0.240906)759094 (0.253031)
Tobi(rate)76286 (0.076286)229191 (0.076397)
Avg rank2.5075622.497479
Total rank pt478170-478170
Avg rank pt0.478170 ­čĹĹ-0.159390
Total Δscore-234662700234662700
Avg game Δscore-234.66270078.220900
Avg round Δscore-22.1794627.393154
Win rate0.2121370.204120
Deal-in rate0.1136330.116214
Call rate0.2958170.252353
Riichi rate0.1904340.217060
Ryukyoku rate0.1799340.179934
Avg winning Δscore6562.0810446982.614957
Avg winning Δscore as dealer8524.9194888972.527641
Avg winning Δscore as non-dealer5820.5239746214.663863
Avg riichi winning Δscore8155.3081528325.205145
Avg open winning Δscore4918.6507455324.010738
Avg dama winning Δscore6841.4668846892.135765
Avg ryukyoku Δscore-33.44996311.149988
Avg winning turn11.17407811.210121
Avg riichi winning turn11.19380411.260085
Avg open winning turn11.13152311.105989
Avg dama winning turn11.25642311.355080
Avg deal-in turn11.52697611.612176
Avg deal-in Δscore-5606.544790-5540.796351
Avg deal-in Δscore to dealer-7334.694569-7293.048601
Avg deal-in Δscore to non-dealer-4991.365772-4922.769562
Chasing riichi rate0.1863780.205428
Riichi chased rate0.2298150.205832
Winning rate after riichi0.4833190.464406
Deal-in rate after riichi0.1479010.155449
Avg riichi turn7.8467438.008428
Avg riichi Δscore3180.3812443072.441118
Avg number of calls1.4307741.439585
Winning rate after call0.3167970.318383
Deal-in rate after call0.1265780.135364
Avg call Δscore885.0256741009.641505
Dealer wins/all dealer rounds0.2322130.227507
Dealer wins/all wins0.2742040.278459
Deal-in to dealer/all deal-ins0.2625240.260740
Yakuman (rate)1437 (0.000135820)5293 (0.000166758)
Nagashi mangan (rate)915 (0.000086482)1191 (0.000037523)

Swapping Challenger and Champion.

Seed: nonce=range(10000, 260000), key=0xd5dfaa4cef265cd7

mortal2-b75c256-t22100115 (x1)mortal3-b24c512-t22122709 (x3)
Games10000003000000
Rounds1064365131930953
Rounds as dealer26571477986504
1st (rate)259347 (0.259347)740653 (0.246884)
2nd (rate)247816 (0.247816)752184 (0.250728)
3rd (rate)234215 (0.234215)765785 (0.255262)
4th (rate)258622 (0.258622)741378 (0.247126)
Tobi(rate)67944 (0.067944)205917 (0.068639)
Avg rank2.4921122.502629
Total rank pt-421020421020
Avg rank pt-0.4210200.140340 ­čĹĹ
Total Δscore228401300-228401300
Avg game Δscore228.401300-76.133767
Avg round Δscore21.458924-7.152975
Win rate0.2014740.210016
Deal-in rate0.1187390.116618
Call rate0.2506260.293914
Riichi rate0.2151690.189668
Ryukyoku rate0.1728330.172833
Avg winning Δscore6915.1489736497.758759
Avg winning Δscore as dealer8911.6808818466.896617
Avg winning Δscore as non-dealer6150.0553765759.151321
Avg riichi winning Δscore8264.5917508098.586794
Avg open winning Δscore5247.7160134845.293569
Avg dama winning Δscore6817.9279616758.749431
Avg ryukyoku Δscore40.759326-13.586442
Avg winning turn11.16846611.132965
Avg riichi winning turn11.22055011.166051
Avg open winning turn11.05519211.077232
Avg dama winning turn11.33614311.215639
Avg deal-in turn11.56129311.470561
Avg deal-in Δscore-5287.797651-5343.773976
Avg deal-in Δscore to dealer-7030.056513-7068.283142
Avg deal-in Δscore to non-dealer-4686.285173-4743.306272
Chasing riichi rate0.1939870.176314
Riichi chased rate0.1718590.194337
Winning rate after riichi0.4628080.482173
Deal-in rate after riichi0.1569770.149222
Avg riichi turn7.9772377.827756
Avg riichi Δscore3067.2516423179.022276
Avg number of calls1.4424321.434169
Winning rate after call0.3162960.315339
Deal-in rate after call0.1391660.130661
Avg call Δscore990.477231865.012397
Dealer wins/all dealer rounds0.2235850.229041
Dealer wins/all wins0.2770450.272776
Deal-in to dealer/all deal-ins0.2566430.258268
Yakuman (rate)1771 (0.000166390)4241 (0.000132818)
Nagashi mangan (rate)379 (0.000035608)2532 (0.000079296)

mortal3-b24c512-t22122709 and mortal3-b24c512-t22121413

Seed: nonce=range(10000, 260000), key=0xd5dfaa4cef265cd7

mortal3-b24c512-t22122709 (x1)mortal3-b24c512-t22121413 (x3)
Games10000003000000
Rounds1067282032018460
Rounds as dealer26387548034066
1st (rate)257695 (0.257695)742305 (0.247435)
2nd (rate)251910 (0.251910)748090 (0.249363)
3rd (rate)246323 (0.246323)753677 (0.251226)
4th (rate)244072 (0.244072)755928 (0.251976)
Tobi(rate)61679 (0.061679)194147 (0.064716)
Avg rank2.4767722.507743
Total rank pt1578780-1578780
Avg rank pt1.578780 ­čĹĹ-0.526260
Total Δscore141713700-141713700
Avg game Δscore141.713700-47.237900
Avg round Δscore13.278000-4.426000
Win rate0.2066160.213110
Deal-in rate0.1165230.125230
Call rate0.2943280.303519
Riichi rate0.1851420.177515
Ryukyoku rate0.1593290.159329
Avg winning Δscore6393.2926996277.894042
Avg winning Δscore as dealer8361.1821708216.077731
Avg winning Δscore as non-dealer5663.5467405542.927200
Avg riichi winning Δscore8038.7099587967.980774
Avg open winning Δscore4763.9760864768.279243
Avg dama winning Δscore6643.9341966373.165641
Avg ryukyoku Δscore-18.7717036.257234
Avg winning turn10.97765310.969263
Avg riichi winning turn11.05423611.046526
Avg open winning turn10.88151110.875537
Avg dama winning turn11.06466511.046965
Avg deal-in turn11.29698511.277504
Avg deal-in Δscore-5131.059349-5120.197911
Avg deal-in Δscore to dealer-6851.804109-6818.371357
Avg deal-in Δscore to non-dealer-4531.572031-4528.012159
Chasing riichi rate0.1633290.171303
Riichi chased rate0.1777620.175511
Winning rate after riichi0.4774210.474646
Deal-in rate after riichi0.1480950.151698
Avg riichi turn7.7492907.745117
Avg riichi Δscore3151.1756893074.558334
Avg number of calls1.4413111.454160
Winning rate after call0.3164000.317539
Deal-in rate after call0.1305360.139848
Avg call Δscore862.860813832.612203
Dealer wins/all dealer rounds0.2260650.233514
Dealer wins/all wins0.2705130.274944
Deal-in to dealer/all deal-ins0.2583740.258556
Yakuman (rate)1315 (0.000123210)6080 (0.000189890)
Nagashi mangan (rate)794 (0.000074395)2218 (0.000069273)

Swapping Challenger and Champion.

Seed: nonce=range(10000, 260000), key=0xd5dfaa4cef265cd7

mortal3-b24c512-t22121413 (x1)mortal3-b24c512-t22122709 (x3)
Games10000003000000
Rounds1066999232009976
Rounds as dealer26979177972075
1st (rate)243806 (0.243806)756194 (0.252065)
2nd (rate)247827 (0.247827)752173 (0.250724)
3rd (rate)253045 (0.253045)746955 (0.248985)
4th (rate)255322 (0.255322)744678 (0.248226)
Tobi(rate)66615 (0.066615)192154 (0.064051)
Avg rank2.5198832.493372
Total rank pt-13737151373715
Avg rank pt-1.3737150.457905 ­čĹĹ
Total Δscore-118840100118840100
Avg game Δscore-118.84010039.613367
Avg round Δscore-11.1377873.712596
Win rate0.2139140.208153
Deal-in rate0.1252890.117664
Call rate0.3017220.293444
Riichi rate0.1803830.187768
Ryukyoku rate0.1662240.166224
Avg winning Δscore6330.7275016443.132694
Avg winning Δscore as dealer8280.3697628410.694912
Avg winning Δscore as non-dealer5586.9397565709.768885
Avg riichi winning Δscore7994.7496598056.114230
Avg open winning Δscore4802.3520734801.785665
Avg dama winning Δscore6409.4341576699.093516
Avg ryukyoku Δscore26.121389-8.707130
Avg winning turn11.05153911.069493
Avg riichi winning turn11.11245011.119327
Avg open winning turn10.97565410.996090
Avg dama winning turn11.11244711.159894
Avg deal-in turn11.37458611.395562
Avg deal-in Δscore-5186.749544-5198.649621
Avg deal-in Δscore to dealer-6900.362263-6921.241774
Avg deal-in Δscore to non-dealer-4594.414358-4602.814162
Chasing riichi rate0.1779530.168486
Riichi chased rate0.1747180.177684
Winning rate after riichi0.4764070.480056
Deal-in rate after riichi0.1530660.149383
Avg riichi turn7.7878947.792345
Avg riichi Δscore3083.7355823162.814094
Avg number of calls1.4497301.438054
Winning rate after call0.3156810.315400
Deal-in rate after call0.1397970.132199
Avg call Δscore833.669134859.677494
Dealer wins/all dealer rounds0.2336240.226936
Dealer wins/all wins0.2761490.271523
Deal-in to dealer/all deal-ins0.2568730.257000
Yakuman (rate)2076 (0.000194564)4131 (0.000129054)
Nagashi mangan (rate)839 (0.000078632)2327 (0.000072696)

Tenhou

Tenhou does not allow AI to play in ranked lobby without their permission, therefore I only compared how close Mortal's decisions matched those of other verified AIs that had previously played in Tenhou tokujou. I also sampled some tokujou and houou games to check against Mortal.

The model used in the statistic experiment was mortal1-b40c192-t22040618.

Docker Quick Start

A handy Dockerfile has been added to the project for an easy and quick start.

Warning

This Docker image is only designed for inference with mjai interface and is not targeted for training.

Build

$ git clone https://github.com/Equim-chan/Mortal.git
$ cd Mortal
$ sudo env DOCKER_BUILDKIT=1 docker build -t mortal:latest .

Prepare a trained model

The Docker image does not contain any model file of Model, therefore it must be prepared separately under a directory, which will be demostrated as /path/to/model/dir below. In this example, snapshot mortal1-b40c192-t22040618 is used.

Example

We are going to use Mortal to evaluate the next move for the scene shown in Figure 1.

Figure 1

First things first, we need to identify the POV's player ID. A player ID is an immutable number that identifies a specific player throughout one game. The rule is simple, the player sitting at the East at E1 is 0, and his shimocha (right) will be 1, toimen (across) will be 2, kamicha (left) will be 3. This works exactly the same as the tw parameter in Tenhou's log URL.

In this case, the POV's player ID is 2, because his seat is West at E1.

Mortal speaks mjai , a simple and easy-to-read stream format for mahjong records. From the perspective of player 2, the equivalant masked mjai events he has perceived so far are:

{"type":"start_game"}
{"type":"start_kyoku","bakaze":"E","dora_marker":"3s","kyoku":3,"honba":0,"kyotaku":0,"oya":2,"scores":[22000,23700,26000,28300],"tehais":[["?","?","?","?","?","?","?","?","?","?","?","?","?"],["?","?","?","?","?","?","?","?","?","?","?","?","?"],["1m","1m","4m","5m","1p","5p","8p","1s","4s","4s","6s","8s","N"],["?","?","?","?","?","?","?","?","?","?","?","?","?"]]}
{"type":"tsumo","actor":2,"pai":"6p"}
{"type":"dahai","actor":2,"pai":"1s","tsumogiri":false}
{"type":"tsumo","actor":3,"pai":"?"}
{"type":"dahai","actor":3,"pai":"1s","tsumogiri":false}
{"type":"tsumo","actor":0,"pai":"?"}
{"type":"dahai","actor":0,"pai":"9s","tsumogiri":false}
{"type":"tsumo","actor":1,"pai":"?"}
{"type":"dahai","actor":1,"pai":"9p","tsumogiri":false}
{"type":"tsumo","actor":2,"pai":"3s"}
{"type":"dahai","actor":2,"pai":"N","tsumogiri":false}
{"type":"tsumo","actor":3,"pai":"?"}
{"type":"dahai","actor":3,"pai":"9m","tsumogiri":false}
{"type":"tsumo","actor":0,"pai":"?"}
{"type":"dahai","actor":0,"pai":"1m","tsumogiri":false}
{"type":"tsumo","actor":1,"pai":"?"}
{"type":"dahai","actor":1,"pai":"1s","tsumogiri":false}
{"type":"tsumo","actor":2,"pai":"7s"}
{"type":"dahai","actor":2,"pai":"1p","tsumogiri":false}
{"type":"tsumo","actor":3,"pai":"?"}
{"type":"dahai","actor":3,"pai":"W","tsumogiri":false}
{"type":"tsumo","actor":0,"pai":"?"}
{"type":"dahai","actor":0,"pai":"1p","tsumogiri":false}
{"type":"tsumo","actor":1,"pai":"?"}
{"type":"dahai","actor":1,"pai":"W","tsumogiri":false}
{"type":"pon","actor":0,"target":1,"pai":"W","consumed":["W","W"]}
{"type":"dahai","actor":0,"pai":"2p","tsumogiri":false}
{"type":"tsumo","actor":1,"pai":"?"}
{"type":"dahai","actor":1,"pai":"9s","tsumogiri":false}
{"type":"tsumo","actor":2,"pai":"P"}
{"type":"dahai","actor":2,"pai":"8p","tsumogiri":false}
{"type":"tsumo","actor":3,"pai":"?"}
{"type":"dahai","actor":3,"pai":"C","tsumogiri":false}
{"type":"tsumo","actor":0,"pai":"?"}
{"type":"dahai","actor":0,"pai":"9p","tsumogiri":false}
{"type":"tsumo","actor":1,"pai":"?"}
{"type":"dahai","actor":1,"pai":"1s","tsumogiri":true}
{"type":"tsumo","actor":2,"pai":"7m"}
{"type":"dahai","actor":2,"pai":"7m","tsumogiri":true}
{"type":"tsumo","actor":3,"pai":"?"}
{"type":"dahai","actor":3,"pai":"7p","tsumogiri":false}
{"type":"tsumo","actor":0,"pai":"?"}
{"type":"dahai","actor":0,"pai":"C","tsumogiri":false}
{"type":"tsumo","actor":1,"pai":"?"}
{"type":"dahai","actor":1,"pai":"2s","tsumogiri":true}
{"type":"tsumo","actor":2,"pai":"6s"}
{"type":"dahai","actor":2,"pai":"6s","tsumogiri":true}
{"type":"tsumo","actor":3,"pai":"?"}
{"type":"dahai","actor":3,"pai":"E","tsumogiri":true}
{"type":"pon","actor":1,"target":3,"pai":"E","consumed":["E","E"]}
{"type":"dahai","actor":1,"pai":"2m","tsumogiri":false}
{"type":"tsumo","actor":2,"pai":"7p"}
{"type":"dahai","actor":2,"pai":"P","tsumogiri":false}
{"type":"tsumo","actor":3,"pai":"?"}
{"type":"dahai","actor":3,"pai":"8s","tsumogiri":false}
{"type":"tsumo","actor":0,"pai":"?"}
{"type":"dahai","actor":0,"pai":"E","tsumogiri":false}
{"type":"tsumo","actor":1,"pai":"?"}
{"type":"dahai","actor":1,"pai":"4p","tsumogiri":false}
{"type":"tsumo","actor":2,"pai":"8p"}
{"type":"dahai","actor":2,"pai":"8p","tsumogiri":true}
{"type":"tsumo","actor":3,"pai":"?"}
{"type":"dahai","actor":3,"pai":"9s","tsumogiri":false}
{"type":"tsumo","actor":0,"pai":"?"}
{"type":"dahai","actor":0,"pai":"S","tsumogiri":true}
{"type":"tsumo","actor":1,"pai":"?"}
{"type":"dahai","actor":1,"pai":"6s","tsumogiri":false}
{"type":"tsumo","actor":2,"pai":"9m"}
{"type":"dahai","actor":2,"pai":"9m","tsumogiri":true}
{"type":"tsumo","actor":3,"pai":"?"}
{"type":"dahai","actor":3,"pai":"2p","tsumogiri":false}
{"type":"tsumo","actor":0,"pai":"?"}
{"type":"dahai","actor":0,"pai":"2s","tsumogiri":true}
{"type":"tsumo","actor":1,"pai":"?"}
{"type":"dahai","actor":1,"pai":"8p","tsumogiri":true}
{"type":"tsumo","actor":2,"pai":"F"}
{"type":"dahai","actor":2,"pai":"F","tsumogiri":true}
{"type":"tsumo","actor":3,"pai":"?"}
{"type":"dahai","actor":3,"pai":"4p","tsumogiri":true}
{"type":"tsumo","actor":0,"pai":"?"}
{"type":"dahai","actor":0,"pai":"4m","tsumogiri":true}
{"type":"tsumo","actor":1,"pai":"?"}
{"type":"dahai","actor":1,"pai":"S","tsumogiri":true}
{"type":"tsumo","actor":2,"pai":"5mr"}
{"type":"dahai","actor":2,"pai":"5m","tsumogiri":false}
{"type":"tsumo","actor":3,"pai":"?"}
{"type":"reach","actor":3}
{"type":"dahai","actor":3,"pai":"N","tsumogiri":false}
{"type":"reach_accepted","actor":3}
{"type":"tsumo","actor":0,"pai":"?"}
{"type":"dahai","actor":0,"pai":"N","tsumogiri":false}
{"type":"tsumo","actor":1,"pai":"?"}
{"type":"dahai","actor":1,"pai":"F","tsumogiri":false}
{"type":"tsumo","actor":2,"pai":"9p"}

Save the mjai log content above into a file named log.json, then run:

$ sudo docker run -i --rm -v /path/to/model/dir:/mnt mortal 2 < log.json

This will output a series of new-line-separated JSONs, each of which represents Mortal's reaction to an mjai event that it is able to react to, with the last line corresponding to the scene illustrated above:

{
  "type": "dahai",
  "actor": 2,
  "pai": "9p",
  "tsumogiri": true,
  "meta": {
    "q_values": [
      -1.1929103,
      -1.5628747,
      -1.6204606,
      -1.607082,
      -1.3267958,
      -0.2436666,
      -1.5208447,
      -1.5280346,
      -1.5830542,
      -1.6640469,
      -1.1801766,
      -1.8054415
    ],
    "mask_bits": 17241923593,
    "is_greedy": true,
    "batch_size": 1,
    "shanten": 1,
    "eval_time_ns": 30352000
  }
}

From the JSON output we can clearly read that Mortal would like to discard 9p in this scene.

Tip

The field meta is not defined in mjai and is completely optional. In Mortal, this field is used to record metadata such as its network's raw outputs and evaluation time.

Don't shut down the process yet. Now let's go one turn further. The player discarded 9p, passed a 1m pon, and here it comes the next scene:

Figure 2

The mjai events the player perceived since Figure 1 are:

{"type":"dahai","actor":2,"pai":"9p","tsumogiri":true}
{"type":"tsumo","actor":3,"pai":"?"}
{"type":"dahai","actor":3,"pai":"2p","tsumogiri":true}
{"type":"tsumo","actor":0,"pai":"?"}
{"type":"dahai","actor":0,"pai":"8s","tsumogiri":false}
{"type":"tsumo","actor":1,"pai":"?"}
{"type":"dahai","actor":1,"pai":"1m","tsumogiri":false}
{"type":"tsumo","actor":2,"pai":"3p"}

Paste them into the running process's input (or just append these to log.json and re-run the command), and we will get Mortal's reactions to them.

First, there will be a none type action, which means Mortal would pass the 1m pon:

{
  "type": "none",
  "meta": {
    "q_values": [
      -1.2190987,
      -0.084070235
    ],
    "mask_bits": 37383395344384,
    "is_greedy": true,
    "batch_size": 1,
    "shanten": 1,
    "eval_time_ns": 29667100
  }
}

Then a dahai event will follow, which corresponds to the scene in Figure 2:

{
  "type": "dahai",
  "actor": 2,
  "pai": "1m",
  "tsumogiri": false,
  "meta": {
    "q_values": [
      -0.22652823,
      -1.7668037,
      -1.0071788,
      -1.7482929,
      -1.7783809,
      -1.5943735,
      -1.5575972,
      -1.5641792,
      -1.6780779,
      -1.7836256,
      -1.5739789,
      -1.915102
    ],
    "mask_bits": 17241794569,
    "is_greedy": true,
    "batch_size": 1,
    "eval_time_ns": 29686500
  }
}

We can tell that Mortal would choose to discard 1m at this point.

Build

Build required components

Prerequisites

To build and use Mortal, you need to have a Python environment and an up-to-date Rust compiler. If you plan to train, make sure you have a GPU installed.

It is recommended to use miniconda and rustup to setup the environment.

Instructions below will assume you already have miniconda and Rust installed.

Clone

$ git clone https://github.com/Equim-chan/Mortal.git
$ cd Mortal

From now on, the root directory of Mortal will be demostrated as $MORTAL_ROOT.

Create and activate a conda env

Working directory: $MORTAL_ROOT

$ conda env create -f environment.yml
$ conda activate mortal

Install pytorch

pytorch is not listed as a dependency in environment.yml on purpose so that users can install it with their favored ways as per their requirement, hardware and OS.

Check pytorch's doc on how to install pytorch in your environment. Personally, I recommand installing pytorch with pip.

Tip

Only torch is needed. You can skip the installation of torchvision and torchaudio.

Build and install libriichi

Working directory: $MORTAL_ROOT

$ cargo build -p libriichi --lib --release

For Linux

$ cp target/release/libriichi.so mortal/libriichi.so

For Windows (MSYS2)

$ cp target/release/riichi.dll mortal/libriichi.pyd

Test the environment

Working directory: $MORTAL_ROOT/mortal

$ python
Python 3.9.7 | packaged by conda-forge | (default, Sep 29 2021, 19:23:11)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import libriichi
>>> help(libriichi)

Optional targets

Run tests

Working directory: $MORTAL_ROOT

$ cargo test --workspace --no-default-features --features flate2/zlib -- --nocapture

Run benchmarks

Working directory: $MORTAL_ROOT

$ cargo test -p libriichi --no-default-features --bench bench

Build executable utilities

Working directory: $MORTAL_ROOT

$ cargo build -p libriichi --bins --no-default-features --release
$ cargo build -p exe-wrapper --release

Build documentation

Working directory: $MORTAL_ROOT/docs

$ cargo install mdbook mdbook-admonish mdbook-pagetoc
$ mdbook build

Meta

What does the name "Mortal" mean?

Mortal in this context means something opposed to supernatural or immortal.

There is no superpower in mahjong, nor any supernatural "fate's bless" to be relied on. Everyone is "mortal" and the AI is no different.

What the AI does is merely believing exclusively in the grand truth and never become emotional, with enough learning and practice and that's it. I've always believed that one of the reasons why many human players cannot defeat AIs in mahjong is that they are prone to becoming emotional, leading to minor but often fatal mistakes, which sometimes the players themselves deny to admit and blame on luck instead.

I got the inspiration from Kajiki Yumi, a character from Saki. She is indeed a mortal compared with other opponents she has played against, yet she tried her best as a mortal fighting for her own objective. "kajusan" was one of the names I have thought of, but I thought there were already a few mahjong projects based on character names from Saki.

I had a hard time thinking for a name. The project started with "OpenPhoenix", because it was at first a reproduction of Suphx, but after I changed many parts of it, it became less and less alike to Suphx, then I renamed it to "Reishanten". In the end, I thought the name was too hard to read and get its meaning, I came up with the name "Mortal".

When was the project started?

The project started on 2021-04-22. A prototype of PlayerState was made that day.

Why AGPL?

First of all, it is because the shanten algorithm (/libriichi/src/algo/shanten.rs) is a Rust port of tomohxx/shanten-number-calculator, which is licensed under GPL. As for the reason for it to be AGPL, my consideration is this project is natually easy to be exploited, such as being used for cheats or getting renamed then sold to unaware people, so even if I can't really stop such exploit, at least I want to do my part and make my attempt on what I can to stop this.

References

  1. Junjie Li, Sotetsu Koyamada, Qiwei Ye, Guoqing Liu, Chao Wang, Ruihan Yang, Li Zhao, Tao Qin, Tie-Yan Liu, and Hsiao-Wuen Hon. Suphx: Mastering mahjong with deep reinforcement learning. arXiv preprint arXiv:2003.13590, 2020.
  2. Dongqi Han, Tadashi Kozuno, Xufang Luo, Zhao-Yun Chen, Kenji Doya, Yuqing Yang, and Dongsheng Li. Variational oracle guiding for reinforcement learning. In International Conference on Learning Representations, 2022.
  3. Shingo Tsunoda. Tenhou Manual. https://tenhou.net/man. Retrieved April 22, 2021.
  4. Sanghyun Woo, Jongchan Park, Joon-Young Lee, and In So Kweon. CBAM: Convolutional Block Attention Module. Proceedings of the European conference on computer vision (ECCV), 2018.
  5. Louis Monier, Jakub Kmec, Alexandre Laterre, Thomas Pierrot, Valentin Courgeau, Olivier Sigaud, and Karim Beguir. Offline reinforcement learning hands-on. arXiv preprint arXiv:2011.14379, 2020.
  6. Artemij Amiranashvili, Alexey Dosovitskiy, Vladlen Koltun, and Thomas Brox. TD or not TD: Analyzing the role of temporal differencing in deep reinforcement learning. arXiv preprint arXiv:1806.01175, 2018.

Founders and original authors

Contributors

Contributors

Sponsors

DonateÔŁĄ´ŞĆ

Mortal is a free software provided under the GNU Affero General Public License.

Mortal was not born in a company or lab, but was essentially made by an individual developer out of pure interest. Writing the code and training the model has cost me far more time and money than I anticipated for a hobby. It would be my pleasure if you would like to honor my efforts.

Buy Me A Coffee

Ko-fi

Buy Me a Coffee at ko-fi.com

Cryptocurrencies

  • Monero
    4777777jHFbZB4gyqrB1JHDtrGFusyj4b3M2nScYDPKEM133ng2QDrK9ycqizXS2XofADw5do5rU19LQmpTGCfeQTerm1Ti
  • Bitcoin
    1Eqqqq9xR78wJyRXXgvR73HEfKdEwq68BT

Tenhou premium

My Tenhou screen name is ń║îň««ŔśşňşÉ. You could transfer premium days to me at https://tenhou.net/reg/transfer.cgi.