これは、ハンドの準備ができているかどうかの判断に関する以前の質問の補足です。
麻雀のルールの知識は優れていますが、この質問を理解するには、ポーカーまたは ROMME ベースのバックグラウンドでも十分です。
麻雀では 14 枚の牌 (牌はポーカーのカードのようなもの) が 4 セットとペアに配置されます。ストレート (「123」) は常に正確に 3 枚のタイルを使用します。同じ種類のセット (「111」) もちょうど 3 枚のタイルで構成されています。これにより、合計 3 * 4 + 2 = 14 タイルになります。
カンや十三の孤児など、ここでは関係のないさまざまな例外があります。色と値の範囲 (1 ~ 9) もアルゴリズムにとって重要ではありません。
ハンドは 13 枚のタイルで構成され、自分の番になるたびに新しいタイルを選択し、任意のタイルを破棄する必要があるため、13 枚のタイルにとどまります (新しく選択したタイルを使用して勝つことができる場合を除く)。
4 セットとペアを形成するように配置できるハンドが「準備完了」です。牌を 1 枚だけ交換する手札を「てんぱい」または「1 から準備ができている」といいます。他の手札には、天牌になるために何枚の牌を交換する必要があるかを表すシャンテン数があります。したがって、シャンテン数が 1 の手札では、1 枚の牌をテンパイにする必要があります (したがって、2 枚の牌を用意する必要があります)。シャンテン数が 5 の手札は、テンパイになるために 5 枚の牌が必要です。
手のシャンテン数を計算しようとしています。何時間もグーグルで検索し、このトピックに関する複数の記事や論文を読んだ後、これは未解決の問題のようです (ブルート フォース アプローチを除く)。私が見つけた最も近いアルゴリズムは偶然に頼っていました。つまり、100% の確率で正しいシャンテン数を検出できませんでした。
ルール
実際のルール (簡略化されたもの) について少し説明し、次に、このタスクに取り組む方法について考えます。麻雀では、「マン」「ピン」「ソウ」と呼ばれるカードゲームのような通常の 3 つの色 (エース、ハートなど) の 4 つの色があります。これらの色はそれぞれ 1 から 9 まであり、ストレートや同種のグループを形成するために使用できます。4番目の色は「名誉」と呼ばれ、同じ種類のグループにのみ使用できますが、ストレートには使用できません. 7つの栄誉は「E、S、W、N、R、G、B」と呼ばれます。
テンパイ ハンドの例を見てみましょう2p, 3p, 3p, 3p, 3p, 4p, 5m, 5m, 5m, W, W, W, E
。次に を選択しE
ます。これは完全な麻雀ハンド (準備完了) で、2 ~ 4 ピンのストリート (ピンはストレートに使用できることを思い出してください)、3 ピンのトリプル、5 人のトリプル、W トリプル、E ペアで構成されています。
元の手札を に少し変更すると2p, 2p, 3p, 3p, 3p, 4p, 5m, 5m, 5m, W, W, W, E
、1 シャンテンの手札になりました。つまり、天牌になるには追加のタイルが必要です。この場合、2p を 3p に交換すると、てんぱいに戻るので、3p と E を引いて勝ちです。
1p, 1p, 5p, 5p, 9p, 9p, E, E, E, S, S, W, W
2シャンテンのハンドです。完成したトリプレットが1つとペアが5つあります。最後に 1 つのペアが必要なので、1p、5p、9p、S、または W のいずれかを選択したら、残りのペアの 1 つを破棄する必要があります。例: 1 ピンをピックし、W を破棄します。ハンドは現在 1 シャンテンにあり、次のようになります1p, 1p, 1p, 5p, 5p, 9p, 9p, E, E, E, S, S, W
。次に、5p、9p、または S のいずれかを待ちます。5p を選択して残りの W を破棄すると仮定すると、次のようになります1p, 1p, 1p, 5p, 5p, 5p, 9p, 9p, E, E, E, S, S
。このハンドはテンパイで、9 ピンまたは S でコンプリートできます。
このテキストがさらに長くなるのを避けるために、ウィキペディアでより多くの例を読んだり、Google でさまざまな検索結果の 1 つを使用したりできます。ただし、それらはすべてもう少し技術的なものなので、上記の説明で十分であることを願っています.
アルゴリズム
述べたように、ハンドのシャンテン数を計算したいと思います。私のアイデアは、タイルを色に応じて 4 つのグループに分割することでした。次に、すべての牌がそれぞれのグループ内のセットに分類され、栄誉グループのトリプレット、ペア、またはシングル タイル、または 3 つの通常グループのストライトになります。完成したセットは無視されます。ペアがカウントされ、最終的な数が減ります (最終的に 1 ペアが必要です)。この数に単一のタイルが追加されます。最後に、数字を 2 で割ります (天牌に近づく良い牌を選ぶたびに、別の不要な牌を取り除くことができるため)。
しかし、このアルゴリズムが正しいことを証明することはできませんし、近距離に多くの牌を含む難しいグループにストレートを組み込むことにも苦労しています。あらゆる種類のアイデアが高く評価されます。私は .NET で開発していますが、疑似コードや読み取り可能な言語も歓迎します。