JavaScript - 数当てゲームの作り方【応用編】
この記事は「数当てゲームの作り方【基本編】」に続く応用編です。入力欄やボタンに機能を加えて遊びやすいように改良します。簡単なゲームなので、プログラミング初心者の方もぜひ挑戦してみてください。
数当てゲームを改良して遊びやすくしよう
今回は、「数当てゲームの作り方【基本編】」で作ったゲームにコードを追加して、新たな機能を加えていきます。入力欄に数字を入れやすくしたり、ゲームの結果がより詳しく表示されるように工夫して、ユーザーが操作しやすいゲームにしていきましょう。
この記事を読むと分かること
- if文の入れ子
- 加算代入演算子 +=
- disabledプロパティ
- focus()
「数当てゲームの作り方【基本編】」の内容は、以下の記事でご確認ください。
数当てゲームのサンプルプロジェクト
今回改良していくポイントは次の4つです。これらに注目しながら、数当てゲームで遊んでみてください。
- 間違えたとき、入力された数字が乱数より大きいのか小さいのかが分かる。
- 間違えたとき、入力欄が空白になって再び入力しやすい状態になる。
- 正解したとき、入力欄と送信ボタンが操作できなくなる。
- リセットしたとき、入力欄が空白になって入力しやすい状態になる。
See the Pen JavaScript - Number Guessing Game by Pyxofy (@pyxofy) on CodePen.
数当てゲームの基本コード
最初に、基本コードをおさらいしておきましょう。
//***********************
// 数当てゲームの基本コード
//***********************
const input = document.querySelector('input');
const submitButton = document.querySelector('#submit');
const resetButton = document.querySelector('#reset');
const result = document.querySelector('p');
let randomNumber = Math.floor(Math.random() * 10) + 1;
function checkAnswer() {
  const userAnswer = Number(input.value);
  let message;
  if (userAnswer === randomNumber) {
    message = '正解です!';
  } else {
    message = '違います。';
  }
  result.textContent = message;
}
function resetNumber() {
  randomNumber = Math.floor(Math.random() * 10) + 1; 
  result.textContent = '';
}
submitButton.addEventListener('click', checkAnswer);
resetButton.addEventListener('click', resetNumber);
これからコードを追加していくのは、2つの関数 checkAnswer と resetNumber です。関数以外の部分は、基本コードのまま変更はしません。
間違えたら、結果をより詳しく表示する
まずは、関数 checkAnswer にコードを追加していきます。checkAnswer は、「入力された数字と乱数が等しいかどうかを調べて、その結果を表示する」という関数です。
基本コードでは、入力された数字と乱数が等しくない場合は「違います。」と表示されるだけでしたね。間違えたときに、入力された数字が乱数より「大きいのか」「小さいのか」が分かるように、else の部分にコードを追加しましょう。
function checkAnswer() {
  const userAnswer = Number(input.value);
  let message;
  if (userAnswer === randomNumber) {
    message = '正解です!';
  } else {
    message = '違います。';
      
    // ここにコードを追加する
    // …
      
  }
  result.textContent = message;
}else の中にもうひとつの if 文を入れ子にします。if 文の入れ子(ネスト)とは、条件文の中に別の条件文が含まれていることです。
- if (userAnswer > randomNumber):入力された数字が乱数より大きいなら。
- else:そうでなければ(入力された数字が乱数より小さいなら)。
  else {
  message = '違います。';
  if (userAnswer > randomNumber) {
    // 入力された数字が乱数より大きい場合に表示する結果;
  } else {
    // 入力された数字が乱数より小さい場合に表示する結果;
  }
}
文字列をつなげる - +=
「違います。」のあとに文字列を追加して、入力された数字が乱数より「大きいのか」「小さいのか」を表示します。そのために使うのが、加算代入演算子 += です。加算代入演算子を文字列に使うと、文字列をつなげることができます。
加算代入演算子、文字列連結の例:
let address = '東京都';
address += '新宿区'; // address = address + '新宿区'と同じ。-> '東京都新宿区'
変数 message に文字列をつなげて、その結果を変数 message に代入しましょう。
- message += userAnswer + 'より小さい数字です。':「違います。」のあとに「入力された数字- userAnswerより小さい数字です。」をつなげる。
- message += userAnswer + 'より大きい数字です。':「違います。」のあとに「入力された数字- userAnswerより大きい数字です。」をつなげる。
  else {
  message = '違います。';
  if (userAnswer > randomNumber) {
    message += userAnswer + 'より小さい数字です。'; // 入力された数字が乱数より大きい場合に表示する結果
  } else {
    message += userAnswer + 'より大きい数字です。'; // 入力された数字が乱数より小さい場合に表示する結果
  }
}
間違えたときに、入力された数字が乱数より「大きいのか」「小さいのか」が分かるようになりました。

