3

I am building a game out of JS. the rules of the game are simple: you are asked what (num1) + (num2) equals (as you can see in the codepen).

In the game you have 4 possible choices to answer the question.

We're I'm stuck right now is creating those possible options: I would like to display three random numbers that are false and one number that is the correct sum.

my JS:

var num1 = Math.floor((Math.random() * 30) + 10);
var num2 = Math.floor((Math.random() * 30) + 10);
var result = num1 + num2;

document.getElementById('field1').innerHTML = num1;
document.getElementById('field2').innerHTML = num2;

var options = {
    option1: document.getElementById('option1'),
    option2: document.getElementById('option2'),
    option3: document.getElementById('option3'),
    option4: document.getElementById('option4'),
}

Here is my codepen:

https://codepen.io/teenicarus/pen/Oxaaoe

How do i do this?

I appreciate all answers

  • You are generating num1 and num2 **once** at runtime, so all your options will have the same randomly generated value. You want to execute this random number generation once for each incorrect option. – Terry Oct 17 '17 at 11:10

4 Answers4

2

The solution is a little complex, it will be so long to describe every row, so feel free to ask if anything isn't clear. Need to say, that the order of numbers on cards is randomly generated too. Here it is:

function shuffle(o) {
 for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
 return o;
};

function startGame() {
  var num1 = Math.floor((Math.random() * 30) + 10);
  var num2 = Math.floor((Math.random() * 30) + 10);
  var result = num1 + num2;
  var otherNumbers = [];
  var counter = 0;

  document.getElementById('field1').innerHTML = num1;
  document.getElementById('field2').innerHTML = num2;

  var options = {
   option1: document.getElementById('option1'),
   option2: document.getElementById('option2'),
   option3: document.getElementById('option3'),
   option4: document.getElementById('option4'),
  }

  function generateRandomNumber() {
    for (var i = 0; counter < 3; i++) {
      var num = Math.floor((Math.random() * 30) + 10);
      if (num !== result && counter < 3) {
         counter++;
         otherNumbers.push(num);
       } else {
        generateRandomNumber();
      }
    }
  }

  generateRandomNumber();
  
  otherNumbers.push(result);
  otherNumbers = shuffle(otherNumbers);
  
  var arrCount = otherNumbers.length - 1;
  for (var key in options) {
    if (arrCount >= 0) {
      options[key].innerHTML = otherNumbers[arrCount];
      arrCount--;
    }
  }
}

startGame();
.App {
  text-align: center;
}

.App-logo {
  animation: App-logo-spin infinite 20s linear;
  height: 60px;
}

.App-header {
  background-color: #222;
  height: 180px;
  padding: 20px;
  color: white;
}

.App-intro {
  font-size: large;
}

@keyframes App-logo-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.text-info {
  color: #fff;
  font-weight: bold;
  font-size: 2.1rem;
}

.question {
  font-size: 2rem;
}

.options {
  margin: 5%;
  display: flex;
  margin-right: -12px;
  margin-left: -12px;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: stretch;
  flex: 1 0 auto;
}

.fields {
  display: flex;
  padding: 12px;
  flex-direction: column;
  justify-content: flex-start;
  align-items: stretch;
  flex: 1;
}

.field-block {
  display: flex;
  min-height: 160px;
  padding: 10%;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  /*flex: 1 0 auto;*/
  border-radius: 4px;
  background-color: #f9bad0;
  font-size: 6rem;
  color: #fff;
  cursor: pointer;
}

.quiz {
  color: #ddd;
  margin: 2%;
  background-color: #ec1561;
  padding: 2%;
  width: 90%;
  position: relative;
}

.button {
  display: flex;
  height: 48px;
  padding-right: 16px;
  padding-left: 16px;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  flex: 0 0 auto;
  border-radius: 4px;
  background-color: #2fcaaa;
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .05), 0 2px 12px 0 rgba(0, 0, 0, .1);
  transition: box-shadow 200ms ease-out;
  color: #fff;
  font-weight: 500;
  text-align: center;
  cursor: pointer;
}

.quiz .after {
  position: absolute;
  top: 5%;
  left: 5%;
  width: 90%;
  height: 80%;
  /*display: none;*/
  color: #FFF;
  text-align: center;
  align-items: center;
  justify-content: center;
  display: flex;
  opacity: 0.8;
  font-size: 3rem;
}

.correct {
  background-color: green;
}

.wrong {
  background-color: #D91E18;
}

.hide {
  display: none !important;
}
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Adding 2 Numbers | Happy Learning!</title>
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
  </head>
<body>
 
<a href="https://happy-learning.herokuapp.com/ " target="_blank"><img alt="Join Slack" height="40" width="139" src="http://i.imgur.com/0Lne5Vr.png"/></a>
<div>
 <h1>Adding Game</h1>

 <p id="demo">In this lecture, we will cover the game to add 2 numbers.</p>
</div>
<hr>

