理系公務員のプログラミング日記

JavaScript ビンゴゲームの作成【前編】

タグ:
JavaScript

乱数を使ってビンゴゲームのカードを作ろう

Math.random()を使って、ビンゴカードに表示する数字を書いていきます。

やり方はいろいろありますが、

1.ビンゴカードの仕様に則った数字の配列を作る。

2.配列を使ってビンゴのマスを作る

の順番で作ります。

ランダムな数字を5個持った配列を作る。

まずは一番基本的な、ランダムな数字を5個持った配列を作ります。

const array = []; for (let i = 0; i<5; i++){ const rand = Math.floor(Math.random()*15) array.push(rand); }

上記のコードで、0~15までのうちランダムで5個の数字が入った配列が作られます。

1.ビンゴカードの仕様に則った数字の配列を作る。

(これちょっと難しいです。)

しかし、上記コードでは重複が発生してしまうので、厳密なビンゴの仕様には合いません。

作られた乱数が既に作られたものと一致する場合は再生成してもらいます。

A.for文を使う場合

文字通り、作った乱数が既に含まれていた場合は再度乱数を作りましょう。

重複する確率はかなり下がります。

const array = []; for (let i = 0; i<5; i++){ const rand = Math.floor(Math.random()*15); // 乱数が被っていなければ if(!array.includes(rand)){ array.push(rand); } else { // 被っていれば、新しい乱数を作る const newRand = Math.floor(Math.random()*5); array.push(newRand); } }

もちろん確率が下がっているだけで、たまーーに重複するときは起こります。

これを解決するのが、もう一回乱数を作るようにする・・・・ではなく、再帰という仕組みを使いましょう。

再帰とは、こうやって何回もif文を繋げる代わりに関数が自分自身を呼び出すことで繰り返しを表現する手法です。

const array = []; const makeRand = () => { const rand = Math.floor(Math.random()*15); // 乱数が被っていなければ if(!array.includes(rand)){ array.push(rand); } else { // 被っていれば、もう一度この関数を実行する makeRand(); } } for (let i = 0; i<5; i++){ makeRand(); }

こうすることで、ビンゴゲームに必要な乱数が入った配列を手に入れることができます。

B.while文を使う場合

実はwhile文を使うともっと簡単に書けます。まずはforで考えて、上手くいかない時はwhileを使うと良いです。

const array = []; // この配列の長さが5になるまで、whileループを回す while(array.length<5){ const rand = Math.floor(Math.random()*15); if(!array.includes(rand)){ array.push(rand) } }

2.配列を使ってビンゴのマスを作る

(上記Bのwhileの方を使ってコードを書いていきます。)

ビンゴにあった25個の数字が入った配列を作ります。

5個作ったら、次の5個を作るようにしました。

const array = []; const makeArray = (i) => { while(array.length<5+5*i){ const rand = 15*i + Math.floor(Math.random()*15); if(!array.includes(rand)){ array.push(rand) } } } for (let i=0; i<5; i++){ makeArray(i); } console.log(array);

この25個の数字を持った配列から25個の数字を書いたdiv要素を作ります。

要素の数が多くなってくると、HTMLに要素を書いて取得するよりJavaScriptで直接書く方が良いでしょう。

// 中略 const board = document.querySelector('.board'); for (let i=0; i<25; i++){ const divEl = document.createElement('div'); if(i === 12){ divEl.textContent = "FREE"; } else { divEl.textContent = array[i]; } board.append(divEl); }

これに対応するHTML・CSSはこんな感じです。

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .board { margin: 0px auto 0 auto; width: 600px; display: grid; grid-template-rows: repeat(5,1fr); grid-auto-flow: column; } .board div { border: solid 2px black; width: 150px; height: 150px; font-size: 50px; font-style: bold; text-align: center; line-height: 3; } </style> </head> <body> <div class="board"></div> </body>

ポイントはここです。

.board{ display: grid; grid-template-rows: repeat(5,1fr); grid-auto-flow: column; }

gridレイアウトによって縦横に並べたあと、grid-auto-flow: columnで要素を縦方向に並べることができます。

ビンゴイメージ