JavaScript/Exercises/GuessNumber

From Wikibooks, open books for an open world
Jump to navigation Jump to search




Guess a hidden number

The app chooses a random number and asks the user to guess it. The user has a limited number of attempts.

First, we need an HTML file plus CSS to realize the user interface. It shall contain:

  • A caption
  • A short description of the game
  • A text area to read the user's attempts plus a button to send the user's input to the app
  • Another text area where the app gives a response to the user, e.g.:
* The hidden number is smaller
* The hidden number is greater
* Bingo! That's the hidden number
  • A button to 'reset' the game
  • A button to unfold the random number
  • At this stage, the HTML doesn't contain any event definition or JavaScript.

The HTML might look like this:

Click to see solution
<!DOCTYPE html>
<html>
<head>
  <title>Number Search</title>
  <script>
  // ...
  </script>

</head>

<body style="padding:2em">

  <!--  caption  -->
  <h1 style="text-align: center;">Guess the Number</h1>
  <p  style="font-size: 1.4em; text-align: center; margin-bottom:3em">
    I have choosen a number between 0 and 60.
  </p>

  <!--  user's input  -->
  <p>
    <label  style="margin-right:1em">Guess it. It's always <br/>possible with 6 attempts.</label>
    <input  type="number" id="userInput" min="1" max="60" />
    <button style="margin-left:1em">Go</button>
  </p>

  <!--  feedback from the script to the user  -->
  <textarea id="feedback"rows="15" cols="80"></textarea>

  <!--  command buttons  -->
  <p>
    <button>Restart</button>
    <button style="margin-left:3em">Show the hidden number</button>
  </p>

</body>
</html>

Next, you develop the app's logic by adding events to buttons and functions within the script element.

  • To generate a random number you can use Math.floor(Math.random() * 60) + 1.
  • The HTML body element shall contain an onload event whose event handler initializes the game. The same function is called when 'reset' is pressed.
  • To get access to the two text areas, they must have an id attribute.
  • Read from and write to the text areas via 'value': document.getElementById("...").value.

All in all, the app might look like this:

Click to see solution
<!DOCTYPE html>
<html>
<head>
  <title>Number Search</title>
  <script>
  "use strict";

  // grab aat start time
  let number;   // the (hidden) number 
  let attempts; // the users's attempts

  // --------  initialize the app  -----------------------------------------
  function init() {
    number = createNumber();
    attempts = 0;
    document.getElementById("userInput").value = "";
    document.getElementById("feedback").value = "";
  }

  // --------  generate a random number between 1 and 60  -------
  function createNumber() {
    return Math.floor(Math.random() * 60) + 1; 
  }

  // --------  show the (hidden) number  ----------------
  function showNumber() {
    alert("The choosen number is: " + number);
  }

  // --------  rate the user's answer  -------------------
  function go() {

    // user's input
    const value = document.getElementById("userInput").value;
    const tmp = parseFloat(value);
    if (Number.isNaN(tmp)) {
      alert("Sorry, this is not a number.");
      return;
    }
    attempts++;

    // feedback area
    const feedback = document.getElementById("feedback");
    let response = feedback.value;

    // determine response
    response += attempts + ". Your answer is: " + tmp + ". ";
    if (tmp == number) {
      response += "Congratulation! This is the hidden number.\n";
    } else if (tmp > number) {
      response += "Sorry! The hidden number is smaller.\n";
    } else {
      response += "Sorry! The hidden number is greater.\n";
    }

    // output
    feedback.value = response;
  }
  </script>

</head>

<body style="padding:2em" onload="init()">

  <!--  caption  -->
  <h1 style="text-align: center;">Guess the Number</h1>
  <p  style="font-size: 1.4em; text-align: center; margin-bottom:3em">
    I have choosen a number between 0 and 60.
  </p>

  <!--  user's input  -->
  <p>
    <label  style="margin-right:1em">Guess it. It's always <br/>possible with 6 attempts.</label>
    <input  type="number" id="userInput" min="1" max="60" />
    <button style="margin-left:1em" onclick="go()">Go</button>
  </p>

  <!--  feedback from the script to the user  -->
  <textarea id="feedback"rows="15" cols="80"></textarea>

  <!--  command buttons  -->
  <p>
    <button onclick="init()">Restart</button>
    <button style="margin-left:3em" onclick="showNumber()">Show the hidden number</button>
  </p>

</body>
</html>


Hint: The user can find the number with a maximum of 6 questions if he uses the strategy of BinarySearch: he always has to answer with the average of the current known lower and upper limit, which is 30 in the beginning. If the hidden number is greater, he shall answer 45. If it's smaller 15, ... .