間違えたら、再び入力しやすいようにする
続いて、入れ子にした if 文のあとに2つの文を追加します。ユーザーが再び入力欄に数字を入れやすいような工夫をしますよ。
前に入力した数字が入力欄に表示されたままだと、ユーザーは入力欄をクリックして数字を削除してから新たな数字を入れなければいけませんね。この手間を省くために、入力欄を空白にしてフォーカスを当てるコードを追加していきましょう。
入力欄を空白にする
間違いだった数字を入力欄から消去して、新たな数字を入力しやすいように準備します。
- inputは、- <input>要素への参照です。
- ドット .に続けてvalueプロパティを書き、空白''を代入して入力欄を空白にします。
  else {
  message = '違います。';
  if (userAnswer > randomNumber) {
    message += userAnswer + 'より小さい数字です。';
  } else {
    message += userAnswer + 'より大きい数字です。';
  }
  input.value = ''; // 入力欄を空白にする
}
入力欄にフォーカスを当てる - focus()
ユーザーが入力欄をクリックしなくても、すぐに新たな数字を入力できるようにするために、入力欄にフォーカスを当てましょう。そのために使うのが focus() です。focus() を使うと、入力欄にカーソルを入れることができるので、わざわざクリックしなくてもそのまま入力することができるようになりますよ。
- inputは、- <input>要素への参照です。
- ドット .に続けて、focus()を書きます。
  else {
  message = '違います。';
  if (userAnswer > randomNumber) {
    message += userAnswer + 'より小さい数字です。';
  } else {
    message += userAnswer + 'より大きい数字です。';
  }
  input.value = '';
  input.focus(); // 入力欄にフォーカスを当てる
}
間違えた数字が消去され入力欄にカーソルが入って、再び数字を入力しやすいようになりました。

正解したら、それ以上入力できないようにする
次は、正解した場合です。基本コードでは、「正解です。」と表示されるだけでしたね。正解したらそれ以上数字を入力できないようにして、ゲームを終わりにしましょう。
数字を入力できないようにするためには、入力欄と送信ボタンを操作できないようにします。そのために使うのが disabled プロパティです。対象の要素に disabled プロパティを指定し、その値を true にすると、要素が無効になります。無効になった要素はクリックできなくなりますよ。
関数 checkAnswer の中の if の部分に2つの文を追加しましょう。入力欄と送信ボタンを無効にしてクリックできないようにする文です。
function checkAnswer() {
  const userAnswer = Number(input.value);
  let message;
  if (userAnswer === randomNumber) {
    message = '正解です!';
    // ここにコードを追加する
    // …
    
  } else {
    message = '違います。';
    if (userAnswer > randomNumber) {
      message += userAnswer + 'より小さい数字です。';
    } else {
      message += userAnswer + 'より大きい数字です。';
    }
    input.value = '';
    input.focus();
  }
  result.textContent = message;
}
- inputは、- <input>要素への参照です。
- ドット .に続けて、disabledを書きます。指定する値はtrueです。
- submitButtonは、送信ボタン要素への参照です。
- ドット .に続けて、disabledを書きます。指定する値はtrueです。
if (userAnswer === randomNumber) {
  message = '正解です!';
  input.disabled = true; // 入力欄を無効にする
  submitButton.disabled = true; // 送信ボタンを無効にする
}
正解したら入力欄と送信ボタンが無効になり、それ以上入力できないようになりました。

