1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

IPFactory(現役生)Advent Calendar 2024

Day 7

【JavaScript】【初心者】チンチロを作った話

Posted at

はじめに

この記事でわかる・できること

  • 簡単なサイコロゲームが作れるようになる
  • 開発初心者に対して:JavaScriptでの開発に慣れることができる
  • チンチロのルール説明はしないです

この記事の対象者

  • JavaScriptに触れたばかり人
  • 開発を始めたばかりの人
  • サイコロゲームを作りたい人

動作環境・使用するツールや言語

  • OS
    • Windows
  • ツール
    • VSCode
  • 言語
    • JavaScript

※私が制作した際の環境です。別環境で制作・実行可能かは検証していないです。

1対1でチンチロを作ろう

乱数を利用してサイコロを表示する

何にしてもサイコロを表示させないと話が始まらない!
ということで
https://janken.asotetu.work/js_saikoro/
こちらの記事を参考にしてサイコロの画像を乱数を利用して表示しました。

・Math.random( )で乱数をつくり、Math.floor( )で小数点を切り捨てる
・ input type=”button” タグでボタンを設置できる
・関数を作り、ボタンの onclick を使うことで、ボタンを押してJavaScriptプログラムを動作させることができる
・document.getElementById( “id名” ).innerHTML =で、idで指定した場所の、文字を書き換えたりタグを書き換えたりできる
・document.getElementById( “id名” ).src =で、idで指定した場所の画像を差し替えることができる

この記事を最後まで見て、同じ要領でこれをidを変えて親と子で3つずつ用意します。
まだ、表示されないものもありますが、今は気にしないでください。後ほど結果を表示するのに使います。

サイコロの初期表示とボタン
<body>
    <h1></h1>
    <p>
        <img id="sainome1" src="1.jpg" width="50" height="50">
        <img id="sainome2" src="1.jpg" width="50" height="50">
        <img id="sainome3" src="1.jpg" width="50" height="50">
    </p>
    <p><button id="saikoroButton" onclick="Saikoro();">サイコロを振る</button></p>
    <p id="kekka"></p>
    <p id="yaku"></p>
    <p id="counter"></p>
    
    <h1></h1>
    <p>
        <img id="sainome4" src="1.jpg" width="50" height="50">
        <img id="sainome5" src="1.jpg" width="50" height="50">
        <img id="sainome6" src="1.jpg" width="50" height="50">
    </p>
    <p><button id="saikoroButtonNew" onclick="SaikoroNew();" disabled>サイコロを振る</button></p>
    <p id="kekkaNew"></p>
    <p id="yakuNew"></p>
    <p id="counterNew"></p>
    <p id="result"></p>
    
    <script src="main.js"></script>
</body>

チンチロは三回まで(もしくは役ができるまで)しかサイコロが振れないので、その制限をつけつつJavaScriptで動作を記述してきます。役が成り立った際の処理はのちほど。
また、子が振り終わってからでないと、親のサイコロを振れないようにします。

サイコロを三回まで振る
let saikoroCount = 0;
const maxSaikoroCount = 3;

let saikoroCountNew = 0;
const maxSaikoroCountNew = 3;

let ChildSaikoroDone = false;   //子と親が振り終わったかどうか
let ParentSaikoroDone = false;

