LIAR GAME - 17Pokerのカラクリと矛盾

LIAR GAMEトーナメント4回戦の中堅戦、17(セブンティーン)ポーカーの「ココおかしいです」。

録画していたのを最近見たのでタイムリーな話しではないことを十分理解した上で、
そんなことはどうでもイイ!!

※再放送を見たので、さらに書き加えました。

それでは本題へ。

念のため、17ポーカーを簡単に説明するとJ×4, Q×4, K×4, A×4, Jokerの計17枚で行うポーカーです。詳しいルールは番組のサイトでチェックして下さい。

今回取り上げるのは、秋山の要求によりヒンズーシャッフルを止めて、リフルシャッフルのみとなった6th Gameと7th Gameです。

リフルシャッフルにより規則的に変化するカードの並び順を調べることによって、秋山の「5枚交換による2連続4カードを本当に再現できるか?」を確かめる。

どうやって調べたか? → サクッとJavascriptで。
規則的に動作するモノを再現するのはプログラミングは最も適しているトコロ。

そして、調べるうちに「おかしい(-_-;)」と思われるところがやはり出てきた。

新品のカードの並びを再現する

菊池の手掛かりをまとめると、
  1. 一番下は♠A
  2. 下から二番目は♠J
  3. 一番上はJoker

function create17Cards(){
    var
    suit = ["♥", "♣", "♦", "♠"],
    num = ["K", "Q", "J", "A"],
    cards = ["Jk"]; //Jk = Joker
    
    for (var i = 0; i < suit.length; i++) {
        for (var k = 0; k < num.length; k++) {
            cards.push(suit[i] + num[k]);
        }
    }
    
    return cards;
}

結果:上→下
[Jk][♥K][♥Q][♥J][♥A][♣K][♣Q][♣J][♣A][♦K][♦Q][♦J][♦A][♠K][♠Q][♠J][♠A]

後に秋山が行う説明の中での並び順とも完全に一致する。


リフルシャッフルを再現する

簡単に説明すると、二つに分けたカードを一枚づつ重ね合わせる方法のこと。
全カードの枚数が奇数(17枚)なのでカードを2分割するとき、「8,9」とするか「9,8」にするかで結果がことなるため重要なポイントとなる。
私が何度か試した結果とドラマ中の説明と一致するのは「8,9」であった。

//Perfect Shuffle
function riffleShuffle(cards, count){
    var tmp = [], cardsA, cardsB;
    
    for (var i = 0; i < count; i++) {
        cardsA = cards.slice(0, 8);
        cardsB = cards.slice(8);
        
        for (var k = 0; k < cardsB.length; k++) {
            tmp[k * 2] = cardsB[k];
        }
        
        for (var n = 0; n < cardsA.length; n++) {
            tmp[n + n + 1] = cardsA[n];
        }
        
        cards = tmp;
    }
    return cards;
}
if文を使わない方が直観的か?と感じたのでこのような形にしたが間違った結果は返さないのでこれで良しとする。

上のcreate17Cards関数で17枚のカードを生成し、このriffleShuffle関数で指定の回数だけシャッフルすると以下のような結果となる。
0: [Jk][♥K][♥Q][♥J][♥A][♣K][♣Q][♣J][♣A][♦K][♦Q][♦J][♦A][♠K][♠Q][♠J][♠A]
1: [♣A][Jk][♦K][♥K][♦Q][♥Q][♦J][♥J][♦A][♥A][♠K][♣K][♠Q][♣Q][♠J][♣J][♠A]
2: [♦A][♣A][♥A][Jk][♠K][♦K][♣K][♥K][♠Q][♦Q][♣Q][♥Q][♠J][♦J][♣J][♥J][♠A]
3: [♠Q][♦A][♦Q][♣A][♣Q][♥A][♥Q][Jk][♠J][♠K][♦J][♦K][♣J][♣K][♥J][♥K][♠A]
4: [♠J][♠Q][♠K][♦A][♦J][♦Q][♦K][♣A][♣J][♣Q][♣K][♥A][♥J][♥Q][♥K][Jk][♠A]
5: [♣J][♠J][♣Q][♠Q][♣K][♠K][♥A][♦A][♥J][♦J][♥Q][♦Q][♥K][♦K][Jk][♣A][♠A]
6: [♥J][♣J][♦J][♠J][♥Q][♣Q][♦Q][♠Q][♥K][♣K][♦K][♠K][Jk][♥A][♣A][♦A][♠A]
7: [♥K][♥J][♣K][♣J][♦K][♦J][♠K][♠J][Jk][♥Q][♥A][♣Q][♣A][♦Q][♦A][♠Q][♠A]
8: [Jk][♥K][♥Q][♥J][♥A][♣K][♣Q][♣J][♣A][♦K][♦Q][♦J][♦A][♠K][♠Q][♠J][♠A]
コンプリートシャッフルを8回行うと元の並びに戻ることが分かる。



