【JavaScript初心者】数字当てゲームを作った。

JavaScriptの勉強のため、数字当てゲームを作りました。
遊んでみるのもよし、自作して私のものと比較してみるのもよしだと思います。
#本記事の環境
※PCに環境構築を行う必要はありません。
WEBブラウザ(Google Chome)
テキストエディタ

# 数字当てゲームとは
1対1の対戦ゲーム。0～9から3つを選択し並び替える(012～987)。プレイヤーは相手が選択した3つの数字の組み合わせと並びを推理する。交互に数字を言い合い、相手より早く特定したほうが勝ち。
数字と並びが合っている場合はEAT(イート)、数字だけが合っている場合はBITE(バイト)と相手に伝える。要するに、相手に「3(スリー)EAT」と言わせられれば勝ち。
※「EAT」、「BITE」の呼び方はモノによって様々ある。
本ゲームを題材としたテレビ番組やアプリゲームがある。←自作してみようと思ったきっかけ。

#要件・仕様
* 言語の勉強が主目的なので、見た目はこだわらない。
* 言語の勉強が主目的なので、処理は小分けにするし、コメントも残す。
* フレームワークは使わない。
* 勝敗くらいは表示する。
* 対戦相手はCPUにする。
* プレイヤーがCPUに申告する3つの数字はプルダウンから選択する(以下、画像の415)。選択後「判定」を選択して判定する。
* 相手に当てさせる3つの数字とその並びはランダムとする。決定したら、プレイヤー側の数値のみ表示する(以下、画像の817)。
* お互いが申告した数字と判定結果の履歴は「プレイヤーXXのメモ」に表示する。

# 成果物(画面)
![Number_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1009061/a0c8d8f3-47c5-e00e-9ccf-591e82726202.png)

# 所感
* ボタン、プルダウン、非同期での画面更新等、いくつか要素があるわりに、デザイン要素が少ないため言語学習に丁度よかった。
* 対戦相手のCPUの思考回路を強化する余裕がなかったのが心残り。上記の画像の通り、今のCPUはお粗末な点があります。改良の余地あり。
* 思いのほか、ソースコード量が多くなった。

# 成果物(ソースコード)
* 参考程度にしてください。軽くは動作確認済みです。  