//子のサイコロ
function Saikoro(){
    if(saikoroCount < maxSaikoroCount){
        saikoroCount++;
        let results = [];
        let images = [];
        
        //サイコロ三つ振る処理
        for (let i = 0; i<3; i++){
            let saikoro = Math.floor( Math.random() *6) +1; //ランダムで1~6の数字を作る
            results.push(saikoro);
            images.push(saikoro + ".jpg");
        }

        //結果の表示
        document.getElementById("kekka").innerHTML = `サイコロの結果: ${results.join(",")}`;
        document.getElementById("sainome1").src = images[0];
        document.getElementById("sainome2").src = images[1];
        document.getElementById("sainome3").src = images[2];
        document.getElementById("counter").innerHTML = saikoroCount+"回目";

        //3回振ってボタン無効
        if(saikoroCount >= maxSaikoroCount){
            document.getElementById("saikoroButton").disabled = true;
            ChildSaikoroDone = true;
        }

        //親ボタンを有効にする
        if(ChildSaikoroDone){
            document.getElementById("saikoroButtonNew").disabled = false;
    }
}

//親のサイコロ
function SaikoroNew(){
    if(saikoroCountNew < maxSaikoroCountNew){
        saikoroCountNew++;
        let results = [];
        let images = [];
        
        //サイコロ三つ振る
        for (let i = 0; i<3; i++){
            let saikoro = Math.floor( Math.random() *6) +1; //ランダムで1~6の数字を作る
            results.push(saikoro);
            images.push(saikoro + ".jpg");
        }

        //結果の表示
        document.getElementById("kekkaNew").innerHTML = `サイコロの結果: ${results.join(",")}`;
        document.getElementById("sainome4").src = images[0];
        document.getElementById("sainome5").src = images[1];
        document.getElementById("sainome6").src = images[2];
        document.getElementById("counterNew").innerHTML = saikoroCountNew+"回目"


        //3回振ってボタンを無効化
        if(saikoroCount >= maxSaikoroCount){
            document.getElementById("saikoroButtonNew").disabled = true;
            ParentSaikoroDone = true;
        }
    }
}

振った回数と最大回数(3回)の変数を用意します。
子と親のサイコロそれぞれで関数を作成し、
サイコロ三つ分すべての結果を入れるために、空の配列を用意します。
for文でサイコロを振る処理を三回繰り返し、一回ごと先ほど用意した配列に入れて、結果を表示します。

ここまででサイコロ三つを三回まで振る機能ができました。

また、サイコロを振る順番については、最初から親のサイコロを振れないようにしておき、子が振り終わったタイミングで親のボタンを有効化します。

所持金・賭け金を取得する

所持金と賭け金について記述します。

金額関連
<p id="childGold">所持金: 1000</p>
<h2>賭け金</h2>
    <p>
        賭け金: <input type="number" id="betAmount" value="100" min="1">
    </p>


<p id="parentGold">所持金: 1000</p>

HTML内の子と親の中にそれぞれ所持金を記述してください。賭け金は子の中に。

そしてJavaScript内では、初期値の設定と、現在の所持金の取得を行います。

初期設定
let childGold = 1000
let parentGold = 1000

function getBetAmount(){
    //賭け金の取得
    let betAmount = parseInt(document.getElementById("betAmount").value);
    //賭け金が無効な場合(負の値とか)の処理
    return isNaN(betAmount) || betAmount <= 0 ? 100 :betAmount;
}

これで初期設定と賭け金の取得ができます。
しかし、現状役の判定や勝敗がないので所持金は変動しません。

リセットボタンの実装

毎回ブラウザを更新してリセットするのは面倒なので、リセットボタンを実装します。

リセットボタン
<p><input type="button" value="リセット" onclick="window.location.reload()"></p>

現段階でのコード

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>チンチロ</title>
</head>
<body>
    <h1></h1>
    <p>
        <img id="sainome1" src="1.jpg" width="50" height="50">
        <img id="sainome2" src="1.jpg" width="50" height="50">
        <img id="sainome3" src="1.jpg" width="50" height="50">
    </p>
    <p><button id="saikoroButton" onclick="Saikoro();">サイコロを振る</button></p>
    <p id="kekka"></p>
    <p id="yaku"></p>
    <p id="counter"></p>
    <p id="childGold">所持金: 1000</p>
    <h2>賭け金</h2>
        <p> <!--valueは初期値-->
            賭け金: <input type="number" id="betAmount" value="100" min="1">
        </p>
    <h1></h1>
    <p>
        <img id="sainome4" src="1.jpg" width="50" height="50">
        <img id="sainome5" src="1.jpg" width="50" height="50">
        <img id="sainome6" src="1.jpg" width="50" height="50">
    </p>
    <p><button id="saikoroButtonNew" onclick="SaikoroNew();" disabled>サイコロを振る</button></p>
    <p id="kekkaNew"></p>
    <p id="yakuNew"></p>
    <p id="counterNew"></p>
    <p id="parentGold">所持金: 1000</p>
    <p id="result"></p>
    
    <p><input type="button" value="リセット" onclick="window.location.reload()"></p>
    
    <script src="main.js"></script>
</body>
</html>
let saikoroCount = 0;
const maxSaikoroCount = 3;

let saikoroCountNew = 0;
const maxSaikoroCountNew = 3;

let ChildSaikoroDone = false;   //子と親が振り終わったかどうか
let ParentSaikoroDone = false;

let childGold = 1000
let parentGold = 1000

function getBetAmount(){
    //賭け金の取得
    let betAmount = parseInt(document.getElementById("betAmount").value);
    //賭け金が無効な場合(負の値とか)の処理
    return isNaN(betAmount) || betAmount <= 0 ? 100 :betAmount;
}

//子のサイコロ
function Saikoro(){
    if(saikoroCount < maxSaikoroCount){
        saikoroCount++;
        let results = [];
        let images = [];
        
        //サイコロ三つ振る処理
        for (let i = 0; i<3; i++){
            let saikoro = Math.floor( Math.random() *6) +1; //ランダムで1~6の数字を作る
            results.push(saikoro);
            images.push(saikoro + ".jpg");
        }
        
        //結果の表示
        document.getElementById("kekka").innerHTML = `サイコロの結果: ${results.join(",")}`;
        document.getElementById("sainome1").src = images[0];
        document.getElementById("sainome2").src = images[1];
        document.getElementById("sainome3").src = images[2];
        document.getElementById("counter").innerHTML = saikoroCount+"回目"

        //3回振ってボタン無効
        if(saikoroCount >= maxSaikoroCount){
            document.getElementById("saikoroButton").disabled = true;
            ChildSaikoroDone = true; 
        }
        
        //親ボタンを有効にする
        if(ChildSaikoroDone){
            document.getElementById("saikoroButtonNew").disabled = false;
        } 
    }
}

//親のサイコロ
function SaikoroNew(){
    if(saikoroCountNew < maxSaikoroCountNew && ChildSaikoroDone){
        saikoroCountNew++;
        let results = [];
        let images = [];
        
        //サイコロ三つ振る
        for (let i = 0; i<3; i++){
            let saikoro = Math.floor( Math.random() *6) +1; //ランダムで1~6の数字を作る
            results.push(saikoro);
             images.push(saikoro + ".jpg");
        }
        
        //結果の表示
        document.getElementById("kekkaNew").innerHTML = `サイコロの結果: ${results.join(",")}`;
        document.getElementById("sainome4").src = images[0];
        document.getElementById("sainome5").src = images[1];
        document.getElementById("sainome6").src = images[2];
        document.getElementById("counterNew").innerHTML = saikoroCountNew+"回目"

        //3回振ってボタンを無効化
        if(saikoroCount >= maxSaikoroCount){
            document.getElementById("saikoroButtonNew").disabled = true;
            ParentSaikoroDone = true;
        }
    }
}

サイコロの出目に応じた役の判定

ここからが重いです。判定方法とその役の強さの比較、勝敗判定と、役によって倍率が変わるので、それに応じた所持金更新と続きます。

まずは出目に応じた役を判定して表示させるところから始めます。
ただ、その前に私が今回使っている役について紹介しようと思います。

役名 配当
ピンゾロ 5倍
アラシ(ゾロ目) 3倍
シゴロ 2倍
通常役(出目) 1倍
役無し 1倍
ヒフミ ‐2倍

通常役は三つの出目のうち二つが揃っていた場合、残りの一つを出目にするものです。

他の条件として

  • 役が被った場合(引き分け)は親が勝ちます
  • アラシは数字の大きいほうが勝ちます
  • 通常役(出目)は数字の大きいほうが勝ちます
  • 倍付のヒフミとシゴロ以上の役が被った場合には支払額が増えます
    • 例えば親がピンゾロ、子がヒフミを出したら子は賭け金の10倍を払います

役判定関数の作成

役判定
function 役判定(results){
    let shigoro = [4,5,6];
    let hihumi = [1,2,3];
    
    if(results[0] == results[1] && results[1] == results[2] ) //ゾロ目のとき
        if(results[0] == 1){
            return "ピンゾロ"
        }else if(results[0] == 2){
            return "2のアラシ"
        }else if(results[0] == 3){
            return "3のアラシ"
        }else if(results[0] == 4){
            return "4のアラシ"
        }else if(results[0] == 5){
            return "5のアラシ"
        }else{
            return "6のアラシ"
        }
    }else if(特殊役(results,shigoro)){
        return "シゴロ"
    }else if(特殊役(results,hihumi)){
        return "ヒフミ"
        
    }else if(results[0] == results[1]){ //通常役
        return results[2] 
    }else if(results[0] == results[2]){
        return results[1]
    }else if(results[1] == results[2]){
        return results[0]
        
    }else{
        return "役無し"
    }
}

