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

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

タグ:
JavaScript

ビンゴ成立のロジック

本当はランダムで数字を出して抽選させる機能を付けたいところですが、出た数字をクリックしていく仕様とします。

まずbingoという変数を作り、ビンゴが成立したらこれをtrueにすることにします。

ゲームを進めていくにつれて、前回作ったビンゴの数字が入った配列arrayの該当数字を'◯'に変えていきます。

そうすると、ビンゴというのは縦横斜めの5+5+2の12パターンのどれかが'◯'で揃うことになるので、それをチェックするcheckArray()関数を作りました。

この関数は、配列を入れてその要素が全て'◯'だったら、bingo変数をtrueに変えます。

let bingo = false; const checkArray = (array) => { if(array.every(value => value === "◯")){ bingo = true; console.log("ビンゴ!"); }; }

チェックすべき12組の配列を作る

次にチェックすべき縦横斜めの12組の配列を作る方法を考えます。

横方向をチェックする

例えば横方向をチェックするには、

const yoko1array = [array[0],array[1],array[2],array[3],array[4]]; const yoko2array = [array[5],array[6],array[7],array[8],array[9]]; // 略

としたいところですが、あまりスマートではないので別の方法を考えましょう。

よっぽどマイナーなプログラミング言語でない限り、こういうよく使いそうな処理は専用のメソッドが用意されているものです。

slice()メソッドは、配列から指定した部分をコピーしてくれる配列のメソッドです。

これを利用すると、

// array.slice(0,5)なら、array[0]~array[4]までの5個の要素が入った配列を返す const yoko1array = array.slice(0,5); const yoko2array = array.slice(5,10); const yoko3array = array.slice(10,15); // 略

さらにこれらで作ったyokoarrayたちは、そのまま上で作ったcheckArray()に突っ込むだけなので、for文を使って纏めて放り込んでみます。

これで横方向を纏めてチェックすることができます。

for (let i=0; i<5; i++){ checkArray(array.slice(i*5,(i+1)*5)); }

縦方向をチェックする

縦方向をチェックする方法も考えてみます。

まずは素直に書いてみます。

const tate1array = [array[0],array[5],array[10],array[15],array[20]]; const tate2array = [array[1],array[6],array[11],array[16],array[21]]; // 略

こっちはslice()では対応できませんので別のメソッドを探してみます。

少し難しいのですが、filterメソッドを利用することで実現することができます。

const tate1array = array.filter((_,index) => index %5 === 0); const tate2array = array.filter((_,index) => index %5 === 1); const tate3array = array.filter((_,index) => index %5 === 2); // 略

filter()は配列から指定した条件に合致する配列を取り出すメソッドです。

filter()に2つの引数を渡したとき、

// value:配列の要素 index:その要素のインデックス(順番) array.filter((value,index) => ...)

となります。

そのため、上記のコードで、

array.filter((_,index) => index %5 === 0);

としているのは、arrayの要素のインデックスが5の倍数の要素だけを集めろという意味になります。

これもfor文を使ってcheckArray()に突っ込むので、

for (let i=0; i<5; i++){ // 縦方向 checkArray(array.slice(i*5,(i+1)*5)); // 横方向 checkArray(array.filter((_,index) => index %5 === i)); }

となります。

斜め方向

これは2パターンしかないので、直接書くだけでも良いかなと思います。

checkArray([array[0],array[6],array[12],array[18],array[24]]); checkArray([array[4],array[8],array[12],array[16],array[20]]);

ゲームが進む(出た数字をclickする)たびに盤面をチェックする

これらを纏めてcheckBingo()関数を作りました。

const checkBingo = () => { for (let i=0; i<5; i++) { // 縦方向 checkArray(array.slice(i*5,(i+1)*5)); // 横方向 checkArray(array.filter((_,index) => index %5 === i)); } // 斜め列のチェック checkArray([array[0],array[6],array[12],array[18],array[24]]); checkArray([array[4],array[8],array[12],array[16],array[20]]); }

この関数をクリックイベントの中に仕込んでおけば完成です!

for (let i=0; i<25; i++){ const divEl = document.createElement('div'); if(i === 12){ divEl.textContent = "FREE"; } else { divEl.textContent = array[i]; } divEl.addEventListener('click',()=>{ divEl.textContent = "◯"; array[i] = "◯"; checkBingo(); }) board.append(divEl); }