カットを再現する

両プレイヤーそれぞれが上から何番目かを指定し、ディーラーがその位置でカードの位置を上下入れ替える。

function cut(cards, n){
    n = Math.max(Math.min(n, cards.length), 0);
    
    var
    cardsA = cards.slice(0, n),
    cardsB = cards.slice(n);

    return cardsB.concat(cardsA);
}



そして、最終的にディーラーを再現すると以下のようになる。
var Dealer = (function(){

    var cards = [];
    
    function create17Cards(){
        var
        suit = ["♥", "♣", "♦", "♠"],
        num  = ["K", "Q", "J", "A"],
        ret  = ["Jk"]; //Jk = Joker
        
        for (var i = 0; i < suit.length; i++) {
            for (var k = 0; k < num.length; k++) {
                ret.push(suit[i] + num[k]);
            }
        }
        
        return ret;
    }
    
    
    return {
        //set new cards
        newGame : function(){
            cards = create17Cards();
        },
        
        //Perfect Shuffle
        riffleShuffle: function(count){
            var tmp = [], cardsA, cardsB;
            
            for (var i = 0; i < count; i++) {
                cardsA = cards.slice(0, 8);
                cardsB = cards.slice(8);
                
                for (var k = 0; k < cardsB.length; k++) {
                    tmp[k * 2] = cardsB[k];
                }
                
                for (var n = 0; n < cardsA.length; n++) {
                    tmp[n + n + 1] = cardsA[n];
                }
                
                cards = tmp;
            }
        },
        
        //cut the cards
        cut:function(n){
            n = Math.max(Math.min(n, cards.length), 0);
            
            var
            cardsA = cards.slice(0,n),
            cardsB = cards.slice(n);
            
            cards = cardsB.concat(cardsA);
        },
        
        
        //First Deal
        firstDeal:function(){
            if(cards.length < 10) return;
            
            var
            decks = [[],[]],
            i     = 0;
            
            for (; i < 10; i++) {
                decks[i % 2].push(cards.shift());
            }
            
            return decks;
        },
        
        
        //change the card
        change: function(n){
            n = Math.min(Math.max(Math.min(n, 5), 1),cards.length);
            var ret = cards.slice(0, n);
            cards.splice(0, n);
            return ret;
        },
        
        
        //Remaining cards
        remainingCards:function(){
            return cards;
        }
    };
})();




そしてこれから、6th Gameと7th Gameを見ていく。

念のため:
プレイヤーは髪が長めの男の名が"秋山"。サングラスをした男が"菊池"。

6th Game


6th Gameからリフルシャッフルを何回行うことになっているのか明らかになっていない。
最初に決められた回数通りと考えるのが妥当だが、この17Pokerというゲームを始める際の説明として、「ヒンズーシャッフルとリフルシャッフルを行います。」と説明されているが、そのシャッフルを何回行うのかドラマ中に明言されていない

カットのコール
菊池:9
秋山:2

秋山の最初の手札:ドラマ中一度も見せていない
菊池の最初の手札:♠K, ♦K, ♦J, ♠J, ♣A

5枚交換後の秋山の手札:♥A, Jk, ♠Q, ♦Q, ♥Q
1枚交換後の菊池の手札:♠K, ♦K, ♦J, ♠J, ♥J

秋山の方が先にカードの交換を行っているので、残されたカードは「♥A, Jk, ♠Q, ♦Q, ♥Q, ♥J, ?」の7枚だったということになる。
並び順までは分からないが最初の5枚の内、JokerとQeenが3枚、その後6枚目に必ず♥Jがある、ということまでは特定できる。

これと同じ状況を作り出せるか検証する。