役判定関数はシゴロとヒフミ以外はそのまま判定できます。シゴロとヒフミは三つのサイコロの順番が関係なく、その数字が含まれているかで判断するので一度別の処理を挟む必要があります。

その処理を特殊役という関数で行うので、以下にコードと説明を載せます。

特殊役
function 特殊役(array,elements){
    return elements.every(elements => array.includes(elements));
}

この関数ではeveryメソッドを使っています。
every メソッドとは、配列の全ての要素がテスト関数を満たしていればtrueを返すメソッドです。
これを使って配列Aの全ての要素が配列Bの各要素に含まれているかをテストします。
詳細は参考資料に添付します。

役判定関数を子と親のサイコロの関数の中に入れる

役判定と表示
//子
let yaku = 役判定(results);
document.getElementById("yaku").innerHTML = "役:"+yaku; 

//親
let yaku = 役判定(results);
document.getElementById("yakuNew").innerHTML = "役:"+yaku;  

そして3回サイコロを振ったら振れなくなることに加えて、役が出ても振れなくなるようにします。
子と親のサイコロ関数の中に追記してください。

//子のサイコロ
//役が出るか、3回振ってボタン無効
if(yaku !== "役無し" || saikoroCount >= maxSaikoroCount){
    document.getElementById("saikoroButton").disabled = true;
    ChildSaikoroDone = true; 
}

