🎯

JavaScriptへの最初のダイブ①(数字当てゲーム)

2023/03/17に公開

MDN( https://developer.mozilla.org/ja/docs/Web/JavaScript
を参考に勉強するように注意が入ったので、こらを教本にしていきます。
その為、抜粋しながら進めたいと思います。
今回はこちら 1)のページです

数字当てゲーム

今回、こちらのゲームを作ります。
数字当てゲーム 2)

ゲームの概要

上司から、次のように作るゲームの概要を聞いたところを想像してみてください。

数字を予想する単純なゲームを作って欲しい。
ランダムな 1 から 100 の数字を決めて、プレイヤーに10回以内に当ててもらうゲームだ。
プレイヤーには予想する都度、正解か間違いかを表示する。もしプレイヤーが間違っていれば、プレイヤーが予想した数字に応じて、大きすぎるか小さすぎるかを表示する。また、プレイヤーの前回の予想がどうだったかも表示する。
ゲームはプレイヤーの予想が正しかった場合、もしくは回数の上限に達した場合に終了する。
ゲームが終了したら、プレイヤーはもう一度プレイ開始できるようにする。

ゲームの概要を聞き、最初に行うべきこと

最初に行うべきことは、簡潔な実行可能な単位に分割することです。

  1. 1 から 100 までの数字をランダムに一つ生成する。
  2. プレイヤーの予想した回数を記録する。最初は 1 回から。
  3. プレイヤーが数字が何かを予想する方法を用意する。
  4. 予想が入力されたら、プレイヤーが以前の予想を見られるように、どこかに記録する。
  5. 入力された数字が正しいかどうかを調べる。
  6. 入力された数字が正しい場合...
     ①正解したお祝いのメッセージを表示
     ②プレイヤーが次の予想を出来ないようにする
     ③プレイヤーが次のゲームを始められるようなコントロールを表示
  7. プレイヤーの予想が間違いで、予想回数の上限にはまだ達していない場合...
    ①プレイヤーが間違っていることを表示
    ②次の予想を入力できるようにする
    ③予想回数に1を加算する
  8. プレイヤーの予想が間違いで、予想回数の上限に達した場合...
    ①プレイヤーにゲームオーバーであることを伝える。
    ②プレイヤーが次の予想を出来ないようにする。
    ③プレイヤーが次のゲームを始められるようなコントロールを表示する。
  9. ゲームがもう一度始まったら、画面とロジックが完全にリセットされるようにして、1.に戻る。

まず初めに(HTML・CSS)

自分のファイルにこちら 3)のhtml&CSSをダウンロードします。

これを見る限り今回は『内部のJavaScript』の使用ですね。

JavaScriptを書いてみよう

<script> 要素の中に以下の内容を書いてみてください。

  1. データを保持する変数を追加
//1から100までのランダムな数字が代入
let randomNumber = Math.floor(Math.random() * 100) + 1;
 //段落に値を追加するために使用
const guesses = document.querySelector('.guesses');
const lastResult = document.querySelector('.lastResult');
const lowOrHi = document.querySelector('.lowOrHi');
//テキスト入力フォームおよび送信ボタンへの参照が保持され、後で予想の送信をコントロールする際に使用される。
const guessSubmit = document.querySelector('.guessSubmit');
const guessField = document.querySelector('.guessField');
//プレイヤーが予想した回数を記録するため1
let guessCount = 1;
//リセットボタンへの参照を保持
let resetButton;
  1. 予想の確認
