我打麻将の研究室

卓組問題

目次

概要

麻雀大会の卓組問題を考える。 最も一般化された卓組問題は「Ni人のプレイヤーからなるチーム i (0 ≦ i < n) による麻雀大会において、どの異なる2つのチームからプレイヤーを1人ずつ選んでも、その間の同卓回数が [m..M] であるような卓組を求めよ」と定式化される。 ただし、麻雀大会は同時性 (全ラウンドで全プレイヤーがただ1つの卓について同時にプレイすること) や 斉次性 (全プレイヤーが同じ回数をプレイすること) を必ずしも必要としないものとする。

用語の定義

再同卓
同卓回数が2以上であること。
n-play (n = 1, 2, 3, 4)
n人のプレイヤーが同卓すること。
n-replay (n = 2, 3, 4)
1つの大会においてn人のプレイヤーが再同卓すること。 ラウンド数が小さければしばしば 2-replay のない大会を構成可能である。 3-replay のある大会は好ましくない。 4-replay のある大会を構成することはほとんどない。
オポーネント
チーム戦においては自分の属するチーム以外のチームに属するプレイヤー、個人戦においては自分以外のプレイヤー。
オポーネントチーム (/ペア/etc)
チーム戦において、自分の属するチーム以外のチーム。 あるオポーネントチームとの同卓回数とは、あるオポーネントチームに対して、そのチームに属するすべてのプレイヤーとの同卓回数の和を指す。

個人戦

個人戦のうち限られたいくつかの場合においては、全プレイヤーが同時に同じ回数をプレイし、全プレイヤーが全オポーネントと定数回数ずつ対戦する卓組が知られている。

8プレイヤー7ラウンド
28組すべての2-playを3回ずつ尽くし、3-replayはない。
12プレイヤー11ラウンド
66組すべての2-playを3回ずつ尽くし、11組 (0番プレイヤー以外のプレイヤーにとって3組ずつ) の3-replayが存在する。
16プレイヤー5ラウンド
120組すべての2-playを1回ずつ尽くす。

4チーム戦, 4人チーム戦

4チーム戦とは、プレイヤーを卓数と同じ人数からなる4つのチームに分けて行うチーム戦である。 現実の運営においては、ラウンド数が十分に少ない (全オポーネントと対戦することが必要でない) 個人戦の麻雀大会を4チーム戦と扱うことがある。 4チーム戦はラウンド数が4の倍数であって座位を予め指定する大会の実際の運営にも向く。 4人チーム戦とは、プレイヤーを卓数と同じ数の4人からなるチームにわけて行うチーム戦である。 現実の運営においては、ラウンド数が十分に少ない4人チーム戦の麻雀大会を、4チーム戦から最初のラウンドを除いたものと扱うことがある。

円順列解: テーブル数5-32
各チームにおいてプレイヤーの座位が円順列として一定であるような解のうち、得られたもののうちラウンド数が最大であるものをリストにした。 1組のデータセットは5行から構成され、最初の行はテーブル数とラウンド数を、次の4行は各チームの座位を表す。 各ラウンドで各プレイヤーのつくべきテーブルの番号は、テーブル数を法として、チーム座位とチーム内のプレイヤー番号との和によって与えられる。
ソースコード (Python)
4チーム戦の卓組生成に使用した Python によるソースコード。 チームごとに各ラウンドの卓組を決定するごとに再同卓をチェックし、問題がなければ再帰している。 得られた卓組を返すのではなく出力して終了するようになっているが、この部分は修正予定である。
ソースコード (C++)
4チーム戦の卓組生成に使用した C++ によるソースコード。 Python 版の実行速度にやや不満があったので移植した。 卓組の生成には next_permutation を使用している。 再同卓チェックに引っ掛かったらそれより後の卓組を reverse してから next_permutation を呼び出すことによって、再同卓ラウンド以降を変更している。 これによって簡単な記述 (4人ゲームであることに特化しているため、再帰を使って書くのが自然な場面で2重ループを使ったり、チェックの関数を分けたりしているが) と高速な探索を両立できる。 コンパイルして実行すると、テーブル数をユーザへ尋ねる。 入力が0なら終了し、そうでなければラウンド数をユーザへ尋ねる。 与えられたテーブル数・ラウンド数に合致した卓組が可能ならば出力する。 そうでなければダミー (一目で再同卓の存在を確かめられる) 卓組を出力する。

3人チーム戦

3人8チーム6テーブル7ラウンドの完全解を掲載する。

8トリオ7ラウンド
252組すべてのオポーネントとの2-playを1回ずつ尽くす。

ペア戦

テーブル数が十分に多くラウンド数が十分に少ないペア戦には、ペア間の再同卓を完全に防ぐ方法が存在する。

8ペア7ラウンド
オポーネントペアとの2-playを3回ずつ尽くし、そのうち1回はreplayがなく, 2回は2-replayである。3-replayは存在しない。
36+ペア4ラウンド, 座位指定
座位の指定された4ラウンドのペア戦。36を超える任意のペア数に使用できる。

一般人数チーム戦

一般人数のチーム戦においては、厳密解のある条件を得ていない。

ツール

以下のツールは Microsoft Visual Basic 2008 Express Edition で開発したため、実行には .NET Framework を要する。

同卓チェッカー

卓組生成プログラムで使用している同卓チェッカーを切り出して公開する: 同卓チェッカー 入力例 出力例

入力 (ボタンの上のテキストボックス) の各行は、ある卓であるラウンドにプレイするプレイヤーの番号をタブ区切りで並べたものとする。 出力の第1行および第1列はヘッダである。 該当する番号のプレイヤー同士が同卓した回数を (ボタンの下のテキストボックスへ) 出力する。 同卓チェッカーは入力エラー (数字とタブと改行以外の文字列がある時の動作)・大会の同時性・斉次性をチェックしない。 したがって、麻雀以外の一般人数によるゲームの大会構成や「大将戦」を採用する大会にも応用が可能である。

卓組コンバータ

生成された卓組からプレイヤー用の卓組データを作成するコンバータを公開する: 卓組コンバータ 入力例 出力例

入力は各ラウンドを表すブロックからなる。 ラウンドとラウンドとの間にはちょうど1つの空行を必要とする。 各ラウンドは卓数と同じ数の行からなり、各行はある卓であるラウンドにプレイするプレイヤーの番号をタブ区切りで並べたものとする。 座位をチェックするとこれは順不同ではなくなり、左から順に東南西北となる。 出力の第1列はヘッダである。 該当する番号のプレイヤーが各ラウンドにつく卓 (座位をチェックした場合は卓と座位) を示す。