検証用関数
function game(shuffleCount, cutNumA, cutNumB){

    var
    $div = $("<div>"),
    dealtCards, playerA, playerB;
    
    //Set new cards.
    Dealer.newGame();
    
    //Shuffle
    Dealer.riffleShuffle(shuffleCount);
    
    //Cut
    Dealer.cut(cutNumA);
    Dealer.cut(cutNumB);
    
    $div.append($("<span>").append([
        "shuffle: " + shuffleCount,
        "  cut 1: " + cutNumA,
        "  cut 2: " + cutNumB
    ].join("<br>")),"<br>");

    
    $div.append($("<span>").append(
        "before deal:" + Dealer.remainingCards().join(",")),
        "<br>");
    
    //deal cards
    dealtCards = Dealer.firstDeal();
    
    $div.append($("<span>").append([
        "       player A: " + dealtCards[0].join(","),
        "       player B: " + dealtCards[1].join(","),
        "remaining cards: " + Dealer.remainingCards().join(",")
    ].join("<br>")));
    
    return $div;    
}

この検証用関数を以下のように使用する。
for (var i = 0; i < 8; i++) {
    $(document.body).append(game(i, 9, 2));
}




6th Game Pattern:結果
  • shuffle:リフルシャッフルをする回数
  • cut 1,2:両プレイヤーが要求するカットの枚数
  • before deal:シャッフルとカットを終え、プレイヤーにカードを配る前のカードの並び順
  • player A:プレイヤーAに配られるカード
  • player B:プレイヤーBに配られるカード
  • remaining cards:プレイヤーにカードを配り終えた後、ディーラーの下に残されたカード

shuffle: 0
cut 1: 9
cut 2: 2
before deal:♦J,♦A,♠K,♠Q,♠J,♠A,Jk,♥K,♥Q,♥J,♥A,♣K,♣Q,♣J,♣A,♦K,♦Q
player A: ♦J,♠K,♠J,Jk,♥Q
player B: ♦A,♠Q,♠A,♥K,♥J
remaining cards: ♥A,♣K,♣Q,♣J,♣A,♦K,♦Q

shuffle: 1
cut 1: 9
cut 2: 2
before deal:♣K,♠Q,♣Q,♠J,♣J,♠A,♣A,Jk,♦K,♥K,♦Q,♥Q,♦J,♥J,♦A,♥A,♠K
player A: ♣K,♣Q,♣J,♣A,♦K
player B: ♠Q,♠J,♠A,Jk,♥K
remaining cards: ♦Q,♥Q,♦J,♥J,♦A,♥A,♠K

shuffle: 2
cut 1: 9
cut 2: 2
before deal:♥Q,♠J,♦J,♣J,♥J,♠A,♦A,♣A,♥A,Jk,♠K,♦K,♣K,♥K,♠Q,♦Q,♣Q
player A: ♥Q,♦J,♥J,♦A,♥A
player B: ♠J,♣J,♠A,♣A,Jk
remaining cards: ♠K,♦K,♣K,♥K,♠Q,♦Q,♣Q

shuffle: 3
cut 1: 9
cut 2: 2
before deal:♦K,♣J,♣K,♥J,♥K,♠A,♠Q,♦A,♦Q,♣A,♣Q,♥A,♥Q,Jk,♠J,♠K,♦J
player A: ♦K,♣K,♥K,♠Q,♦Q
player B: ♣J,♥J,♠A,♦A,♣A
remaining cards: ♣Q,♥A,♥Q,Jk,♠J,♠K,♦J

shuffle: 4
cut 1: 9
cut 2: 2
before deal:♥A,♥J,♥Q,♥K,Jk,♠A,♠J,♠Q,♠K,♦A,♦J,♦Q,♦K,♣A,♣J,♣Q,♣K
player A: ♥A,♥Q,Jk,♠J,♠K
player B: ♥J,♥K,♠A,♠Q,♦A
remaining cards: ♦J,♦Q,♦K,♣A,♣J,♣Q,♣K

shuffle: 5
cut 1: 9
cut 2: 2
before deal:♦Q,♥K,♦K,Jk,♣A,♠A,♣J,♠J,♣Q,♠Q,♣K,♠K,♥A,♦A,♥J,♦J,♥Q
player A: ♦Q,♦K,♣A,♣J,♣Q
player B: ♥K,Jk,♠A,♠J,♠Q
remaining cards: ♣K,♠K,♥A,♦A,♥J,♦J,♥Q