//親のサイコロ
//役が出るか、3回振ってボタンを無効化
if(yaku !== "役無し" || saikoroCount >= maxSaikoroCount){
    document.getElementById("saikoroButtonNew").disabled = true;
    ParentSaikoroDone = true;
}

役ごとの強さの設定

これは勝敗判定の際に役の比較をしやすくするために行います。

役の強さ
function 役の強さ(yaku){
    switch(yaku){
        case "ピンゾロ":return 14; 
        case "6のアラシ":return 13;
        case "5のアラシ":return 12;
        case "4のアラシ":return 11;
        case "3のアラシ":return 10;
        case "2のアラシ":return 9;
        case "シゴロ":return 8;
        case "6":return 7;
        case "5":return 6;
        case "4":return 5;
        case "3":return 4;
        case "2":return 3;
        case "1":return 2;
        case "役無し":return 1;
        case "ヒフミ":return 0;
        default:return -1;
    }
}

今回はSwitch文を使って役ごとに数値を返しています。
数値が大きいほど強い役です。

ここまでのコード

let saikoroCount = 0;
const maxSaikoroCount = 3;

let saikoroCountNew = 0;
const maxSaikoroCountNew = 3;

let ChildSaikoroDone = false;   //子と親が振り終わったかどうか
let ParentSaikoroDone = false;

let childGold = 1000
let parentGold = 1000

function getBetAmount(){
    //賭け金の取得
    let betAmount = parseInt(document.getElementById("betAmount").value);
    //賭け金が無効な場合(負の値とか)の処理
    return isNaN(betAmount) || betAmount <= 0 ? 100 :betAmount;
}

//子のサイコロ
function Saikoro(){
    if(saikoroCount < maxSaikoroCount){
        saikoroCount++;
        let results = [];
        let images = [];
        
        //サイコロ三つ振る処理
        for (let i = 0; i<3; i++){
            let saikoro = Math.floor( Math.random() *6) +1; //ランダムで1~6の数字を作る
            results.push(saikoro);
            images.push(saikoro + ".jpg");
        }
        
        //結果の表示
        document.getElementById("kekka").innerHTML = `サイコロの結果: ${results.join(",")}`;
        document.getElementById("sainome1").src = images[0];
        document.getElementById("sainome2").src = images[1];
        document.getElementById("sainome3").src = images[2];
        document.getElementById("counter").innerHTML = saikoroCount+"回目"
        
        //役判定と表示
        let yaku = 役判定(results);
        document.getElementById("yaku").innerHTML = "役:"+yaku;  
        
        //役が出るか、3回振ってボタン無効
        if(yaku !== "役無し" || saikoroCount >= maxSaikoroCount){
            document.getElementById("saikoroButton").disabled = true;
            ChildSaikoroDone = true; 
        }
        
        //親ボタンを有効にする
        if(ChildSaikoroDone){
            document.getElementById("saikoroButtonNew").disabled = false;
        } 
    }
}

