【JavaScript】初心者が〇✖ゲームを作ってみた(その6)

こんにちは、パキラです


前回でマスにマークを設定するプログラミングは終わりました
今回はその表示されたマークにより勝敗を判定するプログラミングをします
勝敗を判定するためには、縦、横、斜めのマスの中が同じ値が入っているか判断するので、すべてのマス目の値をクリック毎にチェックさせるために、【配列】と【for文】を使用します


その前に前回までのコードの中で、一部を【配列】と【for文】を使用しようと思います
【配列】【for文】に関しては別の記事で説明しています

  //画面を読み込んだときの処理 
function onloadAction(){
   //マス目にイベントを設定する
     $("b1").onclick = clickAction;
     $("b2").onclick = clickAction;
     $("b3").onclick = clickAction;
     $("b4").onclick = clickAction;
     $("b5").onclick = clickAction;
     $("b6").onclick = clickAction;
     $("b7").onclick = clickAction;
     $("b8").onclick = clickAction;
     $("b9").onclick = clickAction;
  }


//マス目にイベントを設定するところを【配列】と【for文】を使用してまとめたいと思います
まとめる理由は、勝敗の判定をするときにとても役に立つからです
上記のコードのままでも勝敗は可能ですが、コードがとても長くなるので綺麗に書くためです



配列

まずマス目のIDリストを配列にします
マス目は横3マス、縦3マスなので二次元配列にします

const IDS = [
 ['b1','b2','b3'],
 ['b4','b5','b6'],
 ['b7','b8','b9']
];

これで二次元配列で横3マス、縦3マスの配列ができました



for文

次にマス目にイベントを設定する関数ですが、ここはfor文を使用します

for(let row = 0; row < 3; row ++ ){
 for(let col = 0; col < 3; col ++){
  $(IDS [row][col]).onclick = clickAction; 
 }
}

これで前回までのマス目にイベントを設定する関数をまとめることができました

では次に前回までのコードを【配列】と【for文】でまとめてみます

//先攻のマーク
const FIRST_MARK = "○";

//後攻のマーク
const SECOND_MARK = "✖";

//ターン数
let count = 1;
//マス目のIDリスト
const IDS = [
  ['b1','b2','b3'],
  ['b4','b5','b6'],
  ['b7','b8','b9']
];

//ID取得する関数
function $(id){
  return document.getElementById(id);
}
//先攻のターンか判定する
function isFirstMove(){
  let isFirst = count % 2;
  return isFirst == 1;
}
//ターン表示を切り替える
function changeDisplayCount(){
  if(isFirstMove()){
    //先攻のターンの場合
    $("display").innerHTML = FIRST_MARK + 'の番です!';
  }else{
    //後攻のターンの場合
    $("display").innerHTML = SECOND_MARK + 'の番です!';
  }
}


//クリックされたときの処理
function clickAction(event){
  //イベントからクリックされたマス目のIDを取得する
  let id = event.target.id;
  //IDからオブジェクトを取得する
  let object = $(id);
   //既にマークが設定されている場合はスキップ
   if(object.value !=""){
    return;
  }
  //オブジェクト(マス目)にマークを設定する
  if(isFirstMove()){
      object.value = FIRST_MARK;
    }
    else{
      object.value = SECOND_MARK;
     
     }
   //ターンを+1する
   count +=1;
   //ターン表示を切り替える
   changeDisplayCount();
  }

  //画面を読み込んだときの処理 
function onloadAction(){
   //マス目にイベントを設定する
    for (let row = 0; row < 3; row++){
      for(let col = 0; col < 3; col++){
        $(IDS[row][col]).onclick = clickAction;
      }
    }
  }

  //画面読み込み時のイベントを設定
window.onload = onloadAction;

【初心者向け】ブログの始め方完全ガイド!立ち上げから収入を得る方法まで

勝敗の判定

まず勝敗の判定をするためには、横、縦、斜めの値が、1番目と2番目と3番目のマークが同じかどうかを判断する関数を作ります

//勝利を判定する
function isWin(firstId,secondId,thirdId){
  //1つ目のマス目が空の場合は終了
  if($(firstId).value==""){
    return false;
  }
  //2つ目のマス目が空の場合は終了
  if($(secondId).value==""){
    return false;
  }
   //3つ目のマス目が空の場合は終了
   if($(thirdId).value==""){
    return false;
   }
  //3つのマス目が同じマークである場合は勝利
  if(
  ($(firstId).value == $(secondId).value) && ($(secondId).value == $(thirdId).value)
  ){
  return true;
  }
  //3つのマス目が同じマークじゃないとき勝利ではない
 return false;
}

これで3つのマス目が同じマークが場合は、【true】が返ってくるようになりました
1つでも違うマークがあった場合は【false】が返ってきますので、継続となります

初心者のためのブログ始め方講座

勝敗を判定する処理

勝敗を判定する前に、勝敗が決した場合に勝者が表示させる関数を先に作成しておきます