function checkGuess() {
    //userGuessという変数を宣言して、現在のテキストフィールドに入力された値をセット。組み込みの Number() 関数を呼び出して、テキストフィールドに入力された値が数値であることも確認。
    const userGuess = Number(guessField.value);
    //条件分岐を伴うコードブロック。guessCount変数が1(プレイヤーの初回の予想)であるかどうかを判定。
    if (guessCount === 1) {
      guesses.textContent = '前回の予想: ';
    }
    //予想が表示されるときにはスペースで区切られて表示するように記載。
    guesses.textContent += userGuess + ' ';
    //ランダムな数字を格納したrandomNumber変数の値と等しいかどうかを調査。もし等しければ、プレイヤーは正解し勝ち(祝福のメッセージを緑色で表示)。さらに、数字の大小を表示する段落をクリアして、後で説明するsetGameOver()関数を実行。
    if (userGuess === randomNumber) {
      lastResult.textContent = 'おめでとう!正解です!';
      lastResult.style.backgroundColor = 'green';
      lowOrHi.textContent = '';
      setGameOver();
      //else if(){ } という部分で、ひとつ前の条件に続けて条件を記載。この条件はユーザの最後のターンかどうかを調査。最後の回ならば、プログラムはゲームオーバーとする以外は、ひとつ前の部分と同じことを実行。
    } else if (guessCount === 10) {
      lastResult.textContent = '!!!ゲームオーバー!!!';
      lowOrHi.textContent = '';
      setGameOver();
      //前の二つの条件がどちらも当てはまらなかった場合のみ実行。(プレイヤーは間違えてはいるものの、予想回数が残っている。) この場合、プレイヤーに予想が間違っていることを伝え、入力された数字が大きいか小さいかを伝えるため、さらなる条件の確認を行う。
    } else {
      lastResult.textContent = '間違いです!';
      lastResult.style.backgroundColor = 'red';
      if(userGuess < randomNumber) {
        lowOrHi.textContent = '今の予想は小さすぎです!' ;
      } else if(userGuess > randomNumber) {
        lowOrHi.textContent = '今の予想は大きすぎです!';
      }
    }
    //次の予想の入力を受け取るための準備。guessCount変数に1を加算し、プレイヤーの予想回数を数えます。(++はインクリメント演算子で、1だけインクリメント(増加)。) そして、入力フォームのテキストフィールドを空にしてから焦点を当て、プレイヤーの次の入力に備える。
    guessCount++;
    guessField.value = '';
    guessField.focus();
  }
  1. "予想を入力"のボタンが押されたときに、イベントを起こす
//guessSubmitボタンに対して、イベントが発生したことを聞き取る構成(イベントリスナー)を追加。これは発生したことを知りたいイベントの種類 (click)と、イベントが発生した場合に実行するコード (checkGuess()) の2つの入力値 (引数) を取る関数です。
guessSubmit.addEventListener('click', checkGuess);
  1. ゲームの機能を完成させる(ゲームオーバーになった時)
function setGameOver() {
    //入力フォームのテキストフィールドとボタンのdisabledプロパティをtrueに設定することで、入力できないようにしている。
    guessField.disabled = true;
    guessSubmit.disabled = true;
    //新しいbutton要素を生成し、そのラベルに"新しいゲームを始める"という文言を設定し、HTMLページに追加。
    resetButton = document.createElement('button');
    resetButton.textContent = '新しいゲームを始める';
    document.body.appendChild(resetButton);
    //上で生成したボタンがクリックされたときに resetGame() という関数が実行されるようにイベントリスナーを設定
    resetButton.addEventListener('click', resetGame);
  }
  1. ゲームの機能を完成させる(次のゲームができるようにゲームを初期化)
function resetGame() {
   //guessCount に 1 を代入して元に戻す
   guessCount = 1;
   //情報段落のすべてを消去。
    const resetParas = const resetParas = document.querySelectorAll('.resultParas p');
    for (let i = 0 ; i < resetParas.length ; i++) {
    resetParas[i].textContent = '';
    }
    //リセットボタンをページから削除。
    resetButton.parentNode.removeChild(resetButton);
    //入力フォームの要素を使用可能にして、新しい予想が入力できるようにテキストフィールドを空にしてフォーカスを設定します。
    guessField.disabled = false;
    guessSubmit.disabled = false;
    guessField.value = '';
    guessField.focus();
    //最終結果を表示している lastResult 段落の背景色を消去。
    lastResult.style.backgroundColor = 'white';
    //同じ数字以外の数字でゲームができるように、新しいランダムな数字を再度生成
    randomNumber = Math.floor(Math.random() * 100) + 1;
  }

