mahjong_engine 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (332) hide show
  1. package/.github/workflows/qlty-coverage.yml +36 -0
  2. package/dist/BlockDivider.d.ts +11 -0
  3. package/dist/BlockDivider.d.ts.map +1 -0
  4. package/dist/BlockDivider.js +114 -0
  5. package/dist/BlockDivider.js.map +1 -0
  6. package/dist/BlockHais.d.ts +26 -0
  7. package/dist/BlockHais.d.ts.map +1 -0
  8. package/dist/BlockHais.js +77 -0
  9. package/dist/BlockHais.js.map +1 -0
  10. package/dist/BlockHaisList.d.ts +19 -0
  11. package/dist/BlockHaisList.d.ts.map +1 -0
  12. package/dist/BlockHaisList.js +85 -0
  13. package/dist/BlockHaisList.js.map +1 -0
  14. package/dist/Hai.d.ts +16 -0
  15. package/dist/Hai.d.ts.map +1 -0
  16. package/dist/Hai.js +71 -0
  17. package/dist/Hai.js.map +1 -0
  18. package/dist/Hais.d.ts +15 -0
  19. package/dist/Hais.d.ts.map +1 -0
  20. package/dist/Hais.js +44 -0
  21. package/dist/Hais.js.map +1 -0
  22. package/dist/IMentsu.d.ts +20 -0
  23. package/dist/IMentsu.d.ts.map +1 -0
  24. package/dist/IMentsu.js +3 -0
  25. package/dist/IMentsu.js.map +1 -0
  26. package/dist/MachiCalculator.d.ts +7 -0
  27. package/dist/MachiCalculator.d.ts.map +1 -0
  28. package/dist/MachiCalculator.js +25 -0
  29. package/dist/MachiCalculator.js.map +1 -0
  30. package/dist/MahjongConsts.d.ts +39 -0
  31. package/dist/MahjongConsts.d.ts.map +1 -0
  32. package/dist/MahjongConsts.js +54 -0
  33. package/dist/MahjongConsts.js.map +1 -0
  34. package/dist/Meld.d.ts +25 -0
  35. package/dist/Meld.d.ts.map +1 -0
  36. package/dist/Meld.js +72 -0
  37. package/dist/Meld.js.map +1 -0
  38. package/dist/Melds.d.ts +9 -0
  39. package/dist/Melds.d.ts.map +1 -0
  40. package/dist/Melds.js +18 -0
  41. package/dist/Melds.js.map +1 -0
  42. package/dist/MentsuAnalyzer.d.ts +11 -0
  43. package/dist/MentsuAnalyzer.d.ts.map +1 -0
  44. package/dist/MentsuAnalyzer.js +23 -0
  45. package/dist/MentsuAnalyzer.js.map +1 -0
  46. package/dist/PlayerContext.d.ts +28 -0
  47. package/dist/PlayerContext.d.ts.map +1 -0
  48. package/dist/PlayerContext.js +28 -0
  49. package/dist/PlayerContext.js.map +1 -0
  50. package/dist/PlayerHand.d.ts +12 -0
  51. package/dist/PlayerHand.d.ts.map +1 -0
  52. package/dist/PlayerHand.js +28 -0
  53. package/dist/PlayerHand.js.map +1 -0
  54. package/dist/index.d.ts +12 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +26 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/tensuu/FuCalculator.d.ts +15 -0
  59. package/dist/tensuu/FuCalculator.d.ts.map +1 -0
  60. package/dist/tensuu/FuCalculator.js +104 -0
  61. package/dist/tensuu/FuCalculator.js.map +1 -0
  62. package/dist/tensuu/FuDetail.d.ts +8 -0
  63. package/dist/tensuu/FuDetail.d.ts.map +1 -0
  64. package/dist/tensuu/FuDetail.js +15 -0
  65. package/dist/tensuu/FuDetail.js.map +1 -0
  66. package/dist/tensuu/ScoreResolver.d.ts +12 -0
  67. package/dist/tensuu/ScoreResolver.d.ts.map +1 -0
  68. package/dist/tensuu/ScoreResolver.js +33 -0
  69. package/dist/tensuu/ScoreResolver.js.map +1 -0
  70. package/dist/tensuu/ScoreResult.d.ts +11 -0
  71. package/dist/tensuu/ScoreResult.d.ts.map +1 -0
  72. package/dist/tensuu/ScoreResult.js +19 -0
  73. package/dist/tensuu/ScoreResult.js.map +1 -0
  74. package/dist/tensuu/TensuuCalculator.d.ts +13 -0
  75. package/dist/tensuu/TensuuCalculator.d.ts.map +1 -0
  76. package/dist/tensuu/TensuuCalculator.js +39 -0
  77. package/dist/tensuu/TensuuCalculator.js.map +1 -0
  78. package/dist/tensuu/TensuuResult.d.ts +15 -0
  79. package/dist/tensuu/TensuuResult.d.ts.map +1 -0
  80. package/dist/tensuu/TensuuResult.js +19 -0
  81. package/dist/tensuu/TensuuResult.js.map +1 -0
  82. package/dist/tileDefs.d.ts +42 -0
  83. package/dist/tileDefs.d.ts.map +1 -0
  84. package/dist/tileDefs.js +23 -0
  85. package/dist/tileDefs.js.map +1 -0
  86. package/dist/yaku/NormalYakuChecker.d.ts +7 -0
  87. package/dist/yaku/NormalYakuChecker.d.ts.map +1 -0
  88. package/dist/yaku/NormalYakuChecker.js +37 -0
  89. package/dist/yaku/NormalYakuChecker.js.map +1 -0
  90. package/dist/yaku/YakuChecker.d.ts +7 -0
  91. package/dist/yaku/YakuChecker.d.ts.map +1 -0
  92. package/dist/yaku/YakuChecker.js +27 -0
  93. package/dist/yaku/YakuChecker.js.map +1 -0
  94. package/dist/yaku/YakuCheckerBase.d.ts +33 -0
  95. package/dist/yaku/YakuCheckerBase.d.ts.map +1 -0
  96. package/dist/yaku/YakuCheckerBase.js +154 -0
  97. package/dist/yaku/YakuCheckerBase.js.map +1 -0
  98. package/dist/yaku/YakuContext.d.ts +14 -0
  99. package/dist/yaku/YakuContext.d.ts.map +1 -0
  100. package/dist/yaku/YakuContext.js +21 -0
  101. package/dist/yaku/YakuContext.js.map +1 -0
  102. package/dist/yaku/YakumanChecker.d.ts +7 -0
  103. package/dist/yaku/YakumanChecker.d.ts.map +1 -0
  104. package/dist/yaku/YakumanChecker.js +36 -0
  105. package/dist/yaku/YakumanChecker.js.map +1 -0
  106. package/dist/yaku/index.d.ts +6 -0
  107. package/dist/yaku/index.d.ts.map +1 -0
  108. package/dist/yaku/index.js +79 -0
  109. package/dist/yaku/index.js.map +1 -0
  110. package/dist/yaku/normal/ChinitsuChecker.d.ts +9 -0
  111. package/dist/yaku/normal/ChinitsuChecker.d.ts.map +1 -0
  112. package/dist/yaku/normal/ChinitsuChecker.js +24 -0
  113. package/dist/yaku/normal/ChinitsuChecker.js.map +1 -0
  114. package/dist/yaku/normal/ChitoitsuChecker.d.ts +8 -0
  115. package/dist/yaku/normal/ChitoitsuChecker.d.ts.map +1 -0
  116. package/dist/yaku/normal/ChitoitsuChecker.js +20 -0
  117. package/dist/yaku/normal/ChitoitsuChecker.js.map +1 -0
  118. package/dist/yaku/normal/DoukouChecker.d.ts +8 -0
  119. package/dist/yaku/normal/DoukouChecker.d.ts.map +1 -0
  120. package/dist/yaku/normal/DoukouChecker.js +17 -0
  121. package/dist/yaku/normal/DoukouChecker.js.map +1 -0
  122. package/dist/yaku/normal/HonchanChecker.d.ts +8 -0
  123. package/dist/yaku/normal/HonchanChecker.d.ts.map +1 -0
  124. package/dist/yaku/normal/HonchanChecker.js +22 -0
  125. package/dist/yaku/normal/HonchanChecker.js.map +1 -0
  126. package/dist/yaku/normal/HonitsuChecker.d.ts +8 -0
  127. package/dist/yaku/normal/HonitsuChecker.d.ts.map +1 -0
  128. package/dist/yaku/normal/HonitsuChecker.js +20 -0
  129. package/dist/yaku/normal/HonitsuChecker.js.map +1 -0
  130. package/dist/yaku/normal/HonrotoChecker.d.ts +8 -0
  131. package/dist/yaku/normal/HonrotoChecker.d.ts.map +1 -0
  132. package/dist/yaku/normal/HonrotoChecker.js +21 -0
  133. package/dist/yaku/normal/HonrotoChecker.js.map +1 -0
  134. package/dist/yaku/normal/IipekoChecker.d.ts +8 -0
  135. package/dist/yaku/normal/IipekoChecker.d.ts.map +1 -0
  136. package/dist/yaku/normal/IipekoChecker.js +18 -0
  137. package/dist/yaku/normal/IipekoChecker.js.map +1 -0
  138. package/dist/yaku/normal/IttsuuChecker.d.ts +8 -0
  139. package/dist/yaku/normal/IttsuuChecker.d.ts.map +1 -0
  140. package/dist/yaku/normal/IttsuuChecker.js +25 -0
  141. package/dist/yaku/normal/IttsuuChecker.js.map +1 -0
  142. package/dist/yaku/normal/JunchanChecker.d.ts +8 -0
  143. package/dist/yaku/normal/JunchanChecker.d.ts.map +1 -0
  144. package/dist/yaku/normal/JunchanChecker.js +19 -0
  145. package/dist/yaku/normal/JunchanChecker.js.map +1 -0
  146. package/dist/yaku/normal/KazehaiChecker.d.ts +11 -0
  147. package/dist/yaku/normal/KazehaiChecker.d.ts.map +1 -0
  148. package/dist/yaku/normal/KazehaiChecker.js +24 -0
  149. package/dist/yaku/normal/KazehaiChecker.js.map +1 -0
  150. package/dist/yaku/normal/MenzenTsumoChecker.d.ts +8 -0
  151. package/dist/yaku/normal/MenzenTsumoChecker.d.ts.map +1 -0
  152. package/dist/yaku/normal/MenzenTsumoChecker.js +16 -0
  153. package/dist/yaku/normal/MenzenTsumoChecker.js.map +1 -0
  154. package/dist/yaku/normal/PinfuChecker.d.ts +8 -0
  155. package/dist/yaku/normal/PinfuChecker.d.ts.map +1 -0
  156. package/dist/yaku/normal/PinfuChecker.js +30 -0
  157. package/dist/yaku/normal/PinfuChecker.js.map +1 -0
  158. package/dist/yaku/normal/RenpuuhaiChecker.d.ts +8 -0
  159. package/dist/yaku/normal/RenpuuhaiChecker.d.ts.map +1 -0
  160. package/dist/yaku/normal/RenpuuhaiChecker.js +22 -0
  161. package/dist/yaku/normal/RenpuuhaiChecker.js.map +1 -0
  162. package/dist/yaku/normal/RyanpekoChecker.d.ts +8 -0
  163. package/dist/yaku/normal/RyanpekoChecker.d.ts.map +1 -0
  164. package/dist/yaku/normal/RyanpekoChecker.js +18 -0
  165. package/dist/yaku/normal/RyanpekoChecker.js.map +1 -0
  166. package/dist/yaku/normal/SanankoChecker.d.ts +8 -0
  167. package/dist/yaku/normal/SanankoChecker.d.ts.map +1 -0
  168. package/dist/yaku/normal/SanankoChecker.js +17 -0
  169. package/dist/yaku/normal/SanankoChecker.js.map +1 -0
  170. package/dist/yaku/normal/SankantsuChecker.d.ts +8 -0
  171. package/dist/yaku/normal/SankantsuChecker.d.ts.map +1 -0
  172. package/dist/yaku/normal/SankantsuChecker.js +17 -0
  173. package/dist/yaku/normal/SankantsuChecker.js.map +1 -0
  174. package/dist/yaku/normal/SanshokuChecker.d.ts +8 -0
  175. package/dist/yaku/normal/SanshokuChecker.d.ts.map +1 -0
  176. package/dist/yaku/normal/SanshokuChecker.js +17 -0
  177. package/dist/yaku/normal/SanshokuChecker.js.map +1 -0
  178. package/dist/yaku/normal/ShosangenChecker.d.ts +8 -0
  179. package/dist/yaku/normal/ShosangenChecker.d.ts.map +1 -0
  180. package/dist/yaku/normal/ShosangenChecker.js +20 -0
  181. package/dist/yaku/normal/ShosangenChecker.js.map +1 -0
  182. package/dist/yaku/normal/TanyaoChecker.d.ts +8 -0
  183. package/dist/yaku/normal/TanyaoChecker.d.ts.map +1 -0
  184. package/dist/yaku/normal/TanyaoChecker.js +18 -0
  185. package/dist/yaku/normal/TanyaoChecker.js.map +1 -0
  186. package/dist/yaku/normal/ToitoiChecker.d.ts +8 -0
  187. package/dist/yaku/normal/ToitoiChecker.d.ts.map +1 -0
  188. package/dist/yaku/normal/ToitoiChecker.js +17 -0
  189. package/dist/yaku/normal/ToitoiChecker.js.map +1 -0
  190. package/dist/yaku/normal/YakuhaiChecker.d.ts +9 -0
  191. package/dist/yaku/normal/YakuhaiChecker.d.ts.map +1 -0
  192. package/dist/yaku/normal/YakuhaiChecker.js +22 -0
  193. package/dist/yaku/normal/YakuhaiChecker.js.map +1 -0
  194. package/dist/yaku/yakuman/ChinrotoChecker.d.ts +6 -0
  195. package/dist/yaku/yakuman/ChinrotoChecker.d.ts.map +1 -0
  196. package/dist/yaku/yakuman/ChinrotoChecker.js +13 -0
  197. package/dist/yaku/yakuman/ChinrotoChecker.js.map +1 -0
  198. package/dist/yaku/yakuman/Churen9Checker.d.ts +10 -0
  199. package/dist/yaku/yakuman/Churen9Checker.d.ts.map +1 -0
  200. package/dist/yaku/yakuman/Churen9Checker.js +17 -0
  201. package/dist/yaku/yakuman/Churen9Checker.js.map +1 -0
  202. package/dist/yaku/yakuman/ChurenChecker.d.ts +7 -0
  203. package/dist/yaku/yakuman/ChurenChecker.d.ts.map +1 -0
  204. package/dist/yaku/yakuman/ChurenChecker.js +33 -0
  205. package/dist/yaku/yakuman/ChurenChecker.js.map +1 -0
  206. package/dist/yaku/yakuman/DaisangenChecker.d.ts +6 -0
  207. package/dist/yaku/yakuman/DaisangenChecker.d.ts.map +1 -0
  208. package/dist/yaku/yakuman/DaisangenChecker.js +15 -0
  209. package/dist/yaku/yakuman/DaisangenChecker.js.map +1 -0
  210. package/dist/yaku/yakuman/DaisushiChecker.d.ts +8 -0
  211. package/dist/yaku/yakuman/DaisushiChecker.d.ts.map +1 -0
  212. package/dist/yaku/yakuman/DaisushiChecker.js +20 -0
  213. package/dist/yaku/yakuman/DaisushiChecker.js.map +1 -0
  214. package/dist/yaku/yakuman/ExtendedYakumanChecker.d.ts +9 -0
  215. package/dist/yaku/yakuman/ExtendedYakumanChecker.d.ts.map +1 -0
  216. package/dist/yaku/yakuman/ExtendedYakumanChecker.js +18 -0
  217. package/dist/yaku/yakuman/ExtendedYakumanChecker.js.map +1 -0
  218. package/dist/yaku/yakuman/Kokushi13Checker.d.ts +10 -0
  219. package/dist/yaku/yakuman/Kokushi13Checker.d.ts.map +1 -0
  220. package/dist/yaku/yakuman/Kokushi13Checker.js +17 -0
  221. package/dist/yaku/yakuman/Kokushi13Checker.js.map +1 -0
  222. package/dist/yaku/yakuman/KokushiChecker.d.ts +7 -0
  223. package/dist/yaku/yakuman/KokushiChecker.d.ts.map +1 -0
  224. package/dist/yaku/yakuman/KokushiChecker.js +18 -0
  225. package/dist/yaku/yakuman/KokushiChecker.js.map +1 -0
  226. package/dist/yaku/yakuman/RyuisoChecker.d.ts +6 -0
  227. package/dist/yaku/yakuman/RyuisoChecker.d.ts.map +1 -0
  228. package/dist/yaku/yakuman/RyuisoChecker.js +17 -0
  229. package/dist/yaku/yakuman/RyuisoChecker.js.map +1 -0
  230. package/dist/yaku/yakuman/ShosushiChecker.d.ts +6 -0
  231. package/dist/yaku/yakuman/ShosushiChecker.d.ts.map +1 -0
  232. package/dist/yaku/yakuman/ShosushiChecker.js +15 -0
  233. package/dist/yaku/yakuman/ShosushiChecker.js.map +1 -0
  234. package/dist/yaku/yakuman/SuankoChecker.d.ts +7 -0
  235. package/dist/yaku/yakuman/SuankoChecker.d.ts.map +1 -0
  236. package/dist/yaku/yakuman/SuankoChecker.js +17 -0
  237. package/dist/yaku/yakuman/SuankoChecker.js.map +1 -0
  238. package/dist/yaku/yakuman/SuankoTankiChecker.d.ts +8 -0
  239. package/dist/yaku/yakuman/SuankoTankiChecker.d.ts.map +1 -0
  240. package/dist/yaku/yakuman/SuankoTankiChecker.js +28 -0
  241. package/dist/yaku/yakuman/SuankoTankiChecker.js.map +1 -0
  242. package/dist/yaku/yakuman/SukantsuChecker.d.ts +6 -0
  243. package/dist/yaku/yakuman/SukantsuChecker.d.ts.map +1 -0
  244. package/dist/yaku/yakuman/SukantsuChecker.js +12 -0
  245. package/dist/yaku/yakuman/SukantsuChecker.js.map +1 -0
  246. package/dist/yaku/yakuman/TsuisoChecker.d.ts +6 -0
  247. package/dist/yaku/yakuman/TsuisoChecker.d.ts.map +1 -0
  248. package/dist/yaku/yakuman/TsuisoChecker.js +13 -0
  249. package/dist/yaku/yakuman/TsuisoChecker.js.map +1 -0
  250. package/jest.config.js +8 -0
  251. package/modules/BlockDivider.ts +129 -0
  252. package/modules/BlockHais.ts +92 -0
  253. package/modules/BlockHaisList.ts +96 -0
  254. package/modules/Hai.ts +67 -0
  255. package/modules/Hais.ts +49 -0
  256. package/modules/IMentsu.ts +20 -0
  257. package/modules/MachiCalculator.ts +25 -0
  258. package/modules/MahjongConsts.ts +46 -0
  259. package/modules/Meld.ts +85 -0
  260. package/modules/Melds.ts +19 -0
  261. package/modules/MentsuAnalyzer.ts +37 -0
  262. package/modules/PlayerContext.ts +39 -0
  263. package/modules/PlayerHand.ts +32 -0
  264. package/modules/index.ts +11 -0
  265. package/modules/tensuu/FuCalculator.ts +118 -0
  266. package/modules/tensuu/FuDetail.ts +13 -0
  267. package/modules/tensuu/ScoreResolver.ts +35 -0
  268. package/modules/tensuu/ScoreResult.ts +24 -0
  269. package/modules/tensuu/TensuuCalculator.ts +40 -0
  270. package/modules/tensuu/TensuuResult.ts +21 -0
  271. package/modules/tileDefs.ts +24 -0
  272. package/modules/yaku/NormalYakuChecker.ts +31 -0
  273. package/modules/yaku/YakuChecker.ts +29 -0
  274. package/modules/yaku/YakuCheckerBase.ts +180 -0
  275. package/modules/yaku/YakuContext.ts +25 -0
  276. package/modules/yaku/YakumanChecker.ts +34 -0
  277. package/modules/yaku/index.ts +83 -0
  278. package/modules/yaku/normal/ChinitsuChecker.ts +25 -0
  279. package/modules/yaku/normal/ChitoitsuChecker.ts +20 -0
  280. package/modules/yaku/normal/DoukouChecker.ts +16 -0
  281. package/modules/yaku/normal/HonchanChecker.ts +24 -0
  282. package/modules/yaku/normal/HonitsuChecker.ts +20 -0
  283. package/modules/yaku/normal/HonrotoChecker.ts +23 -0
  284. package/modules/yaku/normal/IipekoChecker.ts +17 -0
  285. package/modules/yaku/normal/IttsuuChecker.ts +32 -0
  286. package/modules/yaku/normal/JunchanChecker.ts +20 -0
  287. package/modules/yaku/normal/KazehaiChecker.ts +25 -0
  288. package/modules/yaku/normal/MenzenTsumoChecker.ts +15 -0
  289. package/modules/yaku/normal/PinfuChecker.ts +26 -0
  290. package/modules/yaku/normal/RenpuuhaiChecker.ts +21 -0
  291. package/modules/yaku/normal/RyanpekoChecker.ts +17 -0
  292. package/modules/yaku/normal/SanankoChecker.ts +17 -0
  293. package/modules/yaku/normal/SankantsuChecker.ts +16 -0
  294. package/modules/yaku/normal/SanshokuChecker.ts +16 -0
  295. package/modules/yaku/normal/ShosangenChecker.ts +21 -0
  296. package/modules/yaku/normal/TanyaoChecker.ts +18 -0
  297. package/modules/yaku/normal/ToitoiChecker.ts +17 -0
  298. package/modules/yaku/normal/YakuhaiChecker.ts +22 -0
  299. package/modules/yaku/yakuman/ChinrotoChecker.ts +11 -0
  300. package/modules/yaku/yakuman/Churen9Checker.ts +16 -0
  301. package/modules/yaku/yakuman/ChurenChecker.ts +31 -0
  302. package/modules/yaku/yakuman/DaisangenChecker.ts +14 -0
  303. package/modules/yaku/yakuman/DaisushiChecker.ts +21 -0
  304. package/modules/yaku/yakuman/ExtendedYakumanChecker.ts +18 -0
  305. package/modules/yaku/yakuman/Kokushi13Checker.ts +16 -0
  306. package/modules/yaku/yakuman/KokushiChecker.ts +15 -0
  307. package/modules/yaku/yakuman/RyuisoChecker.ts +16 -0
  308. package/modules/yaku/yakuman/ShosushiChecker.ts +13 -0
  309. package/modules/yaku/yakuman/SuankoChecker.ts +14 -0
  310. package/modules/yaku/yakuman/SuankoTankiChecker.ts +28 -0
  311. package/modules/yaku/yakuman/SukantsuChecker.ts +9 -0
  312. package/modules/yaku/yakuman/TsuisoChecker.ts +10 -0
  313. package/package.json +28 -0
  314. package/tests/fu.test.ts +44 -0
  315. package/tests/machi/chinitsu.ts +137 -0
  316. package/tests/machi/chitoitsu.ts +12 -0
  317. package/tests/machi/kokushi.ts +22 -0
  318. package/tests/machi/maisuu.ts +77 -0
  319. package/tests/machi.test.ts +100 -0
  320. package/tests/machiType.test.ts +93 -0
  321. package/tests/score.test.ts +27 -0
  322. package/tests/tehaiCaseRunner.ts +57 -0
  323. package/tests/tensuu/fu.ts +272 -0
  324. package/tests/tensuu/score.ts +46 -0
  325. package/tests/tensuu/tensuuNum.ts +292 -0
  326. package/tests/tensuuFromNum.test.ts +15 -0
  327. package/tests/testConsts.ts +42 -0
  328. package/tests/toBlock.test.ts +155 -0
  329. package/tests/yaku/normal.ts +1046 -0
  330. package/tests/yaku/yakuman.ts +367 -0
  331. package/tests/yaku.test.ts +28 -0
  332. package/tsconfig.json +23 -0