//親のサイコロ
function SaikoroNew(){
    if(saikoroCountNew < maxSaikoroCountNew && ChildSaikoroDone){
        saikoroCountNew++;
        let results = [];
        let images = [];
        
        //サイコロ三つ振る
        for (let i = 0; i<3; i++){
            let saikoro = Math.floor( Math.random() *6) +1; //ランダムで1~6の数字を作る
            results.push(saikoro);
             images.push(saikoro + ".jpg");
        }
        
        //結果の表示
        document.getElementById("kekkaNew").innerHTML = `サイコロの結果: ${results.join(",")}`;
        document.getElementById("sainome4").src = images[0];
        document.getElementById("sainome5").src = images[1];
        document.getElementById("sainome6").src = images[2];
        document.getElementById("counterNew").innerHTML = saikoroCountNew+"回目"
        
        //役判定と表示
        let yaku = 役判定(results);
        document.getElementById("yakuNew").innerHTML = "役:"+yaku;
        
        //役が出るか、3回振ってボタンを無効化
        if(yaku !== "役無し" || saikoroCount >= maxSaikoroCount){
            document.getElementById("saikoroButtonNew").disabled = true;
            ParentSaikoroDone = true;
        }
    }
}

function 特殊役(array,elements){
    return elements.every(elements => array.includes(elements));
}

function 役判定(results){
    let shigoro = [4,5,6];
    let hihumi = [1,2,3];
    if(results[0] == results[1] && results[1] == results[2] ){
        if(results[0] == 1){
            return "ピンゾロ"
        }else if(results[0] == 2){
            return "2のアラシ"
        }else if(results[0] == 3){
            return "3のアラシ"
        }else if(results[0] == 4){
            return "4のアラシ"
        }else if(results[0] == 5){
            return "5のアラシ"
        }else{
            return "6のアラシ"
        }
    }else if(特殊役(results,shigoro)){
        return "シゴロ"
    }else if(特殊役(results,hihumi)){
        return "ヒフミ"
    }else if(results[0] == results[1]){
        return results[2] 
    }else if(results[0] == results[2]){
        return results[1]
    }else if(results[1] == results[2]){
        return results[0]
    }else{
        return "役無し"
    }
}

function 役の強さ(yaku){
    switch(yaku){
        case "ピンゾロ":return 14; 
        case "6のアラシ":return 13;
        case "5のアラシ":return 12;
        case "4のアラシ":return 11;
        case "3のアラシ":return 10;
        case "2のアラシ":return 9;
        case "シゴロ":return 8;
        case "6":return 7;
        case "5":return 6;
        case "4":return 5;
        case "3":return 4;
        case "2":return 3;
        case "1":return 2;
        case "役無し":return 1;
        case "ヒフミ":return 0;
        default:return -1;
    }
}

勝敗判定の実装

まず準備をします。
賭け金と役を取得し、役を数値変換します。

勝敗判定準備

function 勝敗判定(){
    //賭け金取得
    let betAmount = getBetAmount();
    //役を取得
    const childYaku = document.getElementById("yaku").innerHTML.replace('役:','');
    const parentYaku = document.getElementById("yakuNew").innerHTML.replace('役:','');
    //役を数値変換
    let childValue = 役の強さ(childYaku);
    let parentValue = 役の強さ(parentYaku);
}

勝敗判定

ここからが大変です。
勝敗判定をするとともに、親と子の役に応じて賭け金のやりとりをします。
例えば親が勝ちの場合、子がヒフミで親がピンゾロなら10倍、子が役無しで親がシゴロなら2倍、子がヒフミで親がアラシなら6倍という風に、すべてのパターンに対応できるようにします。
こちらがコードになります。

