牌効率(向聴・受け入れ・何切る)

GET/api/v1/analyze

手牌の向聴数と受け入れを返す。ツモ前の形(3n+1 枚)なら有効牌と残り枚数、ツモ後の形(3n+2 枚)なら打牌ごとの向聴・受け入れを、良い順に並べて返す。何切る問題の答え合わせ、Bot の牌効率の表示、待ちの確かめに使えます。

ブラウザで試す

本番の API をそのまま呼びます。

萬子
1
2
1
筒子
1
1
1
索子
1
1
1
1
1
字牌
2
GET /api/v1/analyze?tiles=2334m456p3478s55z6s

パラメータ

知らないパラメータや、同じパラメータの 2 回目は誤りとして返します(書き間違いを黙って無視しないため)。

名前型説明例
tiles必須牌手牌。副露を除いて 1〜14 枚。牌の書き方: 数字のあとに m(萬子)・p(筒子)・s(索子)・z(字牌。1 東 2 南 3 西 4 北 5 白 6 發 7 中)。0 は赤五(0m・0p・0s)。123m456p のようにまとめても、1m2m3m と 1 枚ずつでもよい2334m456p3478s55z6s
melds副露副露(鳴いた面子)。種類:牌 をカンマで区切る。種類は pon(ポン)・chi(チー)・kan(大明槓)・kakan(加槓)・ankan(暗槓)。例: pon:555z,chi:345s。副露の牌は残り枚数から自動で引くpon:555z
visible牌ほかに見えている牌(河・ドラ表示牌など)。受け入れの残り枚数から引く1z2z9m

応答の例

上の例のリクエストの、実際の応答です。

リクエスト
GET https://janten.net/api/v1/analyze?tiles=2334m456p3478s55z6s
  • phase は手牌の枚数で決まります。ツモ前の形(3n+1 枚)は draw で ukeire・waits を、ツモ後の形(3n+2 枚)は discard で打牌ごとの discards を返します。2345m のような短い形も受けます
  • discards は向聴が小さい順、同じなら受け入れが多い順です。赤五は普通の五と同じ打牌にまとめ、hasRed を付けます
  • 受け入れは、手牌・副露・visible に見えている枚数(ツモ後の形では切った牌も)を 4 から引いた残りです。残りが 0 の牌は入れません
  • 待ちは、手牌と副露で 4 枚使った牌を入れません(純カラ)。河などの見えている牌で尽きた待ちは、残り 0 として入れます(空聴が分かるように)
  • 七対子・国士無双の向聴は、副露が無く 13・14 枚のときだけ数えます(それ以外は null)