改良した関数 checkAnswer は、下のようになります。
function checkAnswer() {
  const userAnswer = Number(input.value);
  let message;
  if (userAnswer === randomNumber) {
    message = '正解です!';
    input.disabled = true;
    submitButton.disabled = true;
  } else {
    message = '違います。';
    if (userAnswer > randomNumber) {
      message += userAnswer + 'より小さい数字です。';
    } else {
      message += userAnswer + 'より大きい数字です。';
    }
    input.value = '';
    input.focus();
  }
  result.textContent = message;
}
リセットしたら、再びゲームを始めやすいようにする
ここからは、関数 resetNumber にコードを追加していきますよ。resetNumber は、「乱数を再代入して、すでに表示されている結果を消去する」という関数です。
function resetNumber() {
  randomNumber = Math.floor(Math.random() * 10) + 1; 
  result.textContent = '';
  // ここにコードを追加する
  // …
  
}
さきほど関数 checkAnswer の中に、正解したら入力欄と送信ボタンを無効にするコードを追加しましたね。このままだと、リセットボタンを押してもゲームを再開することができません。入力欄と送信ボタンを操作できるようにするために、disabled プロパティの値を false にしましょう。
- input.disabled = false:入力欄を有効にして入力できるようにします。
- submitButton.disabled = false:送信ボタンを有効にしてクリックできるようにします。
function resetNumber() {
  randomNumber = Math.floor(Math.random() * 10) + 1; 
  result.textContent = '';
  input.disabled = false; // 入力欄を有効にする
  submitButton.disabled = false; // 送信ボタンを有効にする
}
乱数をリセットして再びゲームを始めるときに、ユーザーが数字を入力しやすいように準備しましょう。間違えたときと同じように、入力欄を空白にしてフォーカスを当てるコードを追加します。
- input.value = '':入力欄に入っている値を消去して空白にします。
- input.focus():入力欄にフォーカスを当ててカーソルを入力欄に入れます。
function resetNumber() {
  randomNumber = Math.floor(Math.random() * 10) + 1; 
  result.textContent = '';
  input.disabled = false;
  submitButton.disabled = false;
  input.value = ''; // 入力欄を空白にする
  input.focus(); // 入力欄にフォーカスを当てる
}
リセットボタンを押したとき、ゲームがリセットされて再び始めやすい状態になりました。

完成コード
関数を改良して新たな機能を追加した、数当てゲームのコードが完成です。
//********************
// 数当てゲームのコード
//********************
const input = document.querySelector('input');
const submitButton = document.querySelector('#submit');
const resetButton = document.querySelector('#reset');
const result = document.querySelector('p');
let randomNumber = Math.floor(Math.random() * 10) + 1;
function checkAnswer() {
  const userAnswer = Number(input.value);
  let message;
  if (userAnswer === randomNumber) {
    message = '正解です!';
    input.disabled = true;
    submitButton.disabled = true;
  } else {
    message = '違います。';
    if (userAnswer > randomNumber) {
      message += userAnswer + 'より小さい数字です。';
    } else {
      message += userAnswer + 'より大きい数字です。';
    }
    input.value = '';
    input.focus();
  }
  result.textContent = message;
}
function resetNumber() {
  randomNumber = Math.floor(Math.random() * 10) + 1; 
  result.textContent = '';
  input.disabled = false;
  submitButton.disabled = false;
  input.value = '';
  input.focus();
}
submitButton.addEventListener('click', checkAnswer);
resetButton.addEventListener('click', resetNumber);
まとめ
今回は、基本編で作った数当てゲームに JavaScript コードを追加し、入力欄やボタンにちょっとした機能を加えることで、より操作しやすいゲームに改良しました。
関数や if 文、乱数やボタンの操作なども含まれている数当てゲームのコードはそれほど複雑ではないので、JavaScriptを学びはじめて最初に作るゲームとしておすすめです。ぜひ試してみてくださいね。
最後まで読んでいただき、ありがとうございます。この記事をシェアしてくれると嬉しいです!
メンバー登録で Pyxofy がもっと便利にもっと楽しく!詳しくはこちらをご覧ください。
こちらもチェック!Twitter @pyxofy・LinkedIn・Mastodon・Facebook
 
                 
                    