完成のソースコード(日本語)

<!DOCTYPE html>
<html lang="en-us">
<head>
  <meta charset="utf-8">

  <title>数字当てゲーム</title>

  <style>
    html {
      font-family: sans-serif;
    }

    body {
      width: 50%;
      max-width: 800px;
      min-width: 480px;
      margin: 0 auto;
    }

    .form input[type="number"] {
      width: 200px;
    }

    .lastResult {
      color: white;
      padding: 3px;
    }
  </style>
</head>

<body>
<h1>数字当てゲーム</h1>

<p>1100の中からランダムな数字を選びました。10ターン以内に当てられるかどうか試してみてください。あなたの予想が大きすぎたり小さすぎた場合は、お知らせします。</p>

<div class="form">
  <label for="guessField">予想を入力してください: </label>
  <input type="number" min="1" max="100" required id="guessField" class="guessField">
  <input type="submit" value="予想を入力" class="guessSubmit">
</div>

<div class="resultParas">
  <p class="guesses"></p>
  <p class="lastResult"></p>
  <p class="lowOrHi"></p>
</div>

<script>
  let randomNumber = Math.floor(Math.random() * 100) + 1;
  const guesses = document.querySelector('.guesses');
  const lastResult = document.querySelector('.lastResult');
  const lowOrHi = document.querySelector('.lowOrHi');
  const guessSubmit = document.querySelector('.guessSubmit');
  const guessField = document.querySelector('.guessField');
  let guessCount = 1;
  let resetButton;

 
  function checkGuess() {
    const userGuess = Number(guessField.value);
    if (guessCount === 1) {
      guesses.textContent = '前回の予想: ';
    }
     guesses.textContent += userGuess + ' ';
     if (userGuess === randomNumber) {
      lastResult.textContent = 'おめでとう!正解です!';
      lastResult.style.backgroundColor = 'green';
      lowOrHi.textContent = '';
      setGameOver();
     } else if (guessCount === 10) {
      lastResult.textContent = '!!!ゲームオーバー!!!';
      lowOrHi.textContent = '';
      setGameOver();
     } else {
      lastResult.textContent = '間違いです!';
      lastResult.style.backgroundColor = 'red';
      if(userGuess < randomNumber) {
        lowOrHi.textContent = '今の予想は小さすぎです!' ;
      } else if(userGuess > randomNumber) {
        lowOrHi.textContent = '今の予想は大きすぎです!';
      }
    }
     guessCount++;
    guessField.value = '';
    guessField.focus();
  }

   guessSubmit.addEventListener('click', checkGuess);

  function setGameOver() {
    guessField.disabled = true;
    guessSubmit.disabled = true;
    resetButton = document.createElement('button');
    resetButton.textContent = '新しいゲームを始める';
    document.body.appendChild(resetButton);
    resetButton.addEventListener('click', resetGame);
  }

  function resetGame() {
   guessCount = 1;
   const resetParas = document.querySelectorAll('.resultParas p');
    for (let i = 0 ; i < resetParas.length ; i++) {
    resetParas[i].textContent = '';
    }
    resetButton.parentNode.removeChild(resetButton);
    guessField.disabled = false;
    guessSubmit.disabled = false;
    guessField.value = '';
    guessField.focus();
    lastResult.style.backgroundColor = 'white';
     randomNumber = Math.floor(Math.random() * 100) + 1;
  }
</script>
</body>
</html>

文献表

  1. MDN「JavaScriptへの最初のダイブ」
    https://developer.mozilla.org/ja/docs/Learn/JavaScript/First_steps/A_first_splash
    (2023/3/17閲覧)

  2. 数字当てゲーム
    https://mdn.github.io/learning-area/javascript/introduction-to-js-1/first-splash/number-guessing-game-start.html
    (2023/3/17閲覧)

  3. GitHub「mdn/learning-area」の中の「number-guessing-game-start.html」ファイル https://github.com/mdn/learning-area/blob/main/javascript/introduction-to-js-1/first-splash/number-guessing-game-start.html
    (2023/3/17閲覧)

Discussion