```html:Number.html
<!DOCTYPE html>
<html>
    <head>
        <title>数字当て</title>
        
        <style>
            body {
                background-color : #eee;
            }
            #start, #judge, #next {
                font-size : 20px;
                background-color : #fff;
                text-align : center;
            }
            #result, #turn {
                font-size : 20px;
                background-color : #fff;
            }
            #numbers {
                font-size : 20px;
            }
            #number0, #number1, #number2 {
                font-size : 20px;
            }
            #player00Info, #player01Info {
                font-size : 20px;
            }
            #memos {
                font-size : 20px;
            }
        </style>
    </head>
    <body>
        <div>
            <div>
                <span id="button"></span>
                <p id="result"></p>
                <p id="turn"></p>
                <p id="numbers"></p>
                <p id="player00Info"></p>
                <p id="player01Info"></p>
                <p id="memos"></p>
            </div>
        </div>
        <script language="JavaScript">
            
            // 数字当て情報
            const MAX_PLAYER = 2;
            const MAX_HAND = 3;
            const MAX_NUM = 9;
            const MIN_NUM = 0;
            const PLAYER_USER = 0;
            const PLAYER_CPU = 1;
            
            // その他
            //const FLAG_DEBUG = true;
            const FLAG_DEBUG = false;
            
            // カード
            function Card(num) {
                // プロパティ
                this.num = num;
            }
            
            // デッキ
            function Deck() {
                // プロパティ
                this.deck = [];
                
                // 初期化処理
                this.init = function() {
                    this.deck = [];
                    return;
                };
                
                // デッキ作成処理
                this.make = function() {
                    let card;
                    for (let num = MIN_NUM; num <= MAX_NUM; num++) {
                        card = new Card(num);
                        this.deck.push(card);
                    }
                    return;
                };
                
                // デッキシャッフル処理
                this.shuffle = function() {
                    let random;
                    let work;
                    for (let loop = 0; loop < this.deck.length; loop++) {
                        random = Math.floor(Math.random() * this.deck.length);
                        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.shuffle = function() {
                    let handInfo = this.getAll();
                    let random;
                    let work;
                    for (let loop = 0; loop < handInfo.hand.length; loop++) {
                        random = Math.floor(Math.random() * handInfo.hand.length);
                        work = handInfo.hand[0];
                        handInfo.hand[0] = handInfo.hand[random];
                        handInfo.hand[random] = work;
                    }
                    return;
                };
            }
            
            // プレイヤー
            function Player() {
                // プロパティ
                this.results = [];
                this.results["win"] = 0;
                this.results["lose"] = 0;
                this.cpu = true;
                
                // 初期化処理
                this.init = function() {
                    return;
                };
                
                // CPUフラグ設定処理
                this.setCpu = function(flag) {
                    // CPUフラグを設定する。trueがCPU。
                    this.cpu = flag;
                    return;
                };
            }
            
            // メモ
            function Memo() {
                // プロパティ
                this.memos = [];
                this.memos["num"] = [];
                this.memos["cnts"] = [];
                
                // 初期化処理
                this.init = function() {
                    this.memos = [];
                    this.memos["num"] = [];
                    this.memos["cnts"] = [];
                };
                
                // 数字セット処理
                this.setNumber = function(number) {
                    this.memos["num"].push(number);
                    return;
                };
                
                // 判定結果セット処理
                this.setResults = function(eat, bite) {
                    this.memos["cnts"]["eat"] = eat;
                    this.memos["cnts"]["bite"] = bite;
                    return;
                };
                
                // メモ全取得処理
                this.getAll = function() {
                    return this;
                };
            }
            
            // 桁数整形処理
            function spacePadding(num){
                return (Array(2).join(" ") + num).slice(-2);
            }
            
            // 桁数整形処理
            function zeroPadding(num){
                return (Array(2).join("0") + num).slice(-2);
            }
            
            // 数値比較処理
            function compare(x, y){
                return x - y;
            }
            
            // 数字当て
            function Number () {
                // プロパティ
                let cntTurn = 0;
                let deck = new Deck();
                let hands = [];
                let players = [];
                let memos = [];
                for (let loop = 0; loop < MAX_PLAYER; loop++) {
                    hands[loop] = new Hand();
                    players[loop] = new Player();
                    memos[loop] = [];
                }
                
                // 初期化処理
                this.init = function() {
                    // ターン数を初期化する。
                    cntTurn = 0;
                    
                    // 各プレーヤーごとにプレイヤー、手札、メモの初期化処理を呼び出す。
                    for (let loop = 0; loop < MAX_PLAYER; loop++) {
                        players[loop].init();
                        hands[loop].init();
                        memos[loop] = [];
                    }
                    
                    // CPUフラグ設定処理を呼び出す。
                    players[PLAYER_USER].setCpu(false);
                    
                    return;
                };
                
                // カードイメージ作成処理
                this.makeCardImg = function(card, playerId, index) {
                    // カードイメージを作成する。
                    let cardImg = "";
                    cardImg += "<span id='card' ";
                    cardImg += "name='" + String(playerId) + "_" + String(index) + "' ";
                    cardImg += "style='color:black; ";
                    cardImg += "background-color:white;'>";
                    cardImg += card.num;
                    cardImg += "</span>";
                    return cardImg;
                };
                
                // 手札表示共通処理
                this.outputHandPCommon = function(playerId, handInfo) {
                    let detail = "";
                    handInfo.hand.forEach(function(card, index) {
                        if (FLAG_DEBUG == true) {
                            // カードイメージ作成処理を呼び出す。
                            //alert("outputHandPCommon card:" + card.num + " playerId:" + playerId + " index:" + index);
                            detail += game.makeCardImg(card, playerId, index);
                        } else {
                            if (players[playerId].cpu == false) {
                                // カードイメージ作成処理を呼び出す。
                                detail += game.makeCardImg(card, playerId, index);
                            } else {
                                detail += "<span id='card' ";
                                detail += "name='" + String(playerId) + "_" + String(index) + "' ";
                                detail += "style='color:black; ";
                                detail += "background-color:black;'>";
                                detail += "&#9824;";
                                detail += "</span>";
                            }
                        }
                        detail += "　";
                    });
                    return detail;
                };
                
                // 手札表示処理
                this.outputHandP = function() {
                    // 各プレーヤーごとに手札表示共通処理を呼び出す。
                    let handInfo = hands[0].getAll();
                    let work = this.outputHandPCommon(0, handInfo);
                    
                    // 処理結果を設定する。
                    let id = "player" + String(zeroPadding(0)) + "Info";
                    document.getElementById(id).innerHTML = work;
                    return;
                };
                
                // 手札自動決定処理
                this.selectHandCpu = function() {
                    // デッキの初期化処理を呼び出す。
                    deck.init();
                    
                    // デッキ作成処理を呼び出す。
                    deck.make();
                    
                    // 作成したデッキをシャッフルする。
                    deck.shuffle();
                    
                    for (let loop = 0; loop < MAX_HAND; loop++) {
                        // デッキからカードをドローする。
                        let card = deck.draw();
                        
                        // 手札セット処理を呼び出す。
                        hands[PLAYER_CPU].set(card);
                    }
                    return;
                };
                
                // 手札手動決定処理
                this.selectHandUser = function() {
                    // デッキの初期化処理を呼び出す。
                    deck.init();
                    
                    // デッキ作成処理を呼び出す。
                    deck.make();
                    
                    // 作成したデッキをシャッフルする。
                    deck.shuffle();
                    
                    for (let loop = 0; loop < MAX_HAND; loop++) {
                        // デッキからカードをドローする。
                        let card = deck.draw();
                        
                        // 手札セット処理を呼び出す。
                        hands[PLAYER_USER].set(card);
                    }
                    return;
                };
                
                // ゲーム終了判定実処理
                this.isFinCore = function(playerId) {
                    // 3EATが存在するか調べる。
                    let detail;
                    let work = memos[playerId].find(function(memo) {
                        detail = memo.getAll();
                        return detail.memos["cnts"]["eat"] == MAX_HAND;
                    });
                    
                    // 存在した場合はTRUEを設定する。
                    let result = false;
                    if (work != undefined) {
                        result = true;
                    }
                    return result;
                };
                
                // ゲーム終了判定処理
                this.isFin = function() {
                    let win = -1;
                    for (let loop = 0; loop < MAX_PLAYER; loop++) {
                        // ゲーム終了判定実処理を呼び出す。
                        result = this.isFinCore(loop);
                        if (result == true) {
                            // 勝利プレイヤーのIDを設定する。
                            win = loop;
                            break;
                        }
                    }
                    return win;
                };
                
                // ゲーム終了処理
                this.fin = function(win) {
                    // 開始ボタンを活性に変更する。
                    document.getElementById("start").disabled = false;
                    
                    // 判定ボタンを非活性に変更する。
                    document.getElementById("judge").disabled = true;
                    
                    // 次へボタンを非活性に変更する。
                    document.getElementById("next").disabled = true;
                    
                    
                    // 表示文言を作成する。
                    let work =  "<span ";
                    work += "style='color:red; ";
                    work += "background-color:white;'>";
                    if (win == PLAYER_USER) {
                        work += "プレイヤー" + zeroPadding(win % MAX_PLAYER + 1) + "の勝ち";
                        players[PLAYER_USER].results["win"]++;
                        players[PLAYER_CPU].results["lose"]++;
                    } else {
                        work += "プレイヤー" + zeroPadding(win % MAX_PLAYER + 1) + "の勝ち";
                        players[PLAYER_CPU].results["win"]++;
                        players[PLAYER_USER].results["lose"]++;
                    }
                    work += "</span>";
                    
                    // 作成した文言を表示する。
                    document.getElementById("turn").innerHTML = work;
                    
                    // 結果表示処理を呼び出す。
                    this.outputResult();
                    return;
                };
                
                // ゲーム開始処理
                this.start = function() {
                    // 初期化処理を呼び出す。
                    this.init();
                    
                    // 開始ボタンを非活性に変更する。
                    document.getElementById("start").disabled = true;
                    
                    // 判定ボタンを活性に変更する。
                    document.getElementById("judge").disabled = false;
                    
                    // 手札自動決定処理を呼び出す。
                    this.selectHandCpu();
                    
                    // 手札手動決定処理を呼び出す。
                    this.selectHandUser();
                    
                    // 手札表示処理を呼び出す。
                    this.outputHandP();
                    
                    // プルダウン表示処理を呼び出す。
                    this.outputPullDown();
                    
                    // メモ表示処理を呼び出す。
                    this.outputMemo();
                    
                    // 手番表示処理を呼び出す。
                    this.outputTurn();
                    return;
                };
                
                // ターン変更処理
                this.changeTurn = function() {
                    // ゲーム終了判定処理を呼び出す。
                    result = game.isFin();
                    if (result != -1) {
                        // ゲーム終了処理を呼び出す。
                        game.fin(result);
                    } else {
                        // ターンを切り替える。
                        cntTurn++;
                        
                        // 手札表示処理を呼び出す。
                        this.outputHandP();
                        
                        // 手番表示処理を呼び出す。
                        this.outputTurn();
                        
                        // 手番によって処理を分岐する。
                        if (players[cntTurn % MAX_PLAYER].cpu == true) {
                            // 手番がCPUである場合
                            
                            // 判定ボタンを非活性に変更する。
                            document.getElementById("judge").disabled = true;
                            
                            // 次へボタンを活性に変更する。
                            document.getElementById("next").disabled = false;
                            
                            // ユーザの次へボタン操作イベント待ち。
		                    // ターン変更処理を呼び出す。
		                    game.next();
                        } else {
                            // 手番がユーザである場合
                            
                            // 判定ボタンを活性に変更する。
                            document.getElementById("judge").disabled = false;
                            
                            // 次へボタンを非活性に変更する。
                            document.getElementById("next").disabled = true;
                            
                            // ユーザのカード選択イベント待ち。
                        }
                    }
                    return;
                };
                
                // 探索処理
                this.search = function(playerId, number) {
                    // 指定した値が存在すれば位置情報を設定する。
                    let handInfo = hands[playerId].getAll();
                    let result = handInfo.hand.findIndex(function(card) {
                        return card.num == number;
                    });
                    //alert("search result=" + result);
                    return result;
                };
                
                // メモ表示処理
                this.outputMemo = function() {
                    // 選んだ数字や判定結果を表示する。
                    let detail;
                    let length = memos[PLAYER_USER].length;
                    let work = "<span>";
                    work += "<span>";
                    work += "プレイヤー" + zeroPadding(PLAYER_USER + 1) + "のメモ　　　　";
                    work += "</span>";
                    work += "<span>";
                    work += "プレイヤー" + zeroPadding(PLAYER_CPU + 1) + "のメモ";
                    work += "</span>";
                    work += "<br>";
                    for (let index = 0; index < length; index++) {
                        for (let playerId = 0; playerId < MAX_PLAYER; playerId++) {
                            if (memos[playerId][index] != undefined) {
                                detail = memos[playerId][index].getAll();
                                work += "<span>";
                                work += "[" + detail.memos["num"] + "] ";
                                work += detail.memos["cnts"]["eat"] + " EAT ";
                                work += detail.memos["cnts"]["bite"] + " BITE  ";
                                work += "</span>";
                                work += "　　　";
                            }
                        }
                        work += "<br>";
                    }
                    work += "</span>";
                    let id = "memos";
                    document.getElementById("memos").innerHTML = work;
                    return;
                };
                
                // 判定共通処理
                this.judgeCommon = function(my, your, numbers) {
                    let result;
                    let cnts = [];
                    cnts["eat"] = 0;
                    cnts["bite"] = 0;
                    let length = memos[my].length;
                    memos[my][length] = new Memo();
                    numbers.forEach(function(number, index) {
                        // 数字セット処理を呼び出す。
                        memos[my][length].setNumber(number);
                        
                        // 探索処理を呼び出す。
                        result = game.search(your, number);
                        if (result != -1) {
                            if (result == index) {
                                // 位置が合っているためEAT。
                                cnts["eat"]++;
                            } else {
                                // 位置が合っていないためBITE。
                                cnts["bite"]++;
                            }
                        } else {
                            // ハズレ
                        }
                    });
                    
                    // 判定結果セット処理を呼び出す。
                    memos[my][length].setResults(cnts["eat"], cnts["bite"]);
                    
                    // メモ表示処理を呼び出す。
                    this.outputMemo();
                    
                    // ターン変更処理を呼び出す。
                    game.changeTurn();
                    return;
                };
                
                // 並び替え処理
                this.randomSort = function(str) {
                    let random;
                    let work;
                    for (let loop = 0; loop < str.length; loop++) {
                        random = Math.floor(Math.random() * str.length);
                        work = str[0];
                        str[0] = str[random];
                        str[random] = work;
                    }
                    return str;
                };
                
                // 数字自動選択処理
                this.selectNumberCpu = function() {
                    let card;
                    let numbers = [];
                    let length;
                    let detail;
                    let notHits = [];
                    let hits = [];
                    let work;
                    let work2;
                    length = memos[PLAYER_CPU].length;
                    
                    // 0EAT、OBITEとなった時の数値を洗い出す。
                    work = memos[PLAYER_CPU].filter(function(memo) {
                        detail = memo.getAll();
                        return (detail.memos["cnts"]["eat"] == 0) && (detail.memos["cnts"]["bite"] == 0);
                    });
                    if (work != undefined) {
                        work.forEach(function(data) {
                            data.getAll();
                            notHits.push(data.memos["num"][0]);
                            notHits.push(data.memos["num"][1]);
                            notHits.push(data.memos["num"][2]);
                        });
                    }
                    
                    // EAT、BITEの合計でMAX_HANDとなった時の数値を洗い出す。
                    work = memos[PLAYER_CPU].find(function(memo) {
                        detail = memo.getAll();
                        return detail.memos["cnts"]["eat"] + detail.memos["cnts"]["bite"] == MAX_HAND;
                    });
                    if (work != undefined) {
                        work.getAll();
                        hits.push(work.memos["num"][0]);
                        hits.push(work.memos["num"][1]);
                        hits.push(work.memos["num"][2]);
                    }
                    
                    while (1) {
                        if (hits.length != 0) {
                            // 3つまで絞り込んでいる場合
                            
                            // 並び替え処理を呼び出す。
                            numbers = this.randomSort(hits);
                        } else if (cntTurn < 6) {
                            //alert("序盤 : " + cntTurn);
                            
                            // 0～9の数字をランダムで取得する。(デッキのシャッフル処理を流用。)
                            deck.init();
                            deck.make();
                            deck.shuffle();
                            for (let loop = 0; loop < MAX_HAND; loop++) {
                                card = deck.draw();
                                work = memos[PLAYER_CPU].find(function(memo) {
                                    detail = memo.getAll();
                                    work2 = detail.memos["num"].find(function(number) {
                                        // 既に宣言済みの数字である場合
                                        return number == card.num;
                                    });
                                    if (work2 != undefined) {
                                        // 既に宣言済みの数字である場合
                                        return true;
                                    }
                                });
                                if (work != undefined) {
                                    // 既に宣言済みの数字である場合
                                    loop--;
                                    continue;
                                }
                                
                                numbers[loop] = card.num;
                            }
                        } else if (notHits.length < MAX_HAND * 2) {
                            //alert("候補が多い場合 : " + notHits.length);
                            
                            while (1) {
                                // 0～9の数字をランダムで取得する。(デッキのシャッフル処理を流用。)
                                deck.init();
                                deck.make();
                                deck.shuffle();
                                for (let loop = 0; loop < MAX_HAND; loop++) {
                                    card = deck.draw();
                                    work = notHits.filter(function(notHit) {
                                        return notHit == card.num;
                                    });
                                    if (work != "") {
                                        // 使用されていないと確定している数値の場合は候補から外す。
                                        loop--;
                                        continue;
                                    }
                                    
                                    numbers[loop] = card.num;
                                }
                                
                                numbers.sort(this.compare);
                                //alert("numbers:" + numbers);
                                work = memos[PLAYER_CPU].find(function(memo) {
                                    detail = memo.getAll();
                                    work2 = detail.memos["num"].slice();
                                    work2.sort(this.compare);
                                    //alert("work2:" + work2);
                                    let loop;
                                    for (loop = 0; loop < MAX_HAND; loop++) {
                                        if (numbers[loop] != work2[loop]) {
                                            // 既に宣言済みの数字である場合(並びは不問)
                                            break;
                                        }
                                    }
                                    if (loop >= MAX_HAND) {
                                        return false;
                                    } else {
                                        // 既に宣言済みの数字である場合(並びは不問)
                                        return true;
                                    }
                                });
                                if (work != undefined) {
                                    //alert("宣言済の組み合わせでなかった場合");
                                    
                                    //alert("numbers:" + numbers);
                                    work = memos[PLAYER_CPU].find(function(memo) {
                                        //alert("false");
                                        detail = memo.getAll();
                                        if (detail.memos["cnts"]["eat"] + detail.memos["cnts"]["bite"] >= 2) {
                                            // EAT、BITEの合計が2以上である場合
                                            work2 = numbers.find(function(number) {
                                                for (let loop = 0; loop < MAX_HAND; loop++) {
                                                    if (number == detail.memos["num"][loop]) {
                                                        // 当たりの数字である可能性があるため除外する。
                                                        
                                                        //alert("index:" + loop + "  num:" + detail.memos["num"][loop]);
                                                        return true;
                                                    }
                                                }
                                            });
                                            if (work2 == undefined) {
                                                //alert("false");
                                                return false;
                                            } else {
                                                // 当たりの数字である可能性があるため除外する。
                                                
                                                //alert("true");
                                                return true;
                                            }
                                        }
                                    });
                                    if (work == undefined) {
                                        break;
                                    }
                                }
                            }
                        } else {
                            //alert("候補が少ない場合 : " + notHits.length);
                            
                            // 0～9の数字をランダムで取得する。(デッキのシャッフル処理を流用。)
                            deck.init();
                            deck.make();
                            deck.shuffle();
                            for (let loop = 0; loop < MAX_HAND; loop++) {
                                card = deck.draw();
                                work = notHits.filter(function(notHit) {
                                    return notHit == card.num;
                                });
                                if (work != "") {
                                    // 使用されていないと確定している数値の場合は候補から外す。
                                    loop--;
                                    continue;
                                }
                                numbers[loop] = card.num;
                            }
                        }
                        
                        work = memos[PLAYER_CPU].find(function(memo) {
                            detail = memo.getAll();
                            work = numbers.filter(function(number, index) {
                                return number == detail.memos["num"][index];
                            });
                            return work.length == MAX_HAND;
                        });
                        if (work == undefined) {
                            //alert("宣言済の組み合わせでなかった場合");
                            break;
                        }
                    }
                    return numbers;
                };
                
                // 判定処理
                this.judgeCpu = function(numbers) {
                    // 判定共通処理を呼び出す。
                    game.judgeCommon(PLAYER_CPU, PLAYER_USER, numbers);
                    return;
                };
                
                // 判定処理
                this.judgeUser = function() {
                    // プルダウンで選んだ数字を取得する。
                    let pullDown;
                    let numbers = [];
                    for (let index = 0; index < MAX_HAND; index++) {
                        pullDown = document.getElementById("number" + index);
                        numbers[index] = pullDown.value;
                    }
                    
                    // 判定共通処理を呼び出す。
                    game.judgeCommon(PLAYER_USER, PLAYER_CPU, numbers);
                    return;
                };
                
                // 判定結果セット処理
                this.setResults = function(eat, bite) {
                    this.memos["cnts"]["eat"] = eat;
                    this.memos["cnts"]["bite"] = bite;
                    return;
                };
                
                // ターン進行処理
                this.next = function() {
                    let numbers = [];
                    // 数字自動選択処理を呼び出す。
                    numbers = this.selectNumberCpu();
                    
                    // 判定処理を呼び出す。
                    this.judgeCpu(numbers);
                    return;
                };
                
                // プルダウン表示処理
                this.outputPullDown = function() {
                    let work = "NUMBER : ";
                    let select = "";
                    for (let index = 0; index < MAX_HAND; index++) {
                        work += "<select id='number" + String(index) + "'>";
                        for (let loop = 0; loop <= MAX_NUM; loop++) {
                            if (loop == index) {
                                select = " selected";
                            } else {
                                select = "";
                            }
                            work += "<option value='" + String(loop) + "'"
                            work += select + ">" + String(loop) + "</option>";
                        }
                        work += "</select>";
                    }
                    document.getElementById("numbers").innerHTML = work;
                    return;
                };
                
                // 結果表示処理
                this.outputResult = function() {
                    let work = "<p id='result' style='color:red'>";
                    for (let loop = 0; loop < MAX_PLAYER; loop++) {
                        work += "プレイヤー" + String(zeroPadding(loop + 1)) + "：";
                        work += String(spacePadding(players[loop].results["win"])) + "勝 ";
                        work += String(spacePadding(players[loop].results["lose"])) + "負" + "<br>";
                    }
                    work += "</p>";
                    document.getElementById("result").innerHTML = work;
                    return;
                };
                
                // 手番表示処理
                this.outputTurn = function() {
                    let work =  "<span>";
                    work += "プレイヤー" + zeroPadding(cntTurn % MAX_PLAYER + 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='judge' value='判定' disabled=true onclick='game.judgeUser()'>";
                    work += "<input type='button' id='next' value='次へ' disabled=true onclick='game.next()'>";
                    work += "</span>";
                    document.getElementById("button").innerHTML = work;
                    return;
                };
            }
            
            // 初期化処理を呼び出す。
            let game = new Number();
            game.init();
            
            // ボタン表示処理を呼び出す。
            game.outputButton();
            
            // 結果表示処理を呼び出す。
            game.outputResult();
        </script>
    </body>
</html>
```