去年からジン・ラミーというカードゲームで遊ぶようになった。そしてシャッフルに興味を持ち、ヒンズーシャッフルより良いシャッフル手法について検討した。
1. シャッフルの手法
カット
1組の山を2つに分けて、上下を入れ替える。シャッフル後に1回カットする、という使い方をする。1組の山をリング状と考えると、カードの並びは変化しないため、カットだけを繰り返してもシャッフルとしては不十分である。
ヒンズーシャッフル
日本で一般的なシャッフル手法。ときどき手さばきを失敗してカードを撒き散らしてしまう。充分にシャッフルするために延々とヒンズーシャッフルすることがあるが、本当にシャッフルできているか、シミュレーションで確認したい。
ウォッシュシャッフル
カードをテーブルに広げ、手でかき混ぜる。最後にカードを揃えることが手間であり、時間もかかる。
ファローシャッフル
1組の山を2つに分けて端同士を押し付けて、互い違いにかみ合わせる。慣れると1枚づつ互い違いにかみ合わせることは難しくなく、この場合のランダム性は山の分け方だけである。
ディールシャッフル
1組の山から1枚づつ順にいくつかの山に配る。配り終えたら、1組の山にまとめる。隣り合ったカードが離れることが長所である。時間がかかる。並び方にランダム性はない。
2. 理想的なシャッフル
テーブルに52枚のカードを並べる場所を用意する。PCで1~52をランダムに表示しながら、1組の山から順に表示された場所へ置く。52枚を置き終えたら、1組の山にまとめる。ところが52枚を並べるために広いテーブルが必要である。
3. ランダム順に置くディールシャッフル
ディールシャッフルは時間はかかるが、カードの操作は易しく練習する必要はない。そこでディールシャッフルで山に配るとき、ランダムな順番で山に配ったらどうだろうか。以下「ランダムディール」と呼ぶことにする。
4. シミュレーションプログラムについて
カード番号0,1,2,3のカード4枚の並び替えで説明する。カードの並びを配列で表現する。配列の添え字がカード位置、配列の内容がカード番号である。
シャッフル前:カード配列 = [ 0, 1, 2 ,3 ]
シャッフル後:カード配列 = [ 1, 3 ,0, 2 ]
集計用の配列を2次元で、横軸をカード番号、縦軸をカード位置で表現し、内容を出現回数とする。試行1回ごとに集計し、集計配列1[カード番号][カード位置] を +1 する。
カード位置 |
カード番号 |
0 |
1 |
1 |
3 |
2 |
0 |
3 |
2 |
カード番号 |
|||||
0 |
1 |
2 |
3 |
||
カード位置 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
|
2 |
1 |
0 |
0 |
0 |
|
3 |
0 |
0 |
1 |
0 |
次に、シャッフル前の隣合ったカードの位置の変化を調べた。試行1回ごとに、集計配列2[カード番号][距離] を +1 する。
A |
B |
C |
D |
E |
カード番号 |
カード位置 |
A–1の カード番号 |
Cのシャッフル後の カード位置 |
距離 B-D |
0 |
2 |
3 |
1 |
1 |
1 |
0 |
0 |
2 |
-2 |
2 |
3 |
1 |
0 |
2 |
3 |
1 |
2 |
3 |
-1 |
Aカード番号 |
|||||
0 |
1 |
2 |
3 |
||
E距離 |
0 |
0 |
0 |
0 |
0 |
1, -3 |
1 |
0 |
0 |
0 |
|
2, -2 |
0 |
1 |
1 |
0 |
|
3, -1 |
0 |
0 |
0 |
1 |
同様の要領で、シャッフル前の一つ飛びのカード、2つ飛びのカードとのシャッフル後の距離を集計配列3、集計配列4に保存した。
5. 集計結果の可視化
文献1でシャッフルのシミュレーション結果をグレイスケール画像で表現している。これを集計配列1~4を画像1~4に画像化した。
6. シミュレーション結果
3~10は各シャッフル手法を10000回シミュレーションしたものである。
左から画像1~4とする。画像1~4とも、均一になっていることが望ましい。
ヒンズーシャッフルは、切る枚数を4~20の一様分布とし、山がなくなるまで切ったら、1回と数える。ヒンズーシャッフル(3回)は、これを3回繰り返し、試行1回とした。
1 |
シャッフル前のソートされた初期状態 |
2 |
位置10でカットした状態 |
3 |
ランダム:疑似乱数で並び替えた |
4 |
ランダムディール(5山) |
5 |
ランダムディール(10山) |
6 |
ヒンズーシャッフル(3回) |
7 |
ヒンズーシャッフル(10回) |
8 |
ヒンズーシャッフル(20回) |
9 |
カット+ランダムディール(10山)+カット |
10 |
カット+ヒンズーシャッフル(20回)+カット |
次に、隣合ったカードがシャッフル後も隣り合ったままの確率を調べた。画像2で距離=1や距離=51の集中が濃いほど確率は高い。
確率=Σ(集計配列2[カード番号][1]+集計配列2[カード番号][51]) / 52 / 試行回数
シャッフル手法 |
隣合ったカードが |
ランダム |
0.0392 |
ランダムディール(5山) |
0.1998 |
ランダムディール(10山) |
0.1018 |
ヒンズーシャッフル(3回) |
0.7768 |
ヒンズーシャッフル(10回) |
0.4600 |
ヒンズーシャッフル(20回) |
0.2276 |
7. まとめ
ヒンズーシャッフルは、隣合ったカードが隣のままの確率が高いことがわかった。ヒンズーシャッフル(3回)は78%、ヒンズーシャッフル(10回)で46%、ヒンズーシャッフル(20回)でも23%もある。延々とシャッフルしても隣合ったカードをよく混ぜるのは難しいことがわかった。
ランダムディールの隣だったカードの移動先には特徴があり、隣同士のままか、山1つ以上離れるかである。ディールシャッフルの配り方を考えれば当然であるが、画像2を見るまで思いつかなかった。逆順にはなるが隣のままの確率は、ランダムディール(5山)で20%、ランダムディール(10山)で10%である。
標準偏差はヒンズーシャッフル(20回)が良く、隣合ったカードではランダムディール(10山)のほうが良かった。
実際に手でシャッフルするとどちらも約1分とほぼ同じである。私の場合は、ヒンズーシャッフル(20回)のほうが失敗してカードを撒き散らしやすいので、ランダムディールを主に使っている。つまりゲーム前にノートPCを見ながらカードを配ってシャッフルし(末尾のリンク参照)、あらためてゲームのためにカードを配っている。
参考文献
-
野瀬彰大、深川大路:TCGにおけるシャッフル手法に関する計算機実験を用いた考察, 情報処理学会研究報告, Vol.2011-GI-25 No4 (2011).
リンク
FlickPass>シャッフルナビ
ソースコード( cakePHP plugin) https://github.com/ninton/ShuffleSim