Javascript入門。Tic-Tac-Toe(○×ゲーム)Webアプリを作成。 – その4 – 結果判定処理の実装
こちらはこの記事の続きです。
結果判定のメソッドを追加
前回までで、○×の入力はできるようになりましたが本来の○×ゲームでは、○か×が三つ揃った場合には、どちらかの勝利が確定しゲームが終了します。
が、前回までの実装ではゲームができないわけではないですが三つ揃ったあともゲームを続けることができるので、どちらかが○×を入力した後に毎回、
三つ揃ったか確認し、○か×が揃っていたら勝者を画面に表示してゲームを終了する。
という処理を足していきます。
コードはこちらです。
function.js
// .table の中の要素がクリックされたらイベントが発火
document.querySelector('.table').addEventListener('click',function(e){
if(document.querySelector('#finished').value === 'true'){return}
// ○か×が入力されていたら、処理を行わす中断する。
if(e.target.innerText !== '-'){return}
// クリックした部分に.active要素を当てるために、
// すでに.active要素の当たっている.pannelから
// .active要素を取り除く
const activatedPannel = document.querySelectorAll('.pannel.active')
// エラー回避のため要素が取得できた場合のみ、実行する。
if(activatedPannel[0]){activatedPannel[0].classList.remove("active")}
// くりっくされたボタンをactiveにして、
// 今のターンの印( ○ or × )を入力する。
e.target.classList.add("active")
e.target.innerText = document.querySelector('.btn.active').text
// 順番を交代する。
toggleTurn()
// すでに勝敗が決まっているかチェック
result = judge()
if (result){
document.querySelector('#message').innerText = `${result} win !!!!!!!!`
document.querySelector('#message').classList.remove('hidden')
document.querySelector('#finished').value = 'true'
}
})
今回実装していくメソッドは下の方、toggleTurnの下にあるjudgeメソッドです。 judgeメソッドは試合の結果を○か×で返します。
その後の以下の部分でどちらが勝ったかを表示しています。
if (result){
document.querySelector('#message').innerText = `${result} win !!!!!!!!`
document.querySelector('#message').classList.remove('hidden')
document.querySelector('#finished').value = 'true'
}
メッセージ表示の部分は、前の記事でも書いたようにquerySelectorでHTMLElementを取得してきて、その中の値を書き換えたり、クラスを追加しています。
judgeメソッドの実装
judgeメソッドは次のようになります。// 一旦、縦と横に三つ並んだ場合を判定
function judge(){
// 最終的な結果を格納する変数
// null ・・・継続
// ○ ・・・○の勝ち
// × ・・・×の勝ち
judge_reuslt = null
// 横に3つ並んだ時の結果を判定
// sizeが3より大きい場合も想定して、最大値にsizeを使用。
for( var x = 1; x <= size; x++ ){
texts = []
for( var y = 1; y <= size ; y++){
texts = appendTexts(texts, x, y)
if(!texts[0]){break}
}
judge_reuslt = isFinalized(texts)
if (judge_reuslt){ return judge_reuslt}
}
// 縦に3つ並んだ時の結果を判定
// sizeが3より大きい場合も想定して、最大値にsizeを使用。
for( var y = 1; y <= size; y++ ){
texts = []
for( var x = 1; x <= size ; x++){
texts = appendTexts(texts, x, y)
if(!texts[0]){break}
}
judge_reuslt = isFinalized(texts)
if (judge_reuslt){ return judge_reuslt}
}
return judge_reuslt
}
// 勝敗が決まったかどうかを判定する関数
// listが3つとも同じ記号 ex. 三つとも○かつ
// その記号が'-'でない場合
function isFinalized(list){
let result = Array.from(new Set(list))
if (texts.length === size && result.length === 1 ){
if(result[0] === '-'){ return null }
judge_reuslt = result[0]
return judge_reuslt
}
return null
}
// それぞれのセルを取得して与えられた配列に詰める関数
// 取得した値が'-'だったら空を返却
function appendTexts(a, x, y){
text = document.querySelector(`#pannel-${x}-${y}`).innerText
if( text === '-' ){ return []}
a.push(text)
return a
}
結果判定の仕方ですが、 judgeメソッドの中で次のことを確認します。
- 横に三つ連続で並んだ記号がないか?
- 縦に三つ連続で並んだ記号がないか?
- 斜めに三つ連続で並んだ記号がないか?
- は少し複雑なので、今回はとりあえず1. と2. だけチェックするようにします。
チェックの方法の基本的な方法を確認しておくと、マスの位置をあらかじめ
id='pannel-1-1'
id='pannel-1-2'
・
・
のように定義しているのですが、これはpannel-[列番号]-[行番号]としています。
そのため、 1.のように横の並びを見分けたい場合は、1-1と2-1,3-1の値を取ってくれば良いわけです。 さらに2.を知りたい場合には、1-1,1-2,1-3を調べます。
1.と2.はjudgeメソッド内の上から二つのfor文で確認しています。
for文の中では、上で説明したような座標を取得してきていて、3つの記号が揃っているかをチェックしていて、appendTextsというメソッドがマスから取得してきた記号を配列に格納し、そこで生成された配列isFinalizedで三つ記号が連続しているかを判定しています。
三つ記号が連続していればisFinalizedが記号を返却してくるので、isFinalizedが記号が返したらjudgeメソッドもそのままその記号を返却して、ゲームの結果を表示します。
次回は斜めの場合の判定結果処理を追加して完了
今回はゲームの結果判定処理を追加しましたが、ここまでだと斜めに三つ○か×が続いた場合が考慮されていません。
次回ラストですが、この斜めの処理を追加して完了になります。