勝敗判定
//勝敗判定
    if(childValue > parentValue){   //子勝ち
        if(parentValue == 0){   //親ヒフミで
            if(childValue == 14){   //ピンゾロ
                childGold += betAmount * 10;
                parentGold -= betAmount * 10;
                document.getElementById("result").innerHTML = "子の勝ち";
            } else if (childValue == 13 || childValue == 12 || childValue == 11 || childValue == 10 || childValue == 9){    //アラシ
                childGold += betAmount * 6;
                parentGold -= betAmount * 6;
                document.getElementById("result").innerHTML = "子の勝ち";
            } else if(childValue == 8){    //シゴロ
                childGold += betAmount * 4;
                parentGold -= betAmount * 4;
                document.getElementById("result").innerHTML = "子の勝ち";
            } else {    //ヒフミと出目
                childGold += betAmount * 2;
                parentGold -= betAmount * 2;
                document.getElementById("result").innerHTML = "子の勝ち";
            }
        } else if(childValue == 14){   //ピンゾロ
            childGold += betAmount * 5;
            parentGold -= betAmount * 5;
            document.getElementById("result").innerHTML = "子の勝ち";
        } else if (childValue == 13 || childValue == 12 || childValue == 11 || childValue == 10 || childValue == 9){    //アラシ
            childGold += betAmount * 3;
            parentGold -= betAmount * 3;
            document.getElementById("result").innerHTML = "子の勝ち";
        } else if(childValue == 8){    //シゴロ
            childGold += betAmount * 2;
            parentGold -= betAmount * 2;
            document.getElementById("result").innerHTML = "子の勝ち";
        } else {
            childGold += betAmount;
            parentGold -= betAmount;
            document.getElementById("result").innerHTML = "子の勝ち";
        }
    } else { //親の勝ち
        if(childValue == 0){    //子がヒフミ
            if(parentValue == 14){  //親ピンゾロ
                childGold -= betAmount * 10;
                parentGold += betAmount * 10;
                document.getElementById("result").innerHTML = "親の勝ち";
            } else if(parentValue == 13 || parentValue == 12 || parentValue == 11 || parentValue == 10 ||parentValue == 9){    //アラシ
                childGold -= betAmount * 6;
                parentGold += betAmount * 6;
                document.getElementById("result").innerHTML = "親の勝ち";
            } else if(parentValue == 8){    //シゴロ
                childGold -= betAmount * 4;
                parentGold += betAmount * 4;
                document.getElementById("result").innerHTML = "親の勝ち";
            } else{     //ヒフミと出目
                childGold -= betAmount * 2;
                parentGold += betAmount * 2;
                document.getElementById("result").innerHTML = "親の勝ち";
            }
        } else if(parentValue == 14){  //ヒフミ無し親ピンゾロ
            childGold -= betAmount * 5;
            parentGold += betAmount * 5;
            document.getElementById("result").innerHTML = "親の勝ち";
        } else if(parentValue == 13 || parentValue == 12 || parentValue == 11 || parentValue == 10 ||parentValue == 9){    //アラシ
            childGold -= betAmount * 3;
            parentGold += betAmount * 3;
            document.getElementById("result").innerHTML = "親の勝ち";
        } else if(parentValue == 8){    //シゴロ
            childGold -= betAmount * 2;
            parentGold += betAmount * 2;
            document.getElementById("result").innerHTML = "親の勝ち";
        } else{     //出目
            childGold -= betAmount;
            parentGold += betAmount;
            document.getElementById("result").innerHTML = "親の勝ち";
        }
    }

大変ですが、やっていることは役に応じてif文で条件を変え、条件に応じた倍率を適用するだけです。

所持金の更新

勝敗判定の倍率を踏まえてそれぞれの所持金を更新します。

所持金の更新
document.getElementById("childGold").innerHTML = `所持金: ${childGold}`;
document.getElementById("parentGold").innerHTML = `所持金: ${parentGold}`;

ここまでで完成!

完成したコード

HTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>チンチロ</title>
</head>

<body>
    <h1></h1>
    <p>
        <img id="sainome1" src="1.jpg" width="50" height="50">
        <img id="sainome2" src="1.jpg" width="50" height="50">
        <img id="sainome3" src="1.jpg" width="50" height="50">
    </p>
    <p><button id="saikoroButton" onclick="Saikoro();">サイコロを振る</button></p>
    <p id="kekka"></p>
    <p id="yaku"></p>
    <p id="counter"></p>
    <p id="childGold">所持金: 1000</p>
    
    <h2>賭け金</h2>
    <p> <!--valueは初期値-->
        賭け金: <input type="number" id="betAmount" value="100" min="1">
    </p>
        
    <h1></h1>
    <p>
        <img id="sainome4" src="1.jpg" width="50" height="50">
        <img id="sainome5" src="1.jpg" width="50" height="50">
        <img id="sainome6" src="1.jpg" width="50" height="50">
    </p>
    <p><button id="saikoroButtonNew" onclick="SaikoroNew();" disabled>サイコロを振る</button></p>
    <p id="kekkaNew"></p>
    <p id="yakuNew"></p>
    <p id="counterNew"></p>
    <p id="parentGold">所持金: 1000</p>
    <p id="result"></p>
    
    <p><input type="button" value="リセット" onclick="window.location.reload()"></p>
    
    <script src="main.js"></script>
</body>
</html>
JavaScript
let saikoroCount = 0;
const maxSaikoroCount = 3;

let saikoroCountNew = 0;
const maxSaikoroCountNew = 3;

let ChildSaikoroDone = false;   //子と親が振り終わったかどうか
let ParentSaikoroDone = false;

let childGold = 1000
let parentGold = 1000