200 application/json
{
  "tiles": "2334m456p3478s55z6s",
  "phase": "discard",
  "shanten": { "value": 0, "standard": 0, "chiitoitsu": 4, "kokushi": 11 },
  "discards": [
    {
      "discard": "3m",
      "shanten": 0,
      "ukeire": 8,
      "tiles": [
        { "tile": "2s", "remaining": 4 },
        { "tile": "5s", "remaining": 4 }
      ],
      "waits": [
        { "tile": "2s", "remaining": 4 },
        { "tile": "5s", "remaining": 4 }
      ]
    },
    {
      "discard": "3s",
      "shanten": 1,
      "ukeire": 39,
      "tiles": [
        { "tile": "1m", "remaining": 4 },
        { "tile": "2m", "remaining": 3 },
        { "tile": "3m", "remaining": 2 },
        { "tile": "4m", "remaining": 3 },
        { "tile": "5m", "remaining": 4 },
        { "tile": "2s", "remaining": 4 },
        { "tile": "3s", "remaining": 3 },
        { "tile": "4s", "remaining": 3 },
        { "tile": "5s", "remaining": 4 },
        { "tile": "6s", "remaining": 3 },
        { "tile": "9s", "remaining": 4 },
        { "tile": "5z", "remaining": 2 }
      ]
    },
    {
      "discard": "4s",
      "shanten": 1,
      "ukeire": 36,
      "tiles": [
        { "tile": "1m", "remaining": 4 },
        { "tile": "2m", "remaining": 3 },
        { "tile": "3m", "remaining": 2 },
        { "tile": "4m", "remaining": 3 },
        { "tile": "5m", "remaining": 4 },
        { "tile": "1s", "remaining": 4 },
        { "tile": "2s", "remaining": 4 },
        { "tile": "3s", "remaining": 3 },
        { "tile": "4s", "remaining": 3 },
        { "tile": "5s", "remaining": 4 },
        { "tile": "5z", "remaining": 2 }
      ]
    },
    {
      "discard": "2m",
      "shanten": 1,
      "ukeire": 19,
      "tiles": [
        { "tile": "2m", "remaining": 3 },
        { "tile": "3m", "remaining": 2 },
        { "tile": "5m", "remaining": 4 },
        { "tile": "2s", "remaining": 4 },
        { "tile": "5s", "remaining": 4 },
        { "tile": "5z", "remaining": 2 }
      ]
    },
    {
      "discard": "4m",
      "shanten": 1,
      "ukeire": 19,
      "tiles": [
        { "tile": "1m", "remaining": 4 },
        { "tile": "3m", "remaining": 2 },
        { "tile": "4m", "remaining": 3 },
        { "tile": "2s", "remaining": 4 },
        { "tile": "5s", "remaining": 4 },
        { "tile": "5z", "remaining": 2 }
      ]
    },
    {
      "discard": "4p",
      "shanten": 1,
      "ukeire": 15,
      "tiles": [
        { "tile": "4p", "remaining": 3 },
        { "tile": "7p", "remaining": 4 },
        { "tile": "2s", "remaining": 4 },
        { "tile": "5s", "remaining": 4 }
      ]
    },
    {
      "discard": "6p",
      "shanten": 1,
      "ukeire": 15,
      "tiles": [
        { "tile": "3p", "remaining": 4 },
        { "tile": "6p", "remaining": 3 },
        { "tile": "2s", "remaining": 4 },
        { "tile": "5s", "remaining": 4 }
      ]
    },
    {
      "discard": "6s",
      "shanten": 1,
      "ukeire": 15,
      "tiles": [
        { "tile": "2s", "remaining": 4 },
        { "tile": "5s", "remaining": 4 },
        { "tile": "6s", "remaining": 3 },
        { "tile": "9s", "remaining": 4 }
      ]
    },
    {
      "discard": "5z",
      "shanten": 1,
      "ukeire": 12,
      "tiles": [
        { "tile": "3m", "remaining": 2 },
        { "tile": "2s", "remaining": 4 },
        { "tile": "5s", "remaining": 4 },
        { "tile": "5z", "remaining": 2 }
      ]
    },
    {
      "discard": "5p",
      "shanten": 1,
      "ukeire": 11,
      "tiles": [
        { "tile": "5p", "remaining": 3 },
        { "tile": "2s", "remaining": 4 },
        { "tile": "5s", "remaining": 4 }
      ]
    },
    {
      "discard": "7s",
      "shanten": 1,
      "ukeire": 11,
      "tiles": [
        { "tile": "2s", "remaining": 4 },
        { "tile": "5s", "remaining": 4 },
        { "tile": "7s", "remaining": 3 }
      ]
    },
    {
      "discard": "8s",
      "shanten": 1,
      "ukeire": 11,
      "tiles": [
        { "tile": "2s", "remaining": 4 },
        { "tile": "5s", "remaining": 4 },
        { "tile": "8s", "remaining": 3 }
      ]
    }
  ]
}

誤りの応答

RFC 9457 の application/problem+json で返します。param と position(何文字目か)で場所を示します。

type状態いつ
https://janten.net/api#error-invalid-parameter400牌の書き方の誤り・同じ牌 5 枚以上・赤五が 2 枚・枚数が 3n または 15 枚以上・知らないパラメータ
https://janten.net/api#error-rate-limited429IP ごとに 1 分 60 回、または全体で 1 秒 5 回を超えた(Retry-After の秒数だけ待つ)