2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【JavaScript初心者】ババ抜きを作った。

Last updated at Posted at 2021-03-25

JavaScriptの勉強のため、ババ抜きを作りました。
遊んでみるのもよし、自作して私のものと比較してみるのもよしだと思います。

本記事の環境

※PCに環境構築を行う必要はありません。
WEBブラウザ(Google Chome)
テキストエディタ

ババ抜きとは

ババ抜き(Old Maid、Lose with the Joker、Joker Game)とは、複数人で行うトランプの遊び方のひとつ。始めに同数のカードを人数分配り、一枚ずつ他者から抜き取り同じ札があれば捨て、最後にジョーカーを持っている人が負け。
https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%90%E6%8A%9C%E3%81%8D

要件・仕様

  • 言語の勉強が主目的なので、見た目はこだわらない。
  • 言語の勉強が主目的なので、処理は小分けにするし、コメントも残す。
  • フレームワークは使わない。
  • 基本的なババ抜きのルールに準ずる。
  • 4人対戦とする。
  • 勝敗くらいは表示する。
  • プレイヤー1人、CPU3人とする。
  • プレイヤー01がプレイヤー02の手札を引くところから始める。(本来のルールは、一番手札が多い人からスタート。)
  • CPUが引く手札の位置はランダムとする。
  • 各プレイヤーが持っている手札は、ターンごとに手札内でシャッフルする。
  • CPU同士の動きは処理だけ行って画面上ではスキップする。
  • ジョーカー(以下、画像のJKR)を持っているプレイヤーは、一度だけ、プレイヤー同士の手札のシャッフルを行うことができる(シャッフルタイム)。どのようにシャッフルされるかはランダムとする。

成果物(画面)

oldMaid_05.png

所感

  • ボタン、非同期での画面更新等、いくつか要素があるわりに、デザイン要素が少ないため言語学習に丁度よかった。
  • CPUの実装は難しくなかった。
  • シャッフルはオマケの機能だったが、データの入れ替え等、いい勉強になった。

成果物(ソースコード)

  • 参考程度にしてください。軽くは動作確認済みです。