shuffle: 6
cut 1: 9
cut 2: 2
before deal:♠K,Jk,♥A,♣A,♦A,♠A,♥J,♣J,♦J,♠J,♥Q,♣Q,♦Q,♠Q,♥K,♣K,♦K
player A: ♠K,♥A,♦A,♥J,♦J
player B: Jk,♣A,♠A,♣J,♠J
remaining cards: ♥Q,♣Q,♦Q,♠Q,♥K,♣K,♦K

shuffle: 7
cut 1: 9
cut 2: 2
before deal:♣Q,♣A,♦Q,♦A,♠Q,♠A,♥K,♥J,♣K,♣J,♦K,♦J,♠K,♠J,Jk,♥Q,♥A
player A: ♣Q,♦Q,♠Q,♥K,♣K
player B: ♣A,♦A,♠A,♥J,♣J
remaining cards: ♦K,♦J,♠K,♠J,Jk,♥Q,♥A
注目すべきはリフルシャッフルを2回、または6回行った場合のディーラーに残されたカードだ。
結果、何度シャッフルをしたとしてもこのゲームのようなカードの並びにはならない。

それではどうのようなパターンなら再現されるのだろうか?
菊池の最初の手札から導き出せる可能性があるのでそれを手掛かりに探ってみる。

パターンの組み合わせは
  • コンプリートシャッフルを行う回数
  • 両プレイヤーの要求するカットの枚数
全ての組み合わせを再現し、6th Gameで菊池が最初に手にした5枚のカードと同じカードが配られるパターンがあるかを調べてみる。

テスト用の関数が以下の通り
function samePattern(cards){
    var dealtCards;
    
    function same(cardsA, cardsB){
        var flg;
        
        for (var k = 0; k < cardsA.length; k++) {
            flg = false;
            
            for (var j = 0; j < cardsB.length; j++) {
            
                flg = cardsA[k] === cardsB[j];
                if (flg) {
                    //console.log("j:" + j);
                    break;
                }
            }
            
            if (!flg) {
                //console.log("not found:" + cardsA[k]);
                break;
            }
        }
        return flg;
    }
    
    //Shuffle count
    for (var i = 0; i < 8; i++) {
        //cut 1 Number
        for (var n = 0; n < 17; n++) {
            //cut 2 Number
            for (var m = 0; m < 17; m++) {
                Dealer.newGame();
                
                Dealer.riffleShuffle(i);
                Dealer.cut(n);
                Dealer.cut(m);
                
                dealtCards = Dealer.firstDeal();
                
                if (same(dealtCards[0], cards)) {
                    return [n, m, i];
                }
                
                if (same(dealtCards[1], cards)) {
                    return [n, m, i];
                }
            }
        }
    }
    
    return false;
}

そしてこのsamePattern関数を以下のように使用する。
var kikuchi = ["♠K","♦K","♦J","♠J","♣A"];
console.log(samePattern(kikuchi));//false
結果はfalse。
つまり、どのようなパターンであったとしても、菊池の最初の手札の組み合わせは生まれないのだ


7th Game

このゲームでは秋山の要求により、さらに3回多くリフルシャッフルが行われている。
秋山:「...念のためあと2回、いや3回シャッフルしてくれ。」

カットのコール
秋山:8
菊池:7

秋山の最初の手札:♥J, ♦A, ♥A, ♠K, ♣K
菊池の最初の手札:♠A, ♣A, Jk, ♦K, ♥K

5枚交換後の秋山の手札:♠J, ♣Q, ♠Q, ♦Q, ♥Q
菊池は交換なし

最初の手札を配り終わった後のディーラーの下に残されているカードの上から5枚に秋山が5枚交換で手にしたカードがある組み合わせはあるか?

6th Gameと同じようにパターンを出してみる。

shuffle: 0
cut 1: 8
cut 2: 7
before deal:♠J,♠A,Jk,♥K,♥Q,♥J,♥A,♣K,♣Q,♣J,♣A,♦K,♦Q,♦J,♦A,♠K,♠Q
player A: ♠J,Jk,♥Q,♥A,♣Q
player B: ♠A,♥K,♥J,♣K,♣J
remaining cards: ♣A,♦K,♦Q,♦J,♦A,♠K,♠Q