//勝敗の結果を表示させる
function displayResult(message){
  $("display").innerHTML = message;
  isGame = false;

次に先ほど作った勝敗を判定する関数を使用して、それぞれのマス目になんのマークがあるのかを確認する処理です

//勝敗を判定する処理
function judgEnd(){
  let isEnd = false;
  //横3マスが同じマーク
  for(let row=0; row<3; row++){
    //勝敗を判定
    isEnd = isWin(IDS[row][0],IDS[row][1],IDS[row][2]);
    if(isEnd){
      displayResult($(IDS[row][0]).value + "の勝ち!");
      return true;  
    }
  }
  //縦3マスが同じマーク
  for(let col=0; col<3; col++){
    //勝敗を判定
    isEnd = isWin(IDS[0][col],IDS[1][col],IDS[2][col]);
    if(isEnd){
      displayResult($(IDS[0][col]).value + "の勝ち!");
      return true;  
    }
  }
  //斜め(右下がり)3マスが同じマーク
   isEnd = isWin(IDS[0][0],IDS[1][1],IDS[2][2]);
   if(isEnd){
      displayResult($(IDS[0][0]).value + "の勝ち!");
      return true;
   }
  //斜め(左下がり)3マスが同じマーク
  isEnd = isWin(IDS[0][2],IDS[1][1],IDS[2][0]);
   if(isEnd){
      displayResult($(IDS[0][2]).value + "の勝ち!");
      return true;
   }
   //引き分けの判定
   if(9<=count){
     displayResult("引き分け!");
     return true;
   }
   //ゲーム続行
  return false;
}

これで横、縦、斜めの勝敗が判定できるようになり、勝者が表示されるようにました
そして、すべてのマス目にマークが埋まって勝敗がつかなかった場合は引き分けと判定されるようになりました
この関数をクリックした処理の中に組み込んであげれば完成です

//先攻のマーク
const FIRST_MARK = "○";

//後攻のマーク
const SECOND_MARK = "✖";

//ターン数
let count = 1;
//マス目のIDリスト
const IDS = [
  ['b1','b2','b3'],
  ['b4','b5','b6'],
  ['b7','b8','b9']
];


//ID取得する関数
function $(id){
  return document.getElementById(id);
}
//先攻のターンか判定する
function isFirstMove(){
  let isFirst = count % 2;
  return isFirst == 1;
}
//勝敗の結果を表示させる
function displayResult(message){
  $("display").innerHTML = message;
  isGame = false;
}
//ターン表示を切り替える
function changeDisplayCount(){
  if(isFirstMove()){
    //先攻のターンの場合
    $("display").innerHTML = FIRST_MARK + 'の番です!';
  }else{
    //後攻のターンの場合
    $("display").innerHTML = SECOND_MARK + 'の番です!';
  }
}


//クリックされたときの処理
function clickAction(event){
  //イベントからクリックされたマス目のIDを取得する
  let id = event.target.id;
  //IDからオブジェクトを取得する
  let object = $(id);
   //既にマークが設定されている場合はスキップ
   if(object.value !=""){
    return;
  }
  //オブジェクト(マス目)にマークを設定する
  if(isFirstMove()){
      object.value = FIRST_MARK;
    }
    else{
      object.value = SECOND_MARK;
     
     }
     //ゲーム終了
  if(judgEnd()){
    return;
  }
   //ターンを+1する
   count +=1;
   //ターン表示を切り替える
   changeDisplayCount();
  }
//勝敗を判定する処理
function judgEnd(){
  let isEnd = false;
  //横3マスが同じマーク
  for(let row=0; row<3; row++){
    //勝敗を判定
    isEnd = isWin(IDS[row][0],IDS[row][1],IDS[row][2]);
    if(isEnd){
      displayResult($(IDS[row][0]).value + "の勝ち!");
      return true;  
    }
  }
  //縦3マスが同じマーク
  for(let col=0; col<3; col++){
    //勝敗を判定
    isEnd = isWin(IDS[0][col],IDS[1][col],IDS[2][col]);
    if(isEnd){
      displayResult($(IDS[0][col]).value + "の勝ち!");
      return true;  
    }
  }
  //斜め(右下がり)3マスが同じマーク
   isEnd = isWin(IDS[0][0],IDS[1][1],IDS[2][2]);
   if(isEnd){
      displayResult($(IDS[0][0]).value + "の勝ち!");
      return true;
   }
  //斜め(左下がり)3マスが同じマーク
  isEnd = isWin(IDS[0][2],IDS[1][1],IDS[2][0]);
   if(isEnd){
      displayResult($(IDS[0][2]).value + "の勝ち!");
      return true;
   }
   //引き分けの判定
   if(9<=count){
     displayResult("引き分け!");
     return true;
   }
   //ゲーム続行
  return false;
}

//勝利を判定する
function isWin(firstId,secondId,thirdId){
  //1つ目のマス目が空の場合は終了
  if($(firstId).value==""){
    return false;
  }
  //2つ目のマス目が空の場合は終了
  if($(secondId).value==""){
    return false;
  }
   //3つ目のマス目が空の場合は終了
   if($(thirdId).value==""){
    return false;
   }
  //3つのマス目が同じマークである場合は勝利
  if(
  ($(firstId).value == $(secondId).value) && ($(secondId).value == $(thirdId).value)
  ){
  return true;
  }
  //3つのマス目が同じマークじゃないとき勝利ではない
 return false;
}
  //画面を読み込んだときの処理 
function onloadAction(){
   //マス目にイベントを設定する
    for (let row = 0; row < 3; row++){
      for(let col = 0; col < 3; col++){
        $(IDS[row][col]).onclick = clickAction;
      }
    }
  }

  //画面読み込み時のイベントを設定
window.onload = onloadAction;



○✖ゲーム

○の番です!









まとめ

ここまで読んでいただきありがとうございます
今回で○×ゲームがかなりできあがったてきましたね
でも勝敗が決しても空いているマスにマークが付けられてしまうので、その処理とリセットの処理を次回に紹介していきます

次の記事その⑥



コメント