oldMaid.html
<!DOCTYPE html>
<html>
    <head>
        <title>ババ抜き</title>
        
        <style>
            body {
                background-color : #eee;
            }
            #start, #next, #shuffle {
                font-size : 15px;
                background-color : #fff;
                text-align : center;
            }
            #result {
                font-size : 15px;
                background-color : #fff;
            }
            #player00Info, #player01Info, #player02Info, #player03Info {
                font-size : 20px;
            }
            #card {
                font-family:'MS Gothic';
                font-size : 20px;
                text-align : center;
            }
        </style>
    </head>
    <body>
        <div>
            <div>
                <span id="button"></span>
                <p id="result"></p>
                <p id="turn"></p>
                <p id="player00Info"></p>
                <p id="player01Info"></p>
                <p id="player02Info"></p>
                <p id="player03Info"></p>
            </div>
        </div>
        <script language="JavaScript">
            
            // カード基本情報
            const MAX_NUM = 13;
            const MIN_NUM = 1;
            const CARD_JOKER = "JKR";
            const CARD_SPADE = "&#9824;";
            const CARD_CLUB  = "&#9827;";
            const CARD_HEART = "&#9829;";
            const CARD_DIA   = "&#9830;";
            const COLOR_01   = "black";
            const COLOR_02   = "red";
            const COLOR_03   = "white";
            
            // ババ抜き情報
            const MAX_PLAYER = 4;
            
            // その他
            const MAX_SHUFFLE = 6;
            //const FLAG_DEBUG = true;
            const FLAG_DEBUG = false;
            
            // カード
            function Card(mark, num) {
                // プロパティ
                this.mark = mark;
                this.num = num;
            }
            
            // デッキ
            function Deck() {
                // プロパティ
                this.deck = [];
                
                // 初期化処理
                this.init = function() {
                    this.deck = [];
                    return;
                };
                
                // デッキ作成処理
                this.make = function() {
                    let card;
                    //for (let num = MIN_NUM; num <= 5; num++) {
                    for (let num = MIN_NUM; num <= MAX_NUM; num++) {
                        card = new Card(CARD_SPADE, num);
                        this.deck.push(card);
                        card = new Card(CARD_CLUB, num);
                        this.deck.push(card);
                        card = new Card(CARD_HEART, num);
                        this.deck.push(card);
                        card = new Card(CARD_DIA, num);
                        this.deck.push(card);
                    }
                    card = new Card(CARD_JOKER, 0);
                    this.deck.push(card);
                    return;
                };
                
                // デッキシャッフル処理
                this.shuffle = function() {
                    for (let loop = 0; loop < this.deck.length; loop++) {
                        let random = Math.floor(Math.random() * this.deck.length);
                        let work = this.deck[0];
                        this.deck[0] = this.deck[random];
                        this.deck[random] = work;
                    }
                    return;
                };
                
                // ドロー処理
                this.draw = function() {
                    return this.deck.shift();
                };
            }
            
            // 手札
            function Hand() {
                // プロパティ
                this.hand = [];
                
                // 初期化処理
                this.init = function() {
                    this.hand = [];
                    return;
                };
                
                // 手札セット処理
                this.set = function(card) {
                    this.hand.push(card);
                    return;
                };
                
                // 手札全取得処理
                this.getAll = function() {
                    return this;
                };
                
                // 手札全整理処理
                this.checkPairAll = function() {
                    // ペアを探し、見つけたら捨てる。
                    let handInfo = this.getAll();
                    for (let baseIdx = 0; baseIdx < handInfo.hand.length; baseIdx++) {
                        for (let targetIdx = 0; targetIdx < handInfo.hand.length; targetIdx++) {
                            if ((targetIdx != baseIdx) &&
                                (handInfo.hand[targetIdx].num == handInfo.hand[baseIdx].num)) {
                                if (targetIdx < baseIdx) {
                                    handInfo.hand.splice(baseIdx, 1);
                                    handInfo.hand.splice(targetIdx, 1);
                                } else {
                                    handInfo.hand.splice(targetIdx, 1);
                                    handInfo.hand.splice(baseIdx, 1);
                                }
                                baseIdx--;
                                break;
                            }
                        }
                    }
                    return;
                };
                
                // 指定手札取得処理
                this.getTarget = function(index) {
                    // 引数で指定した手札を返す。
                    let handInfo = this.getAll();
                    let card;
                    //alert("len:" + handInfo.hand.length);
                    for (let loop = 0; loop < handInfo.hand.length; loop++) {
                        if (loop == index) {
                            card = handInfo.hand[loop];
                            handInfo.hand.splice(loop, 1);
                            break;
                        }
                    }
                    //alert("mark:" + card.mark + "  num:" + card.num);
                    return card;
                };
                
                // 手札シャッフル処理
                this.shuffle = function() {
                    let handInfo = this.getAll();
                    for (let loop = 0; loop < handInfo.hand.length; loop++) {
                        let random = Math.floor(Math.random() * handInfo.hand.length);
                        let work = handInfo.hand[0];
                        handInfo.hand[0] = handInfo.hand[random];
                        handInfo.hand[random] = work;
                    }
                    return;
                };
            }
            
            // 桁数整形処理
            function spacePadding(num){
                return (Array(2).join(" ") + num).slice(-2);
            }
            
            // 桁数整形処理
            function zeroPadding(num){
                return (Array(2).join("0") + num).slice(-2);
            }
            
            // プレイヤー
            function Player() {
                // プロパティ
                this.strWin = "";
                this.results = [];
                this.results["win1"] = 0;
                this.results["win2"] = 0;
                this.results["win3"] = 0;
                this.results["lose"] = 0;
                this.cpu = true;
                this.shuffle = false;
                
                // 初期化処理
                this.init = function() {
                    // 抜けた番目を初期化する。
                    this.strWin = "";
                    
                    // シャッフルタイム使用フラグを初期化する。
                    this.shuffle = false;
                    return;
                };
                
                // CPUフラグ設定処理
                this.setCpu = function(flag) {
                    // CPUフラグを設定する。trueがCPU。
                    this.cpu = flag;
                    return;
                };
            }
            
            // ババ抜き
            function OldMaid () {
                // プロパティ
                let cntTurn = 0;
                let cntWin = 1;
                let players = [];
                players[0] = new Player();
                players[1] = new Player();
                players[2] = new Player();
                players[3] = new Player();
                let deck = new Deck();
                let hands = [];
                hands[0] = new Hand();
                hands[1] = new Hand();
                hands[2] = new Hand();
                hands[3] = new Hand();
                
                // 初期化処理
                this.init = function() {
                    // ターン数を初期化する。
                    cntTurn = 0;
                    
                    // 抜けた番目を初期化する。
                    cntWin = 1;
                    
                    // デッキの初期化処理を呼び出す。
                    deck.init();
                    
                    // プレイヤーの初期化処理を呼び出す。
                    players[0].init();
                    players[1].init();
                    players[2].init();
                    players[3].init();
                    
                    // 手札の初期化処理を呼び出す。
                    hands[0].init();
                    hands[1].init();
                    hands[2].init();
                    hands[3].init();
                    
                    // CPUフラグ設定処理を呼び出す。
                    players[0].setCpu(false);
                    return;
                };
                
                // カードイメージ作成処理
                this.makeCardImg = function(card, playerId, index) {
                    // 黒色
                    let color = COLOR_01;
                    if ((card.mark == CARD_HEART) || (card.mark == CARD_DIA)) {
                        // 赤色
                        color = COLOR_02;
                    }
                    
                    // カードイメージを作成する。
                    let cardImg = "";
                    if (card.mark != CARD_JOKER) {
                        // ジョーカー以外である場合
                        cardImg += "<span id='card' ";
                        cardImg += "name='" + String(playerId) + "_" + String(index) + "' ";
                        cardImg += "style='color:" + color + "; ";
                        cardImg += "background-color:" + COLOR_03 + ";'>";
                        cardImg += card.mark + String(spacePadding(card.num));
                        cardImg += "</span>";
                    } else {
                        // ジョーカーである場合
                        cardImg += "<span id='card' ";
                        cardImg += "name='" + String(playerId) + "_" + String(index) + "' ";
                        cardImg += "style='color:" + color + "; ";
                        cardImg += "background-color:" + COLOR_03 + ";'>";
                        cardImg += card.mark;
                        cardImg += "</span>";
                    }
                    return cardImg;
                };
                
                // 手札表示共通処理
                this.outputHandPCommon = function(playerId, handInfo) {
                    let detail = "";
                    if (handInfo.hand.length == 0) {
                        // 抜けたプレイヤーである場合
                        if (players[playerId].strWin == "") {
                            // 抜けた初回である場合
                            players[playerId].strWin = "<span id='card' ";
                            players[playerId].strWin += "style='color:" + COLOR_02 + "; ";
                            players[playerId].strWin += "background-color:" + COLOR_03 + ";'>";
                            players[playerId].strWin += "  " + String(cntWin) + "抜け" + "  ";
                            players[playerId].strWin += "</span>";
                            players[playerId].results["win" + cntWin]++;
                            cntWin++;
                        }
                        detail = players[playerId].strWin;
                    } else {
                        // 抜けていないプレイヤーである場合
                        for (let loop = 0; loop < handInfo.hand.length; loop++) {
                            let card = handInfo.hand[loop];
                            if (FLAG_DEBUG == true) {
                                // カードイメージ作成処理を呼び出す。
                                //alert("outputHandPCommon card:" + card.mark + card.num + " playerId:" + playerId + " loop:" + loop);
                                detail += this.makeCardImg(card, playerId, loop);
                            } else {
                                //if ((playerId == cntTurn) && (players[playerId].cpu == false)) {
                                if (players[playerId].cpu == false) {
                                    // カードイメージ作成処理を呼び出す。
                                    detail += this.makeCardImg(card, playerId, loop);
                                } else {
                                    detail += "<span id='card' ";
                                    detail += "name='" + String(playerId) + "_" + String(loop) + "' ";
                                    detail += "style='color:" + COLOR_01 + "; ";
                                    detail += "background-color:" + COLOR_01 + ";'>";
                                    //detail += "&#92171;";
                                    detail += CARD_SPADE + "XX";
                                    detail += "</span>";
                                }
                            }
                            detail += " ";
                        }
                    }
                    return detail;
                };
                
                // 手札表示処理
                this.outputHandP = function() {
                    for (let loop = 0; loop < MAX_PLAYER; loop++) {
                        // 各プレーヤーごとに手札表示共通処理を呼び出す。
                        let handInfo = hands[loop].getAll();
                        let work = String(zeroPadding(loop + 1)) + "" + this.outputHandPCommon(loop, handInfo);
                        if (loop != 3) {
                            work += "<br>↓";
                        }
                        
                        // 処理結果を設定する。
                        let id = "player" + String(zeroPadding(loop)) + "Info";
                        document.getElementById(id).innerHTML = work;
                    }
                    return;
                };
                
                // 手札配布処理
                this.distribute = function() {
                    let loop = 0;
                    while(1) {
                        // デッキからカードをドローする。
                        let card = deck.draw();
                        if (card == undefined) {
                            //alert("手札配布終了!");
                            break;
                        }
                        
                        // 手札セット処理を呼び出す。
                        hands[loop % MAX_PLAYER].set(card);
                        loop++;
                    }
                    return;
                };
                
                // ジョーカー探索処理
                this.searchJoker = function() {
                    let info = [];
                    for (let playerId = 0; playerId < MAX_PLAYER; playerId++) {
                        //alert("searchJoker playerId:" + playerId);
                        let handInfo = hands[playerId].getAll();
                        //alert("searchJoker len:" + handInfo.hand.length);
                        let index;
                        for (index = 0; index < handInfo.hand.length; index++) {
                            if (handInfo.hand[index].mark != CARD_JOKER) {
                                continue;
                            }
                            // プレイヤーと手札の情報を設定する。
                            info["id"] = playerId;
                            info["index"] = index;
                            break;
                        }
                        if (index < handInfo.hand.length) {
                            break;
                        }
                    }
                    //alert("searchJoker playerId:" + info["id"] + "  index:" + info["index"]);
                    return info;
                };
                
                // ゲーム終了判定処理
                this.isFin = function() {
                    let result;
                    if (cntWin >= MAX_PLAYER) {
                        // ゲーム終了
                        result = true;
                    } else {
                        // ゲーム続行
                        result = false;
                    }
                    return result;
                };
                
                // ゲーム終了処理
                this.fin = function() {
                    // ジョーカー探索処理を呼び出す。
                    let info = this.searchJoker();
                    //alert("fin playerId:" + info["id"] + "  index:" + info["index"]);
                    
                    // 処理結果を設定する。
                    let playerName = "プレイヤー" + String(zeroPadding(info["id"] + 1));
                    let work = "<p id='turn' style='color:red'>勝敗:" + playerName + "の負け</p>";
                    document.getElementById("turn").innerHTML = work;
                    
                    // 開始ボタンを活性に変更する。
                    document.getElementById("start").disabled = false;
                    
                    // 次へボタンを活性に変更する。
                    document.getElementById("next").disabled = true;
                    
                    // シャッフルボタンを活性に変更する。
                    document.getElementById("shuffle").disabled = true;
                    
                    // 勝敗カウンタをインクリメントする。
                    for (let loop = 0; loop < MAX_PLAYER; loop++) {
                        if (loop == info["id"]) {
                            players[loop].results["lose"]++;
                        } else {
                            //let winindex = "win" + info["id"];
                            //alert("winindex"+winindex);
                            //players[loop].results[winindex]++;
                        }
                    }
                    
                    // 結果表示処理を呼び出す。
                    this.outputResult();
                    return;
                };
                
                // シャッフルタイム実処理
                this.shuffleTimeCore = function(kind) {
                    let winPlayerId = -1;
                    if (kind <= 3) {
                        // 抜けているプレイヤーがいるか確認する。
                        // 2人以上抜けている場合は、本メソッドは呼ばれない想定。
                        for (let playerId = 0; playerId < MAX_PLAYER; playerId++) {
                            if (players[playerId].strWin != "") {
                                winPlayerId = playerId;
                                break;
                            }
                        }
                    }
                    
                    // 手札をシャッフルする。
                    let work;
                    switch (kind) {
                        case 0  : alert("出目 : 右1(手札を右隣りに1つ移動。)");
                                  hands.unshift(hands.pop());
                                  if (winPlayerId >= 0) {
                                      work = hands[winPlayerId];
                                      hands[winPlayerId] = hands[(winPlayerId + 1) % MAX_PLAYER];
                                      hands[(winPlayerId + 1) % MAX_PLAYER] = work;
                                  }
                                  break;
                        case 1  : alert("出目 : 右2(手札を右隣りに2つ移動。)");
                                  hands.unshift(hands.pop());
                                  if (winPlayerId >= 0) {
                                      work = hands[winPlayerId];
                                      hands[winPlayerId] = hands[(winPlayerId + 1) % MAX_PLAYER];
                                      hands[(winPlayerId + 1) % MAX_PLAYER] = work;
                                  }
                                  hands.unshift(hands.pop());
                                  if (winPlayerId >= 0) {
                                      work = hands[winPlayerId];
                                      hands[winPlayerId] = hands[(winPlayerId + 1) % MAX_PLAYER];
                                      hands[(winPlayerId + 1) % MAX_PLAYER] = work;
                                  }
                                  break;
                        case 2  : alert("出目 : 左1(手札を左隣りに1つ移動。)");
                                  hands.push(hands.shift());
                                  if (winPlayerId >= 0) {
                                      work = hands[winPlayerId];
                                      hands[winPlayerId] = hands[(winPlayerId + 3) % MAX_PLAYER];
                                      hands[(winPlayerId + 3) % MAX_PLAYER] = work;
                                  }
                                  break;
                        case 3  : alert("出目 : 左2(手札を左隣りに2つ移動。)");
                                  hands.push(hands.shift());
                                  if (winPlayerId >= 0) {
                                      work = hands[winPlayerId];
                                      hands[winPlayerId] = hands[(winPlayerId + 3) % MAX_PLAYER];
                                      hands[(winPlayerId + 3) % MAX_PLAYER] = work;
                                  }
                                  hands.push(hands.shift());
                                  if (winPlayerId >= 0) {
                                      work = hands[winPlayerId];
                                      hands[winPlayerId] = hands[(winPlayerId + 3) % MAX_PLAYER];
                                      hands[(winPlayerId + 3) % MAX_PLAYER] = work;
                                  }
                                  break;
                        case 4  : alert("出目 : ×(シャッフル発動失敗)");
                                  break;
                        case 5  : alert("出目 : ×(シャッフル発動失敗)");
                                  break;
                        default : alert("shuffleTime kind=" + kind);
                                  break;
                    }
                    
                    // 手札シャッフル処理を呼び出す。
                    for (let playerId = 0; playerId < MAX_PLAYER; playerId++) {
                        if (players[playerId].strWin == "") {
                            hands[playerId].shuffle();
                        }
                    }
                    
                    // 手札表示処理を呼び出す。
                    game.outputHandP();
                    
                    // カード選択イベント設定処理を呼び出す。
                    game.setSelectCardEvt();
                    return;
                };
                
                // シャッフルタイム処理
                this.shuffleTime = function() {
                    let work = "シャッフル発動!!";
                    alert(work);
                    
                    // サイコロを振ってシャッフル方法を決める。
                    let random = Math.floor(Math.random() * MAX_SHUFFLE);
                    //alert("出目 : " + random);
                    
                    // シャッフルタイム実処理を呼び出す。
                    this.shuffleTimeCore(random);
                    //this.shuffleTimeCore(1);
                    
                    // シャッフルタイム使用フラグをONにする。
                    players[cntTurn].shuffle = true;
                    
                    // シャッフルボタン表示切替処理を呼び出す。
                    this.changesShuffleButton();
                    return;
                };
                
                // 対象プレイヤー情報取得処理
                this.getTargetPlayer = function() {
                    // 引くプレイヤーと引かれるプレイヤーを調べる。
                    let toPlayer = cntTurn;
                    let fromPlayer = (cntTurn + 1) % MAX_PLAYER;
                    while(1) {
                        if ((toPlayer != fromPlayer) && (players[fromPlayer].strWin == "")) {
                            break;
                        }
                        fromPlayer = (fromPlayer + 1) % MAX_PLAYER;
                    }
                    let result = [];
                    result["from"] = fromPlayer;
                    result["to"] = toPlayer;
                    return result;
                };
                
                // カード選択共通処理
                this.selectCardCommon = function(fromPlayer, toPlayer, intPlayer, intIdx) {
                    if (fromPlayer != intPlayer) {
                        // カードを引く先が間違っている場合
                        let work = "プレイヤー" + zeroPadding(toPlayer + 1) + "の手番です。";
                        work += "プレイヤー" + zeroPadding(fromPlayer + 1) + "のカードを引いてください。";
                        alert(work);
                    } else {
                        // カードを引く先が正しい場合
                        
                        // 指定手札取得処理を呼び出す。
                        let card = hands[fromPlayer].getTarget(intIdx);
                        //alert("fromPlayer:" + fromPlayer + "  intIdx:" + intIdx + "  mark:" + card.mark + "  num:" + card.num);
                        
                        // 手札セット処理を呼び出す。
                        hands[toPlayer].set(card);
                        
                        // 手札整理処理を呼び出す。
                        hands[toPlayer].checkPairAll();
                        
                        // 手札シャッフル処理を呼び出す。
                        hands[toPlayer].shuffle();
                        
                        // 手札表示処理を呼び出す。
                        game.outputHandP();
                        
                        // カード選択イベント設定処理を呼び出す。
                        game.setSelectCardEvt();
                        
                        // ターン変更処理を呼び出す。
                        game.changeTurn();
                    }
                    return;
                };
                
                // カード選択イベント処理
                this.selectCardUser = function(event) {
                    // クリックしたカードが妥当かどうかによって処理を分岐する。
                    if (players[cntTurn].cpu == true) {
                        // 手番がCPUである場合
                        let work = "プレイヤー" + zeroPadding(cntTurn + 1) + "(CPU)の手番です。";
                        work += "カード選択はできません。";
                        alert(work);
                    } else {
                        // 対象プレイヤー情報取得処理を呼び出す。
                        let result = game.getTargetPlayer();
                        
                        // イベント情報からクリックしたカードを特定する。
                        let name = event.target.getAttribute("name").split("_");
                        let intPlayer = parseInt(name[0], 10);
                        let intIdx = parseInt(name[1], 10);
                        
                        // カード選択共通処理を呼び出す。
                        game.selectCardCommon(result["from"], result["to"], intPlayer, intIdx);
                    }
                    return;
                };
                
                // カード自動選択処理
                this.selectCardCpu = function() {
                    // 対象プレイヤー情報取得処理を呼び出す。
                    let result = this.getTargetPlayer();
                    
                    // 引くカードを決める。
                    let handInfo = hands[result["from"]].getAll();
                    let random = Math.floor(Math.random() * handInfo.hand.length);
                    let intPlayer = result["from"];
                    let intIdx = random;
                    //alert("intPlayer + "、" + intIdx);
                    //let work = "プレイヤー" + zeroPadding(result["to"] + 1) + "が、";
                    //work += "プレイヤー" + zeroPadding(result["from"] + 1) + "のカードを引きます。";
                    //alert(work);
                    
                    // カード選択共通処理を呼び出す。
                    this.selectCardCommon(result["from"], result["to"], intPlayer, intIdx);
                    return;
                };
                
                // カード選択イベント設定共通処理
                this.setSelectCardEvtCommon = function(playerId, handInfo) {
                    // 各カードにイベントを設定する。
                    for (let loop = 0; loop < handInfo.hand.length; loop++) {
                        let work = document.getElementsByName(String(playerId) + "_" + String(loop));
                        work[0].addEventListener("click", this.selectCardUser);
                    }
                    return;
                };
                
                // カード選択イベント設定処理
                this.setSelectCardEvt = function() {
                    for (let loop = 0; loop < MAX_PLAYER; loop++) {
                        // 各プレーヤーごとにカード選択イベント設定共通処理を呼び出す。
                        let handInfo = hands[loop].getAll();
                        this.setSelectCardEvtCommon(loop, handInfo);
                    }
                    return;
                };
                
                // シャッフルボタン表示切替処理
                this.changesShuffleButton = function() {
                    // シャッフルボタンを活性に変更する。
                    document.getElementById("shuffle").disabled = false;
                    
                    if (cntWin >= 3) {
                        // 残りのプレイヤーが2人以下の場合
                        
                        // シャッフルボタンを非活性に変更する。
                        document.getElementById("shuffle").disabled = true;
                    }
                    if (players[0].shuffle != false) {
                        // プレイヤー01がシャッフルタイム使用済の場合
                        
                        // シャッフルボタンを非活性に変更する。
                        document.getElementById("shuffle").disabled = true;
                    }
                    
                    // ジョーカー探索処理を呼び出す。
                    let info = this.searchJoker();
                    //alert("fin playerId:" + info["id"] + "  index:" + info["index"]);
                    if (info["id"] != 0) {
                        // プレイヤー01がジョーカーを保持していない場合
                        
                        // シャッフルボタンを非活性に変更する。
                        document.getElementById("shuffle").disabled = true;
                    }
                    return;
                };
                
                // ゲーム開始処理
                this.start = function() {
                    // 初期化処理を呼び出す。
                    this.init();
                    
                    // 開始ボタンを非活性に変更する。
                    document.getElementById("start").disabled = true;
                    
                    // デッキ作成処理を呼び出す。
                    deck.make();
                    
                    // 作成したデッキをシャッフルする。
                    deck.shuffle();
                    
                    // 手札配布処理を呼び出す。
                    this.distribute();
                    
                    // 各プレーヤーごとに手札全整理処理を呼び出す。
                    for (let loop = 0; loop < MAX_PLAYER; loop++) {
                        hands[loop].checkPairAll();
                    }
                    
                    // 手札表示処理を呼び出す。
                    this.outputHandP();
                    
                    // カード選択イベント設定処理
                    this.setSelectCardEvt();
                    
                    // 手番表示処理を呼び出す。
                    this.outputTurn();
                    
                    // シャッフルボタン表示切替処理を呼び出す。
                    this.changesShuffleButton();
                    return;
                };
                
                // ターン変更処理
                this.changeTurn = function() {
                    // ゲーム終了判定処理を呼び出す。
                    result = game.isFin();
                    if (result == true) {
                        // ゲーム終了処理を呼び出す。
                        game.fin();
                    } else {
                        // ターンを切り替える。
                        cntTurn = (cntTurn + 1) % MAX_PLAYER;
                        while(1) {
                            if (players[cntTurn].strWin == "") {
                                break;
                            }
                            cntTurn = (cntTurn + 1) % MAX_PLAYER;
                        }
                        
                        // 手札表示処理を呼び出す。
                        this.outputHandP();
                        
                        // カード選択イベント設定処理
                        this.setSelectCardEvt();
                        
                        // 手番表示処理を呼び出す。
                        this.outputTurn();
                        
                        // 手番によって処理を分岐する。
                        if (players[cntTurn].cpu == true) {
                            // 手番がCPUである場合
                            
                            // 次へボタンを活性に変更する。
                            document.getElementById("next").disabled = false;
                            
                            let info = this.searchJoker();
                            if (info["id"] != 0) {
                                // プレイヤー01がジョーカーを保持していない場合
                                // 自動でターンを進める。
                                game.next();
                            } else {
                                // プレイヤー01がジョーカーを保持している場合
                                // ユーザの次へボタン操作イベント待ち。
                            }
                        } else {
                            // 手番がユーザである場合
                            
                            // 次へボタンを非活性に変更する。
                            document.getElementById("next").disabled = true;
                            
                            // ユーザのカード選択イベント待ち。
                        }
                        
                        // シャッフルボタン表示切替処理を呼び出す。
                        this.changesShuffleButton();
                    }
                    return;
                };
                
                // ターン進行処理
                this.next = function() {
                    // ジョーカー探索処理を呼び出す。
                    let info = this.searchJoker();
                    //alert("fin playerId:" + info["id"] + "  index:" + info["index"]);
                    if (info["id"] != 0) {
                        // プレイヤー01がジョーカーを保持していない場合
                        
                        if (players[info["id"]].shuffle != true) {
                            // シャッフルタイム未使用である場合
                            
                            if (cntWin == 2) {
                                // 残りのプレイヤーが3人の場合
                                
                                // シャッフルタイム処理を呼び出す。
                                this.shuffleTime();
                            }
                        }
                    }
                    
                    // カード自動選択処理を呼び出す。
                    this.selectCardCpu();
                    return;
                };
                
                // 結果表示処理
                this.outputResult = function() {
                    let work = "";
                    for (let loop = 0; loop < MAX_PLAYER; loop++) {
                        if (loop == 0) {
                            work += "<p id='result' style='color:red'>";
                        } else {
                            work += "<p id='result' style='color:black'>";
                        }
                        work += "プレイヤー" + String(zeroPadding(loop + 1)) + "";
                        work += "1位 " + String(spacePadding(players[loop].results["win1"])) + "";
                        work += " 2位 " + String(spacePadding(players[loop].results["win2"])) + "";
                        work += " 3位 " + String(spacePadding(players[loop].results["win3"])) + "";
                        work += " 4位 " + String(spacePadding(players[loop].results["lose"])) + "";
                        let total = 0;
                        total += parseInt(String(spacePadding(players[loop].results["win1"])));
                        total += parseInt(String(spacePadding(players[loop].results["win2"])));
                        total += parseInt(String(spacePadding(players[loop].results["win3"])));
                        let win = total;
                        total += parseInt(String(spacePadding(players[loop].results["lose"])));
                        let par = "---";
                        if (total != 0) {
                            par = win / total * 100.00;
                            par = par.toFixed(3);
                        }
                        work += " 勝率 " + par + "%" + "<br>";
                    }
                    work += "</p>";
                    document.getElementById("result").innerHTML = work;
                    return;
                };
                
                // 手番表示処理
                this.outputTurn = function() {
                    let work =  "<span>";
                    work += "プレイヤー" + zeroPadding(cntTurn + 1) + "の手番  ";
                    work += "</span>";
                    document.getElementById("turn").innerHTML = work;
                    return;
                };
                
                // ボタン表示処理
                this.outputButton = function() {
                    let work =  "<span>";
                    work += "<input type='button' id='start' value='開始' onclick='game.start()'>";
                    work += "<input type='button' id='next' value='次へ' disabled=true onclick='game.next()'>";
                    work += "<input type='button' id='shuffle' value='シャッフル' disabled=true onclick='game.shuffleTime()'>";
                    work += "</span>";
                    document.getElementById("button").innerHTML = work;
                    return;
                };
            }
            
            // 初期化処理を呼び出す。
            let game = new OldMaid();
            game.init();
            
            // ボタン表示処理を呼び出す。
            game.outputButton();
            
            // 結果表示処理を呼び出す。
            game.outputResult();
        </script>
    </body>
</html>

関連

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?