function getBetAmount(){
    //賭け金の取得
    let betAmount = parseInt(document.getElementById("betAmount").value);
    //賭け金が無効な場合(負の値とか)の処理
    return isNaN(betAmount) || betAmount <= 0 ? 100 :betAmount;
}

//子のサイコロ
function Saikoro(){
    if(saikoroCount < maxSaikoroCount){
        saikoroCount++;
        let results = [];
        let images = [];
        
        //サイコロ三つ振る処理
        for (let i = 0; i<3; i++){
            let saikoro = Math.floor( Math.random() *6) +1; //ランダムで1~6の数字を作る
            results.push(saikoro);
            images.push(saikoro + ".jpg");
        }
        
        //結果の表示
        document.getElementById("kekka").innerHTML = `サイコロの結果: ${results.join(",")}`;
        document.getElementById("sainome1").src = images[0];
        document.getElementById("sainome2").src = images[1];
        document.getElementById("sainome3").src = images[2];
        document.getElementById("counter").innerHTML = saikoroCount+"回目"
        
        //役判定と表示
        let yaku = 役判定(results);
        document.getElementById("yaku").innerHTML = "役:"+yaku;  
        
        //役が出るか、3回振ってボタン無効
        if(yaku !== "役無し" || saikoroCount >= maxSaikoroCount){
            document.getElementById("saikoroButton").disabled = true;
            ChildSaikoroDone = true; 
        }
        
        //親ボタンを有効にする
        if(ChildSaikoroDone){
            document.getElementById("saikoroButtonNew").disabled = false;
        } 
    }
}

//親のサイコロ
function SaikoroNew(){
    if(saikoroCountNew < maxSaikoroCountNew && ChildSaikoroDone){
        saikoroCountNew++;
        let results = [];
        let images = [];
        
        //サイコロ三つ振る
        for (let i = 0; i<3; i++){
            let saikoro = Math.floor( Math.random() *6) +1; //ランダムで1~6の数字を作る
            results.push(saikoro);
             images.push(saikoro + ".jpg");
        }
        
        //結果の表示
        document.getElementById("kekkaNew").innerHTML = `サイコロの結果: ${results.join(",")}`;
        document.getElementById("sainome4").src = images[0];
        document.getElementById("sainome5").src = images[1];
        document.getElementById("sainome6").src = images[2];
        document.getElementById("counterNew").innerHTML = saikoroCountNew+"回目"
        
        //役判定と表示
        let yaku = 役判定(results);
        document.getElementById("yakuNew").innerHTML = "役:"+yaku;  
        
        //役が出るか、3回振ってボタンを無効化
        if(yaku !== "役無し" || saikoroCount >= maxSaikoroCount){
            document.getElementById("saikoroButtonNew").disabled = true;
            ParentSaikoroDone = true;
        }
    
        //勝敗判定
        if(ChildSaikoroDone && ParentSaikoroDone ){
            勝敗判定();
        }
    }
}

function 特殊役(array,elements){
    return elements.every(elements => array.includes(elements));
}

function 役判定(results){
    let shigoro = [4,5,6];
    let hihumi = [1,2,3];
    if(results[0] == results[1] && results[1] == results[2] ){
        if(results[0] == 1){
            return "ピンゾロ"
        }else if(results[0] == 2){
            return "2のアラシ"
        }else if(results[0] == 3){
            return "3のアラシ"
        }else if(results[0] == 4){
            return "4のアラシ"
        }else if(results[0] == 5){
            return "5のアラシ"
        }else{
            return "6のアラシ"
        }
    }else if(特殊役(results,shigoro)){
        return "シゴロ"
    }else if(特殊役(results,hihumi)){
        return "ヒフミ"
    }else if(results[0] == results[1]){
        return results[2] 
    }else if(results[0] == results[2]){
        return results[1]
    }else if(results[1] == results[2]){
        return results[0]
    }else{
        return "役無し"
    }
}

function 役の強さ(yaku){
    switch(yaku){
        case "ピンゾロ":return 14; 
        case "6のアラシ":return 13;
        case "5のアラシ":return 12;
        case "4のアラシ":return 11;
        case "3のアラシ":return 10;
        case "2のアラシ":return 9;
        case "シゴロ":return 8;
        case "6":return 7;
        case "5":return 6;
        case "4":return 5;
        case "3":return 4;
        case "2":return 3;
        case "1":return 2;
        case "役無し":return 1;
        case "ヒフミ":return 0;
        default:return -1;
    }
}

