Javascript入門。Tic-Tac-Toe(○×ゲーム)Webアプリを作成。 – その4 – 結果判定処理の実装

 

こちらはこの記事の続きです。

Javascript入門。Tic-Tac-Toe(○×ゲーム)Webアプリを作成。 – その3 –

 

結果判定のメソッドを追加

 

前回までで、○×の入力はできるようになりましたが本来の○×ゲームでは、○か×が三つ揃った場合には、どちらかの勝利が確定しゲームが終了します。

が、前回までの実装ではゲームができないわけではないですが三つ揃ったあともゲームを続けることができるので、どちらかが○×を入力した後に毎回、

三つ揃ったか確認し、○か×が揃っていたら勝者を画面に表示してゲームを終了する。

という処理を足していきます。

コードはこちらです。

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 &amp;&amp; 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. 縦に三つ連続で並んだ記号がないか?
  3. 斜めに三つ連続で並んだ記号がないか?
  4. は少し複雑なので、今回はとりあえず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メソッドもそのままその記号を返却して、ゲームの結果を表示します。

 

次回は斜めの場合の判定結果処理を追加して完了

今回はゲームの結果判定処理を追加しましたが、ここまでだと斜めに三つ○か

×が続いた場合が考慮されていません。

次回ラストですが、この斜めの処理を追加して完了になります。