shuffle: 1
cut 1: 8
cut 2: 7
before deal:♣J,♠A,♣A,Jk,♦K,♥K,♦Q,♥Q,♦J,♥J,♦A,♥A,♠K,♣K,♠Q,♣Q,♠J
player A: ♣J,♣A,♦K,♦Q,♦J
player B: ♠A,Jk,♥K,♥Q,♥J
remaining cards: ♦A,♥A,♠K,♣K,♠Q,♣Q,♠J

shuffle: 2
cut 1: 8
cut 2: 7
before deal:♥J,♠A,♦A,♣A,♥A,Jk,♠K,♦K,♣K,♥K,♠Q,♦Q,♣Q,♥Q,♠J,♦J,♣J
player A: ♥J,♦A,♥A,♠K,♣K
player B: ♠A,♣A,Jk,♦K,♥K
remaining cards: ♠Q,♦Q,♣Q,♥Q,♠J,♦J,♣J

shuffle: 3
cut 1: 8
cut 2: 7
before deal:♥K,♠A,♠Q,♦A,♦Q,♣A,♣Q,♥A,♥Q,Jk,♠J,♠K,♦J,♦K,♣J,♣K,♥J
player A: ♥K,♠Q,♦Q,♣Q,♥Q
player B: ♠A,♦A,♣A,♥A,Jk
remaining cards: ♠J,♠K,♦J,♦K,♣J,♣K,♥J

shuffle: 4
cut 1: 8
cut 2: 7
before deal:Jk,♠A,♠J,♠Q,♠K,♦A,♦J,♦Q,♦K,♣A,♣J,♣Q,♣K,♥A,♥J,♥Q,♥K
player A: Jk,♠J,♠K,♦J,♦K
player B: ♠A,♠Q,♦A,♦Q,♣A
remaining cards: ♣J,♣Q,♣K,♥A,♥J,♥Q,♥K

shuffle: 5
cut 1: 8
cut 2: 7
before deal:♣A,♠A,♣J,♠J,♣Q,♠Q,♣K,♠K,♥A,♦A,♥J,♦J,♥Q,♦Q,♥K,♦K,Jk
player A: ♣A,♣J,♣Q,♣K,♥A
player B: ♠A,♠J,♠Q,♠K,♦A
remaining cards: ♥J,♦J,♥Q,♦Q,♥K,♦K,Jk

shuffle: 6
cut 1: 8
cut 2: 7
before deal:♦A,♠A,♥J,♣J,♦J,♠J,♥Q,♣Q,♦Q,♠Q,♥K,♣K,♦K,♠K,Jk,♥A,♣A
player A: ♦A,♥J,♦J,♥Q,♦Q
player B: ♠A,♣J,♠J,♣Q,♠Q
remaining cards: ♥K,♣K,♦K,♠K,Jk,♥A,♣A

shuffle: 7
cut 1: 8
cut 2: 7
before deal:♠Q,♠A,♥K,♥J,♣K,♣J,♦K,♦J,♠K,♠J,Jk,♥Q,♥A,♣Q,♣A,♦Q,♦A
player A: ♠Q,♥K,♣K,♦K,♠K
player B: ♠A,♥J,♣J,♦J,♠J
remaining cards: Jk,♥Q,♥A,♣Q,♣A,♦Q,♦A

この結果から、2回シャッフルしたときにドラマと同じ組み合わせが再現できることが分かった。

しかし、秋山はシャッフルの回数を通常の回数に加えて更に3回行わせている
ということは、シャッフルの回数は2回であるはずがないので、そうすると次にこの組み合わせが現れるのは10回目となる。
7th Gameはこのゲームの設定として、最初にリフルシャッフルを7回行うことを前提に成り立つことになる。
計10回もリフルシャッフルを行わせるというは少々疑問に感じるのだが、仮に10回行ったと仮定すると、それ以前のゲームまでは10 - 3で7回行っていたことになる。
そうすると、6th Gameの結果に益々無理が生じてくることになる。

つまり、7th Gameの結果から6th Gameは7回リフルシャッフルを行っていることになり、上で示したように、そのパターンで秋山が5枚交換でJoker + Q × 3の4カードを引き当てることは不可能なのだ。

0 Comments:

Sony Style(ソニースタイル)
デル株式会社

Recent Posts