function 勝敗判定(){
    //賭け金取得
    let betAmount = getBetAmount();
    
    //役を取得
    const childYaku = document.getElementById("yaku").innerHTML.replace('役:','');
    const parentYaku = document.getElementById("yakuNew").innerHTML.replace('役:','');
    
    //役を数値変換
    let childValue = 役の強さ(childYaku);
    let parentValue = 役の強さ(parentYaku);
    
    //勝敗判定
    if(childValue > parentValue){   //子勝ち
        if(parentValue == 0){   //親ヒフミで
            if(childValue == 14){   //ピンゾロ
                childGold += betAmount * 10;
                parentGold -= betAmount * 10;
                document.getElementById("result").innerHTML = "子の勝ち";
            } else if (childValue == 13 || childValue == 12 || childValue == 11 || childValue == 10 || childValue == 9){    //アラシ
                childGold += betAmount * 6;
                parentGold -= betAmount * 6;
                document.getElementById("result").innerHTML = "子の勝ち";
            } else if(childValue == 8){    //シゴロ
                childGold += betAmount * 4;
                parentGold -= betAmount * 4;
                document.getElementById("result").innerHTML = "子の勝ち";
            } else {    //ヒフミと出目
                childGold += betAmount * 2;
                parentGold -= betAmount * 2;
                document.getElementById("result").innerHTML = "子の勝ち";
            }
        } else if(childValue == 14){   //ピンゾロ
            childGold += betAmount * 5;
            parentGold -= betAmount * 5;
            document.getElementById("result").innerHTML = "子の勝ち";
        } else if (childValue == 13 || childValue == 12 || childValue == 11 || childValue == 10 || childValue == 9){    //アラシ
            childGold += betAmount * 3;
            parentGold -= betAmount * 3;
            document.getElementById("result").innerHTML = "子の勝ち";
        } else if(childValue == 8){    //シゴロ
            childGold += betAmount * 2;
            parentGold -= betAmount * 2;
            document.getElementById("result").innerHTML = "子の勝ち";
        } else {
            childGold += betAmount;
            parentGold -= betAmount;
            document.getElementById("result").innerHTML = "子の勝ち";
        }
    } else { //親の勝ち
        if(childValue == 0){    //子がヒフミ
            if(parentValue == 14){  //親ピンゾロ
                childGold -= betAmount * 10;
                parentGold += betAmount * 10;
                document.getElementById("result").innerHTML = "親の勝ち";
            } else if(parentValue == 13 || parentValue == 12 || parentValue == 11 || parentValue == 10 ||parentValue == 9){    //アラシ
                childGold -= betAmount * 6;
                parentGold += betAmount * 6;
                document.getElementById("result").innerHTML = "親の勝ち";
            } else if(parentValue == 8){    //シゴロ
                childGold -= betAmount * 4;
                parentGold += betAmount * 4;
                document.getElementById("result").innerHTML = "親の勝ち";
            } else{     //ヒフミと出目
                childGold -= betAmount * 2;
                parentGold += betAmount * 2;
                document.getElementById("result").innerHTML = "親の勝ち";
            }
        } else if(parentValue == 14){  //ヒフミ無し親ピンゾロ
            childGold -= betAmount * 5;
            parentGold += betAmount * 5;
            document.getElementById("result").innerHTML = "親の勝ち";
        } else if(parentValue == 13 || parentValue == 12 || parentValue == 11 || parentValue == 10 ||parentValue == 9){    //アラシ
            childGold -= betAmount * 3;
            parentGold += betAmount * 3;
            document.getElementById("result").innerHTML = "親の勝ち";
        } else if(parentValue == 8){    //シゴロ
            childGold -= betAmount * 2;
            parentGold += betAmount * 2;
            document.getElementById("result").innerHTML = "親の勝ち";
        } else{     //出目
            childGold -= betAmount;
            parentGold += betAmount;
            document.getElementById("result").innerHTML = "親の勝ち";
        }
    }
    
    //所持金の更新
    document.getElementById("childGold").innerHTML = `所持金: ${childGold}`;
    document.getElementById("parentGold").innerHTML = `所持金: ${parentGold}`;
}

参考資料

おわりに

今回記事にしたのは1対1での形式で遊ぶまででしたが、子を複数人に増減できるように改造してあります。

もし、気になる方がいれば以下のURLからコードを覗いてみてください!
https://github.com/Hina03/dice-game/tree/dev

1
0
2

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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?