<div class="quiz">
  <div class="quiz-content">
    <div class="question">
    What is the sum of <span class="text-info" id="field1">5</span> and <span class="text-info" id="field2">5</span>?
    </div>
    <div class="options">
      <div class="fields animated zoomIn">
        <div class="field-block" id="option1">
          10
        </div>
      </div>
      <div class="fields animated zoomIn">
        <div class="field-block" id="option2">
          10
        </div>
      </div>
      <div class="fields animated zoomIn">
        <div class="field-block" id="option3">
          10
        </div>
      </div>
      <div class="fields animated zoomIn">
        <div class="field-block" id="option4">
          10
        </div>
      </div>
    </div>
    <div class="after hide" id="after">

    </div>
    <div class="play-again">
      <a class="button" onclick="startGame()">Play Again</a>
    </div>
  </div>
</div>

<script src='index.js'></script>

</body>
</html>
P.S.
  • 15,970
  • 14
  • 62
  • 86
0

Here is a solution you can refer.

document.addEventListener("DOMContentLoaded", function(event) { 
  var num1 = Math.floor((Math.random() * 30) + 10);
    var num2 = Math.floor((Math.random() * 30) + 10);
    var result = num1 + num2;

    document.getElementById('field1').innerHTML = num1;
    document.getElementById('field2').innerHTML = num2;
    var opts = [];
    for(var i=0;i<3;i++){
      opts.push(findRandom(result,opts));
    }  
    opts.push(result);
    opts.sort();  
    for(var i=1;i<5;i++){ 
     document.getElementById('option'+i).innerHTML = opts[i-1];
    }  
});

function findRandom(n,opts){
  var result = 0;
  while(result !=n && result == 0){
    result = Math.floor(Math.random() * (n + 1)); 
    if(opts.indexOf(result) >0){
      result = 0;
    }
  }
  return result;
   
}
.App {
  text-align: center;
}

.App-logo {
  animation: App-logo-spin infinite 20s linear;
  height: 60px;
}

.App-header {
  background-color: #222;
  height: 180px;
  padding: 20px;
  color: white;
}

.App-intro {
  font-size: large;
}

@keyframes App-logo-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.text-info {
  color: #fff;
  font-weight: bold;
  font-size: 2.1rem;
}

.question {
  font-size: 2rem;
}

.options {
  margin: 5%;
  display: flex;
  margin-right: -12px;
  margin-left: -12px;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: stretch;
  flex: 1 0 auto;
}

.fields {
  display: flex;
  padding: 12px;
  flex-direction: column;
  justify-content: flex-start;
  align-items: stretch;
  flex: 1;
}

.field-block {
  display: flex;
  min-height: 160px;
  padding: 10%;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  /*flex: 1 0 auto;*/
  border-radius: 4px;
  background-color: #f9bad0;
  font-size: 6rem;
  color: #fff;
  cursor: pointer;
}

.quiz {
  color: #ddd;
  margin: 2%;
  background-color: #ec1561;
  padding: 2%;
  width: 90%;
  position: relative;
}

.button {
  display: flex;
  height: 48px;
  padding-right: 16px;
  padding-left: 16px;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  flex: 0 0 auto;
  border-radius: 4px;
  background-color: #2fcaaa;
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .05), 0 2px 12px 0 rgba(0, 0, 0, .1);
  transition: box-shadow 200ms ease-out;
  color: #fff;
  font-weight: 500;
  text-align: center;
  cursor: pointer;
}

.quiz .after {
  position: absolute;
  top: 5%;
  left: 5%;
  width: 90%;
  height: 80%;
  /*display: none;*/
  color: #FFF;
  text-align: center;
  align-items: center;
  justify-content: center;
  display: flex;
  opacity: 0.8;
  font-size: 3rem;
}

.correct {
  background-color: green;
}

.wrong {
  background-color: #D91E18;
}

.hide {
  display: none !important;
}
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Adding 2 Numbers | Happy Learning!</title>
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
  </head>
<body>
 
<a href="https://happy-learning.herokuapp.com/ " target="_blank"><img alt="Join Slack" height="40" width="139" src="http://i.imgur.com/0Lne5Vr.png"/></a>
<div>
 <h1>Adding Game</h1>

 <p id="demo">In this lecture, we will cover the game to add 2 numbers.</p>
</div>
<hr>

<div class="quiz">
  <div class="quiz-content">
    <div class="question">
    What is the sum of <span class="text-info" id="field1">5</span> and <span class="text-info" id="field2">5</span>?
    </div>
    <div class="options">
      <div class="fields animated zoomIn">
        <div class="field-block" id="option1">
          10
        </div>
      </div>
      <div class="fields animated zoomIn">
        <div class="field-block" id="option2">
          10
        </div>
      </div>
      <div class="fields animated zoomIn">
        <div class="field-block" id="option3">
          10
        </div>
      </div>
      <div class="fields animated zoomIn">
        <div class="field-block" id="option4">
          10
        </div>
      </div>
    </div>
    <div class="after hide" id="after">

    </div>
    <div class="play-again">
      <a class="button">Play Again</a>
    </div>
  </div>
</div>

