{"id":44885387,"url":"https://github.com/tomohxx/shanten-number","last_synced_at":"2026-04-01T22:54:07.347Z","repository":{"id":234218832,"uuid":"150951691","full_name":"tomohxx/shanten-number","owner":"tomohxx","description":"A tool for calculating the shanten number in Japanese mahjong.","archived":false,"fork":false,"pushed_at":"2025-10-13T09:46:25.000Z","size":2262,"stargazers_count":42,"open_issues_count":1,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-13T11:02:24.478Z","etag":null,"topics":["cpp","cpp20","japanese-mahjong","mahjong","shanten-number"],"latest_commit_sha":null,"homepage":"https://tomohxx.github.io/mahjong-algorithm-book/srf/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tomohxx.png","metadata":{"files":{"readme":"README.ja.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-09-30T09:17:23.000Z","updated_at":"2025-10-13T09:46:29.000Z","dependencies_parsed_at":"2025-06-10T20:32:02.046Z","dependency_job_id":"093fac6f-be6c-4d0c-954b-8e2cd0f54252","html_url":"https://github.com/tomohxx/shanten-number","commit_stats":null,"previous_names":["tomohxx/shanten-number"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/tomohxx/shanten-number","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomohxx%2Fshanten-number","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomohxx%2Fshanten-number/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomohxx%2Fshanten-number/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomohxx%2Fshanten-number/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tomohxx","download_url":"https://codeload.github.com/tomohxx/shanten-number/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomohxx%2Fshanten-number/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29551248,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-17T14:33:00.708Z","status":"ssl_error","status_checked_at":"2026-02-17T14:32:58.657Z","response_time":100,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","cpp20","japanese-mahjong","mahjong","shanten-number"],"created_at":"2026-02-17T17:17:10.798Z","updated_at":"2026-04-01T22:54:07.334Z","avatar_url":"https://github.com/tomohxx.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Shanten Number\r\n\r\nこのプログラムに使用しているアルゴリズムはシャンテン数を正確に計算できることが証明されています.\r\n\r\n[Read this in English.](README.md)\r\n\r\n## シャンテン数\r\n\r\nシャンテン数はテンパイまでに必要な最小のツモ回数のことです.\r\n\r\n## ビルド\r\n\r\n### デバッグモード\r\n\r\n```\r\n$ mkdir build\r\n$ cd build\r\n$ cmake .. -DCMAKE_BUILD_TYPE=Debug\r\n$ make\r\n```\r\n\r\n### リリースモード\r\n\r\n```\r\n$ mkdir build\r\n$ cd build\r\n$ cmake .. -DCMAKE_BUILD_TYPE=Release\r\n$ make\r\n```\r\n\u003e [!NOTE]\r\n\u003e C++20以上に対応したコンパイラが必要です.\r\n\r\n### コンパイルオプション\r\n\r\n#### `-DENABLE_NYANTEN`\r\n\r\nテーブルの検索アルゴリズムにCryolite氏のnyanten[^1][^2]で使用されている最小完全ハッシュ関数を使用します. このオプションを有効にすることでテーブルのサイズを小さくできます. ただし, シャンテン数を計算できる手牌の枚数が14枚以下に制限されます.\r\n\r\n[^1]: https://github.com/Cryolite/nyanten\r\n[^2]: https://www.slideshare.net/slideshow/a-fast-and-space-efficient-algorithm-for-calculating-deficient-numbers-a-k-a-shanten-numbers-pptx/269706666\r\n\r\n#### `-DFIX_RANDOM_SEED`\r\n\r\nサンプルプログラムで使用する乱数のシードを固定します.\r\n\r\n### テーブルの作成\r\n\r\nシャンテン数計算に必要なパラメータテーブルを構築します. `index_h.bin`, `index_s.bin`を作成します.\r\n\r\n```\r\n$ ./mkind\r\n```\r\n\r\n\u003e [!TIP]\r\n\u003e Intel Threading Building Blocks (`TBB`)が利用可能な場合は自動でリンクされ並列ビルドが有効になります.\r\n\r\n## 使用方法\r\n\r\n1. 手牌を表す`std::array\u003cint, 34\u003e`配列を用意します.\r\n   - `n`番目の要素が`n`番目の牌の枚数を格納します.\r\n\r\n      |        | 1       | 2       | 3       | 4       | 5       | 6       | 7       | 8       | 9       |\r\n      | :----- | :------ | :------ | :------ | :------ | :------ | :------ | :------ | :------ | :------ |\r\n      | マンズ | 0 (1m)  | 1 (2m)  | 2 (3m)  | 3 (4m)  | 4 (5m)  | 5 (6m)  | 6 (7m)  | 7 (8m)  | 8 (9m)  |\r\n      | ピンズ | 9 (1p)  | 10 (2p) | 11 (3p) | 12 (4p) | 13 (5p) | 14 (6p) | 15 (7p) | 16 (8p) | 17 (9p) |\r\n      | ソーズ | 18 (1s) | 19 (2s) | 20 (3s) | 21 (4s) | 22 (5s) | 23 (6s) | 24 (7s) | 25 (8s) | 26 (9s) |\r\n      | 字牌   | 27 (東) | 28 (南) | 29 (西) | 30 (北) | 31 (白) | 32 (発) | 33 (中) |         |         |\r\n\r\n   - 例えば123m245779p13555zのような手牌の場合, 以下の配列を定義します.\r\n\r\n      ```cpp\r\n      std::array\u003cint, 34\u003e hand = {\r\n         1, 1, 1, 0, 0, 0, 0, 0, 0, // Manzu\r\n         0, 1, 0, 1, 1, 0, 2, 0, 1, // Pinzu\r\n         0, 0, 0, 0, 0, 0, 0, 0, 0, // Souzu\r\n         1, 0, 1, 0, 3, 0, 0        // Jihai\r\n      };\r\n      ```\r\n\r\n1. シャンテン数を計算します. 各メソッドは**シャンテン数+1**の値を返します.\r\n   - 一般形(`m`面子一雀頭):\r\n      ```cpp\r\n      int Calsht::calc_lh(const std::array\u003cint, 34\u003e\u0026 t, int m, bool three_player = false) const\r\n      ```\r\n   - 七対子:\r\n      ```cpp\r\n      int Calsht::calc_sp(const std::array\u003cint, 34\u003e\u0026 t, bool three_player = false) const\r\n      ```\r\n   - 国士無双:\r\n      ```cpp\r\n      int Calsht::calc_to(const std::array\u003cint, 34\u003e\u0026 t) const\r\n      ```\r\n   - 標準形:\r\n      ```cpp\r\n      std::tuple\u003cint, unsigned int\u003e Calsht::operator()(const std::array\u003cint, 34\u003e\u0026 t,\r\n                                                       int m,\r\n                                                       unsigned int mode,\r\n                                                       bool check_hand = false,\r\n                                                       bool three_player = false) const\r\n      ```\r\n\u003e [!NOTE]\r\n\u003e 通常, `m`には手牌の枚数を3で割った値を代入します.\r\n\r\n\u003e [!NOTE]\r\n\u003e `mode`にはどのあがりパターンに対してシャンテン数を計算するかを指定します. 一般形の場合は1, 七対子の場合は2, 国士無双の場合は4です. 複数のあがりパターンに対してシャンテン数を計算する場合はそれらの論理和を指定します.\r\n\r\n\u003e [!NOTE]\r\n\u003e このメソッドはシャンテン数の最小値とそのあがりパターンのタプルを返します. あがりパターンは`mode`と同じように表されます.\r\n\r\n\u003e [!NOTE]\r\n\u003e `check_hand`を`true`にすると手牌のバリデーションを行います. `three_player`を`true`にすると三人麻雀でのシャンテン数を計算します.\r\n\r\n例として, 先に定義した手牌のシャンテン数を計算します.\r\n\r\n```cpp\r\n#include \"calsht.hpp\"\r\n#include \u003carray\u003e\r\n#include \u003cfilesystem\u003e\r\n#include \u003ciostream\u003e\r\n\r\nint main()\r\n{\r\n   // Set the location of shanten tables\r\n   Calsht calsht(std::filesystem::current_path());\r\n\r\n   std::array\u003cint, 34\u003e hand = {\r\n      1, 1, 1, 0, 0, 0, 0, 0, 0, // manzu\r\n      0, 1, 0, 1, 1, 0, 2, 0, 1, // pinzu\r\n      0, 0, 0, 0, 0, 0, 0, 0, 0, // souzu\r\n      1, 0, 1, 0, 3, 0, 0        // jihai\r\n   };\r\n\r\n   const auto [sht, mode] = calsht(hand, 4, 7);\r\n\r\n   std::cout \u003c\u003c sht \u003c\u003c std::endl;\r\n   std::cout \u003c\u003c mode \u003c\u003c std::endl;\r\n\r\n   return 0;\r\n}\r\n```\r\n出力:\r\n```\r\n3\r\n1\r\n```\r\n\r\n## 実行例\r\n\r\n手牌をランダムに生成し, シャンテン数ごとの出現率とシャンテン数の期待値を計算します.\r\n\r\n```\r\n$ ./example 14 100000000 0\r\n  -1         278    0.000278\r\n   0       69553    0.069553\r\n   1     2334287    2.334287\r\n   2    19502040   19.502040\r\n   3    43925782   43.925782\r\n   4    28516861   28.516861\r\n   5     5496101    5.496101\r\n   6      155098    0.155098\r\nNumber of Tiles         14\r\nNumber of Hands         100000000\r\nExpected Value          3.155940\r\n```\r\n\r\n## ライセンス\r\n\r\nGNU Lesser General Public License v3.0.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomohxx%2Fshanten-number","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomohxx%2Fshanten-number","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomohxx%2Fshanten-number/lists"}