@@ -0,0 +1,15 @@
1
+ import { YakuContext } from '../YakuContext';
2
+ import { YakuCheckerBase } from '../YakuCheckerBase';
3
+
4
+ export class MenzenTsumoChecker extends YakuCheckerBase{
5
+ protected yakuName: string = "門前清自摸和";
6
+
7
+ constructor(context: YakuContext){
8
+ super(context);
9
+ this.hanMenzen = 1;
10
+ }
11
+
12
+ protected isSatisfied(): boolean {
13
+ return this.isMenzen() && this.context.ctx.isTsumo;
14
+ }
15
+ }
@@ -0,0 +1,26 @@
1
+ import { YakuContext } from '../YakuContext';
2
+ import { YakuCheckerBase } from '../YakuCheckerBase';
3
+ import { BlockHais } from '../../BlockHais';
4
+ import { MachiType } from '../../MahjongConsts';
5
+ import { MentsuAnalyzer } from '../../MentsuAnalyzer';
6
+
7
+ export class PinfuChecker extends YakuCheckerBase{
8
+ protected yakuName: string = "平和";
9
+
10
+ constructor(context: YakuContext){
11
+ super(context);
12
+ this.hanMenzen = 1;
13
+ }
14
+
15
+ protected isSatisfied(): boolean {
16
+ const analyzer = new MentsuAnalyzer(this.context.block.getBlockHais(), this.context.melds);
17
+ const pw = this.context.ctx.playerWind;
18
+ const rw = this.context.ctx.roundWind;
19
+ if(!this.isMenzen()) return false;
20
+ if(analyzer.hasYakuhaiMentsu(m => m instanceof BlockHais && m.isJanto(), pw, rw)) return false;
21
+ if(!analyzer.getAll().every(m => m.isShuntsu() || (m instanceof BlockHais && m.isJanto()))) return false;
22
+ if(!this.context.block.calcMachiType(this.context.ctx.agariHai.getId()).has(MachiType.RYANMEN)) return false;
23
+
24
+ return true;
25
+ }
26
+ }
@@ -0,0 +1,21 @@
1
+ import { YakuContext } from '../YakuContext';
2
+ import { YakuCheckerBase } from '../YakuCheckerBase';
3
+ import { MentsuAnalyzer } from '../../MentsuAnalyzer';
4
+
5
+ export class RenpuuhaiChecker extends YakuCheckerBase{
6
+ protected yakuName: string;
7
+
8
+ constructor(context: YakuContext){
9
+ super(context);
10
+ this.hanMenzen = 2;
11
+ this.hanFuro = 2;
12
+ this.yakuName = `連風牌:${this.context.ctx.playerWind.name}`;
13
+ }
14
+
15
+ protected isSatisfied(): boolean {
16
+ const analyzer = new MentsuAnalyzer(this.context.block.getBlockHais(), this.context.melds);
17
+ const pw = this.context.ctx.playerWind;
18
+ const rw = this.context.ctx.roundWind;
19
+ return analyzer.hasDoubleWindMentsu(m => m.isKotsuOrKantsu(), pw, rw);
20
+ }
21
+ }
@@ -0,0 +1,17 @@
1
+ import { YakuContext } from '../YakuContext';
2
+ import { YakuCheckerBase } from '../YakuCheckerBase';
3
+
4
+
5
+ export class RyanpekoChecker extends YakuCheckerBase{
6
+ protected yakuName: string = "二盃口";
7
+
8
+ constructor(context: YakuContext){
9
+ super(context);
10
+ this.hanMenzen = 3;
11
+ }
12
+
13
+ protected isSatisfied(): boolean {
14
+ if(!this.isMenzen()) return false;
15
+ return this.countSameShuntsuGroups() === 2;
16
+ }
17
+ }
@@ -0,0 +1,17 @@
1
+ import { YakuContext } from '../YakuContext';
2
+ import { YakuCheckerBase } from '../YakuCheckerBase';
3
+
4
+
5
+ export class SanankoChecker extends YakuCheckerBase{
6
+ protected yakuName: string = "三暗刻";
7
+
8
+ constructor(context: YakuContext){
9
+ super(context);
10
+ this.hanMenzen = 2;
11
+ this.hanFuro = 2;
12
+ }
13
+
14
+ protected isSatisfied(): boolean {
15
+ return this.countAnko() === 3;
16
+ }
17
+ }
@@ -0,0 +1,16 @@
1
+ import { YakuContext } from '../YakuContext';
2
+ import { YakuCheckerBase } from '../YakuCheckerBase';
3
+
4
+ export class SankantsuChecker extends YakuCheckerBase{
5
+ protected yakuName: string = "三槓子";
6
+
7
+ constructor(context: YakuContext){
8
+ super(context);
9
+ this.hanMenzen = 2;
10
+ this.hanFuro = 2;
11
+ }
12
+
13
+ protected isSatisfied(): boolean {
14
+ return this.countKantsu() === 3;
15
+ }
16
+ }
@@ -0,0 +1,16 @@
1
+ import { YakuContext } from '../YakuContext';
2
+ import { YakuCheckerBase } from '../YakuCheckerBase';
3
+
4
+ export class SanshokuChecker extends YakuCheckerBase{
5
+ protected yakuName: string = "三色同順";
6
+
7
+ constructor(context: YakuContext){
8
+ super(context);
9
+ this.hanMenzen = 2;
10
+ this.hanFuro = 1;
11
+ }
12
+
13
+ protected isSatisfied(): boolean {
14
+ return this.checkSanshoku((m) => m.isShuntsu());
15
+ }
16
+ }
@@ -0,0 +1,21 @@
1
+ import { YakuContext } from '../YakuContext';
2
+ import { YakuCheckerBase } from '../YakuCheckerBase';
3
+
4
+
5
+ export class ShosangenChecker extends YakuCheckerBase{
6
+ protected yakuName: string = "小三元";
7
+
8
+ constructor(context: YakuContext){
9
+ super(context);
10
+ this.hanMenzen = 2;
11
+ this.hanFuro = 2;
12
+ }
13
+
14
+ protected isSatisfied(): boolean {
15
+ const {foundTargets, mentsuCount, jantoCount} = this.countTargetBlocks(this.context.block, [32,33,34]);
16
+
17
+ if(foundTargets.size !== 3) return false;
18
+
19
+ return mentsuCount === 2 && jantoCount === 1;
20
+ }
21
+ }
@@ -0,0 +1,18 @@
1
+ import { YakuContext } from '../YakuContext';
2
+ import { YakuCheckerBase } from '../YakuCheckerBase';
3
+
4
+
5
+ export class TanyaoChecker extends YakuCheckerBase{
6
+ protected yakuName: string = "断么九";
7
+
8
+ constructor(context: YakuContext){
9
+ super(context);
10
+ this.hanMenzen = 1;
11
+ this.hanFuro = 1;
12
+ }
13
+
14
+ protected isSatisfied(): boolean {
15
+ const allTiles = this.getAllTiles();
16
+ return allTiles.every(h => h.isChuchanHai()) && (this.context.ctx.kuitan || this.isMenzen());
17
+ }
18
+ }
@@ -0,0 +1,17 @@
1
+ import { YakuContext } from '../YakuContext';
2
+ import { YakuCheckerBase } from '../YakuCheckerBase';
3
+
4
+
5
+ export class ToitoiChecker extends YakuCheckerBase{
6
+ protected yakuName: string = "対々和";
7
+
8
+ constructor(context: YakuContext){
9
+ super(context);
10
+ this.hanMenzen = 2;
11
+ this.hanFuro = 2;
12
+ }
13
+
14
+ protected isSatisfied(): boolean {
15
+ return this.countKotsu() === 4;
16
+ }
17
+ }
@@ -0,0 +1,22 @@
1
+ import { YakuContext } from '../YakuContext';
2
+ import { YakuCheckerBase } from '../YakuCheckerBase';
3
+ import { IMentsu } from '../../IMentsu';
4
+ import { MentsuAnalyzer } from '../../MentsuAnalyzer';
5
+
6
+ export class YakuhaiChecker extends YakuCheckerBase{
7
+ protected yakuName: string;
8
+ private targetHai: number;
9
+
10
+ constructor(context: YakuContext, targetHai: number, yakuName: string){
11
+ super(context);
12
+ this.targetHai = targetHai;
13
+ this.yakuName = yakuName;
14
+ this.hanMenzen = 1;
15
+ this.hanFuro = 1;
16
+ }
17
+
18
+ protected isSatisfied(): boolean {
19
+ const allMentsu: IMentsu[] = new MentsuAnalyzer(this.context.block.getBlockHais(), this.context.melds).getAll();
20
+ return allMentsu.some(mentsu => mentsu.isKotsuOrKantsu() && mentsu.containsHai(this.targetHai));
21
+ }
22
+ }
@@ -0,0 +1,11 @@
1
+ import { YakuCheckerBase } from '../YakuCheckerBase';
2
+
3
+
4
+ export class ChinrotoChecker extends YakuCheckerBase{
5
+ protected yakuName: string = "清老頭";
6
+
7
+ protected isSatisfied(): boolean {
8
+ const allTiles = this.getAllTiles();
9
+ return allTiles.every(h => h.isRoutouHai());
10
+ }
11
+ }
@@ -0,0 +1,16 @@
1
+ import { ExtendedYakumanChecker } from './ExtendedYakumanChecker';
2
+ import { YakuContext } from '../YakuContext';
3
+ import { ChurenChecker } from './ChurenChecker';
4
+ import { YakuCheckerBase } from '../YakuCheckerBase';
5
+
6
+ export class Churen9Checker extends ExtendedYakumanChecker{
7
+ protected yakuName: string = "純正九蓮宝燈";
8
+ protected baseChecker: YakuCheckerBase;
9
+ protected requiredMachiCount: number;
10
+
11
+ constructor(context: YakuContext){
12
+ super(context);
13
+ this.baseChecker = new ChurenChecker(context);
14
+ this.requiredMachiCount = 9;
15
+ }
16
+ }
@@ -0,0 +1,31 @@
1
+ import { YakuCheckerBase } from '../YakuCheckerBase';
2
+ import { ChinitsuChecker } from '../normal/ChinitsuChecker';
3
+
4
+
5
+ export class ChurenChecker extends YakuCheckerBase{
6
+ protected yakuName: string = "九蓮宝燈";
7
+
8
+ protected isSatisfied(): boolean {
9
+ const chinitsuChecker = new ChinitsuChecker(this.context);
10
+ if(!chinitsuChecker.isChinitsu()) return false;
11
+ if(!this.isMenzen()) return false;
12
+
13
+ const count = new Array(9).fill(0);
14
+ const hais = this.context.hais.map(h => h.clone());
15
+ hais.forEach(h => count[h.num - 1]++);
16
+
17
+ //1と9は3枚以上
18
+ const hasEnoughTerminals = count[0] >= 3 && count[8] >= 3;
19
+ if(!hasEnoughTerminals) return false;
20
+ //2から8は1枚以上
21
+ for(let i = 1; i <= 7; i++){
22
+ if(count[i] < 1) return false;
23
+ }
24
+
25
+ return true;
26
+ }
27
+
28
+ public isChuren(): boolean {
29
+ return this.isSatisfied();
30
+ }
31
+ }
@@ -0,0 +1,14 @@
1
+ import { YakuCheckerBase } from '../YakuCheckerBase';
2
+
3
+
4
+ export class DaisangenChecker extends YakuCheckerBase{
5
+ protected yakuName: string = "大三元";
6
+
7
+ protected isSatisfied(): boolean {
8
+ const {foundTargets, mentsuCount, jantoCount} = this.countTargetBlocks(this.context.block, [32,33,34]);
9
+
10
+ if(foundTargets.size !== 3) return false;
11
+
12
+ return mentsuCount === 3 && jantoCount === 0;
13
+ }
14
+ }
@@ -0,0 +1,21 @@
1
+ import { YakuCheckerBase } from '../YakuCheckerBase';
2
+ import { YakuContext } from '../YakuContext';
3
+
4
+
5
+ export class DaisushiChecker extends YakuCheckerBase{
6
+ protected yakuName: string = "大四喜";
7
+
8
+ constructor(context: YakuContext){
9
+ super(context);
10
+ this.hanMenzen = 26;
11
+ this.hanFuro = 26;
12
+ }
13
+
14
+ protected isSatisfied(): boolean {
15
+ const {foundTargets, mentsuCount, jantoCount} = this.countTargetBlocks(this.context.block, [28,29,30,31]);
16
+
17
+ if(foundTargets.size !== 4) return false;
18
+
19
+ return mentsuCount === 4 && jantoCount === 0;
20
+ }
21
+ }
@@ -0,0 +1,18 @@
1
+ import { YakuCheckerBase } from '../YakuCheckerBase';
2
+ import { YakuContext } from '../YakuContext';
3
+
4
+ export abstract class ExtendedYakumanChecker extends YakuCheckerBase{
5
+ protected abstract baseChecker: YakuCheckerBase;
6
+ protected abstract requiredMachiCount: number;
7
+
8
+ constructor(context: YakuContext){
9
+ super(context);
10
+ this.hanMenzen = 26;
11
+ this.hanFuro = 26;
12
+ }
13
+
14
+ public isSatisfied(): boolean {
15
+ if(!this.baseChecker.check()) return false;
16
+ return this.calculateMachiCount() === this.requiredMachiCount;
17
+ }
18
+ }
@@ -0,0 +1,16 @@
1
+ import { ExtendedYakumanChecker } from './ExtendedYakumanChecker';
2
+ import { YakuContext } from '../YakuContext';
3
+ import { KokushiChecker } from './KokushiChecker';
4
+ import { YakuCheckerBase } from '../YakuCheckerBase';
5
+
6
+ export class Kokushi13Checker extends ExtendedYakumanChecker{
7
+ protected yakuName: string = "国士無双13面待ち";
8
+ protected baseChecker: YakuCheckerBase;
9
+ protected requiredMachiCount: number;
10
+
11
+ constructor(context: YakuContext){
12
+ super(context);
13
+ this.baseChecker = new KokushiChecker(context);
14
+ this.requiredMachiCount = 13;
15
+ }
16
+ }
@@ -0,0 +1,15 @@
1
+ import { YakuCheckerBase } from '../YakuCheckerBase';
2
+ import { BlockType } from '../../MahjongConsts';
3
+
4
+ export class KokushiChecker extends YakuCheckerBase{
5
+ protected yakuName: string = "国士無双";
6
+
7
+ protected isSatisfied(): boolean {
8
+ if(!this.isMenzen()) return false;
9
+ return this.context.block.getBlockHais().some(b => b.getType() === BlockType.KOKUSHI);
10
+ }
11
+
12
+ public isKokushi(): boolean {
13
+ return this.isSatisfied();
14
+ }
15
+ }
@@ -0,0 +1,16 @@
1
+ import { YakuCheckerBase } from '../YakuCheckerBase';
2
+
3
+ export class RyuisoChecker extends YakuCheckerBase{
4
+ protected yakuName: string = "緑一色";
5
+
6
+ protected isSatisfied(): boolean {
7
+ const greenNums = new Set([20, 21, 22, 24, 26, 33]);
8
+
9
+ const allTiles = [
10
+ ...this.context.hais,
11
+ ...this.context.melds.flatMap(m => m.getHais())
12
+ ];
13
+
14
+ return allTiles.every(h => greenNums.has(h.getId()));
15
+ }
16
+ }
@@ -0,0 +1,13 @@
1
+ import { YakuCheckerBase } from '../YakuCheckerBase';
2
+
3
+ export class ShosushiChecker extends YakuCheckerBase{
4
+ protected yakuName: string = "小四喜";
5
+
6
+ protected isSatisfied(): boolean {
7
+ const {foundTargets, mentsuCount, jantoCount} = this.countTargetBlocks(this.context.block, [28,29,30,31]);
8
+
9
+ if(foundTargets.size !== 4) return false;
10
+
11
+ return mentsuCount === 3 && jantoCount === 1;
12
+ }
13
+ }
@@ -0,0 +1,14 @@
1
+ import { YakuCheckerBase } from '../YakuCheckerBase';
2
+
3
+ export class SuankoChecker extends YakuCheckerBase{
4
+ protected yakuName: string = "四暗刻";
5
+
6
+ protected isSatisfied(): boolean {
7
+ if(!this.isMenzen()) return false;
8
+ return this.countAnko() === 4;
9
+ }
10
+
11
+ public isSuanko(): boolean {
12
+ return this.isSatisfied();
13
+ }
14
+ }
@@ -0,0 +1,28 @@
1
+ import { YakuCheckerBase } from '../YakuCheckerBase';
2
+ import { BlockType } from '../../MahjongConsts';
3
+ import { SuankoChecker } from './SuankoChecker';
4
+ import { YakuContext } from '../YakuContext';
5
+
6
+
7
+ export class SuankoTankiChecker extends YakuCheckerBase{
8
+ protected yakuName: string = "四暗刻単騎";
9
+
10
+ constructor(context: YakuContext){
11
+ super(context);
12
+ this.hanMenzen = 26;
13
+ this.hanFuro = 26;
14
+ }
15
+
16
+ protected isSatisfied(): boolean {
17
+ const base = new SuankoChecker(this.context)
18
+ if(!base.isSuanko()) return false;
19
+
20
+ for(const blockhais of this.context.block){
21
+ if(blockhais.getType() === BlockType.JANTO){
22
+ if(blockhais.getHais().some(h => h.getId() == this.context.ctx.agariHai.getId())) return true;
23
+ }
24
+ }
25
+
26
+ return false;
27
+ }
28
+ }
@@ -0,0 +1,9 @@
1
+ import { YakuCheckerBase } from '../YakuCheckerBase';
2
+
3
+ export class SukantsuChecker extends YakuCheckerBase{
4
+ protected yakuName: string = "四槓子";
5
+
6
+ protected isSatisfied(): boolean {
7
+ return this.countKantsu() === 4;
8
+ }
9
+ }
@@ -0,0 +1,10 @@
1
+ import { YakuCheckerBase } from '../YakuCheckerBase';
2
+
3
+ export class TsuisoChecker extends YakuCheckerBase{
4
+ protected yakuName: string = "字一色";
5
+
6
+ protected isSatisfied(): boolean {
7
+ const allTiles = this.getAllTiles();
8
+ return allTiles.every(h => h.isJihai());
9
+ }
10
+ }
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "mahjong_engine",
3
+ "version": "1.0.0",
4
+ "description": "mahjong",
5
+ "homepage": "https://github.com/daicharn/IsTheOrderaMahjong#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/daicharn/IsTheOrderaMahjong/issues"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/daicharn/IsTheOrderaMahjong.git"
12
+ },
13
+ "license": "ISC",
14
+ "author": "",
15
+ "main": "dist/index.js",
16
+ "types": "dist/index.d.ts",
17
+ "scripts": {
18
+ "test": "jest",
19
+ "coverage": "jest --coverage",
20
+ "build": "npx tsc && npm run copy-assets",
21
+ "copy-assets": "xcopy images dist\\images /E /I /Y"
22
+ },
23
+ "devDependencies": {
24
+ "@types/jest": "^30.0.0",
25
+ "jest": "^30.4.2",
26
+ "ts-jest": "^29.4.12"
27
+ }
28
+ }
@@ -0,0 +1,44 @@
1
+ import { YakuChecker } from "../modules/yaku/YakuChecker";
2
+ import { FuSpec, TehaiCase } from './testConsts';
3
+ import { YakuContext } from '../modules/yaku/YakuContext';
4
+ import { TehaiCaseRunner } from './tehaiCaseRunner';
5
+ import { FuCalculator } from "../modules/tensuu/FuCalculator";
6
+ import { caseFu } from './tensuu/fu';
7
+ import { FuDetail } from "../modules/tensuu/FuDetail";
8
+
9
+ type fuList = FuSpec[][];
10
+
11
+ function sortFuspecs(specs: fuList): FuSpec[][] {
12
+ const sortedSpecs: FuSpec[][] = [];
13
+ for(const spec of specs){
14
+ sortedSpecs.push([...spec].sort((a, b) => a.name.localeCompare(b.name)));
15
+ }
16
+ return sortedSpecs;
17
+ }
18
+
19
+ const testcases: TehaiCase<fuList>[] = [];
20
+ caseFu.forEach(casefu => testcases.push(casefu));
21
+
22
+ testcases.forEach(testcase => {
23
+ describe(testcase.desc, () => {
24
+ test(testcase.name, () => {
25
+ const fuList: FuDetail[][] = [];
26
+ const runner: TehaiCaseRunner<fuList> = new TehaiCaseRunner(testcase);
27
+ const blocks = runner.blocks;
28
+ blocks.forEach((block) => {
29
+ const context = new YakuContext(runner.hand, runner.ctx, block);
30
+ const yaku_map = new YakuChecker(context).check();
31
+ fuList.push(new FuCalculator(context, yaku_map).calcFu());
32
+ });
33
+ const expected: FuDetail[][] = [];
34
+ for(const specs of testcase.expected){
35
+ const details: FuDetail[] = [];
36
+ for(const spec of specs){
37
+ details.push(new FuDetail(spec.name, spec.fu, spec.mentsu));
38
+ }
39
+ expected.push(details);
40
+ }
41
+ expect(sortFuspecs(fuList)).toEqual(sortFuspecs(expected));
42
+ });
43
+ });
44
+ });