<script src='index.js'></script>

</body>
</html>
Vineesh
  • 3,762
  • 20
  • 37
0

As per my comment, you will need to re-run that number generator to generate new and incorrect answers for the 3 remaining options. There are a few things that you want to watch out for:

  1. You have to avoid collisions, i.e. do not generate numbers that are the same as the answer, or the same as any pre-generated incorrect options. We can make this simple check by using a while loop
  2. You can use a generic function to generate num1 + num2, so that it can be re-used again to generate incorrect answers.
  3. Instead of giving your options unique IDs, simply give them a generic class, e.g. <div class="field-block option"></div> . We want to be able to know how many options we have so that we generate correct number of answer + incorrect answers.
  4. You might want to shuffle your answers array before appending them to the DOM, otherwise they will all have the first element containing the correct answer.

Side note: Although it is not mentioned in your original answer, I expected that you want to know which is the correct answer when a user click on that option. When a click event is fired from the option, you can simply get the index of the option, and check it against the answers array. If the option's index matches the index of the correct answer in the array, then you are good to go.


In the code snippet below, I have stripped the stylesheet and some unnecessary markup:

// FY shuffle
function shuffle(a) {
    var j, x, i;
    for (i = a.length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        x = a[i];
        a[i] = a[j];
        a[j] = x;
    }
}

// Function that generates all options
var generateAllOptions = function() {
  // Number generator
  var getRandomNumber = function() {
    return Math.floor((Math.random() * 30) + 10);
  };
  
  // Get the question + correct answer
  var num1 = getRandomNumber();
  var num2 = getRandomNumber();
  var correctAnswer = num1 + num2;
  var answers = [correctAnswer];
  
  // Update question
  document.getElementById('field1').innerHTML = num1;
  document.getElementById('field2').innerHTML = num2;
  
  // Generate incorrect answers/options, but make sure there are no collisions
  var options = document.querySelectorAll('.options .option');
  while(answers.length < options.length) {
    var incorrectAnswer = getRandomNumber() + getRandomNumber();
    if (answers.indexOf(incorrectAnswer) === -1)
      answers.push(incorrectAnswer);
  }
  
  // Shuffle answers
  shuffle(answers);
  
  // Store index of correct answer
  var correctIndex = answers.indexOf(correctAnswer);
  
  // Append shuffled answers to options
  for (var i = 0; i < options.length; i++) {
  
    var option = options[i];
    
    // Write answer values into innerHTML
    option.innerHTML = answers[i];
    
    // Bind click event to all options, use IIFE!
    (function(idx) {
      option.addEventListener('click', function() {
        if (idx === correctIndex) {
          alert('You have selected the right answer!');
        } else {
          alert('That is an incorrect answer.');
        }
      });
    })(i);
  }
  
  
  
  
};

generateAllOptions();
.option {
  font-weight: bold;
  background-color: steelblue;
  color: #fff;
  border-radius: 4px;
  padding: 10px;
  margin: 5px;
}
<div>
  <h1>Adding Game</h1>

  <p id="demo">In this lecture, we will cover the game to add 2 numbers.</p>
</div>
<hr>

<div class="quiz">
  <div class="quiz-content">
    <div class="question">
      What is the sum of <span class="text-info" id="field1">5</span> and <span class="text-info" id="field2">5</span>?
    </div>
    <div class="options">
      <div class="fields animated zoomIn">
        <div class="field-block option"></div>
      </div>
      <div class="fields animated zoomIn">
        <div class="field-block option"></div>
      </div>
      <div class="fields animated zoomIn">
        <div class="field-block option"></div>
      </div>
      <div class="fields animated zoomIn">
        <div class="field-block option"></div>
      </div>
    </div>
    <div class="after hide" id="after">

    </div>
    <div class="play-again">
      <a class="button">Play Again</a>
    </div>
  </div>
</div>
Terry
  • 63,248
  • 15
  • 96
  • 118
0

Try this simple solution. This generates 4 unique random options out of which one option is the correct one. The option number of the correct answer is also random.

You only need to modify your js.

var num1 = Math.floor((Math.random() * 30) + 10);
var num2 = Math.floor((Math.random() * 30) + 10);
var result = num1 + num2;

var ansIndex=(Math.floor((Math.random()*10))%4)+1; //this index will be the position of the correct answer

var option=[];

//the below loop fills the options array with random but unique options
for(var i=0;i<4;i++){
   var temp=Math.floor((Math.random() * 30) + 10);
   if(final.indexOf(temp)==(-1)){
        option.push(temp);
        continue;
   }
   else{
        i--;
   }
}

//finally the correct option is overwritten
option[ansIndex-1]=result;


var answer=document.getElementsByClassName("field-block");
answer[0].innerHTML=option[0];
answer[1].innerHTML=option[1];
answer[2].innerHTML=option[2];
answer[3].innerHTML=option[3];



document.getElementById('field1').innerHTML = num1;
document.getElementById('field2').innerHTML = num2;
Samay Jain
  • 265
  • 1
  • 13