简体   繁体   中英

Algorithm stops and I don't have no idea why

Hey! I am trying to code Pexeso with HTML, CSS and Javascript. I have random generating function (number can't be used more then one time - I solved this with the array). Then I have another function which calls the mentioned function and choose by the returned number id of img element and sets image source. Everything looks right - IDE and Google Chrome don't return any errors, but it still doesn't do the right thing - it never source all images.

I am putting the code and also screen how it looks after compiling.

HTML

<!DOCTYPE html>
<html lang='cs'>
  <head>
    <title></title>
    <meta charset='utf-8'>
    <link href='style.css' rel='stylesheet' type='text/css'>
  </head>
  <body>
  <div class="container">
    <img class="pexeso" src="" id="1">
    <img class="pexeso" src="" id="2">
    <img class="pexeso" src="" id="3">
    <img class="pexeso" src="" id="4">
    <img class="pexeso" src="" id="5">
    <img class="pexeso" src="" id="6">
    <img class="pexeso" src="" id="7">
    <img class="pexeso" src="" id="8">
    <img class="pexeso" src="" id="9">
    <img class="pexeso" src="" id="10">
    <img class="pexeso" src="" id="11">
    <img class="pexeso" src="" id="12">
    <img class="pexeso" src="" id="13">
    <img class="pexeso" src="" id="14">
    <img class="pexeso" src="" id="15">
    <img class="pexeso" src="" id="16">       
  </div>
  <script src='app.js'></script>
  </body>
</html>

JS

var position;
position = new Array();

function generateNumber(){
//generates random number between 0 and 15
var number = Math.round(Math.random()*15)+1;

//checks if number is already used
for (var i = 0; i <= position.length; i++){
    if (position[i] == number){
        generateNumber();
    }

//returns number
    console.log(number);
    position.push(number);
    return number;
}
}

function mixPexeso(){
for (var i = 0; i <= 7; i++){
//sets images to their location and type their position
    var firstImage = generateNumber();
    var secondImage = generateNumber();
    var image = 'img/image-'+i+'.png';

    document.getElementById(firstImage).src = image;
    document.getElementById(secondImage).src = image;
    }
}

mixPexeso();

Screen: https://prnt.sc/l4wr1q

The problem:

When you find out that the number already exist, you should break the loop and return the result of generateNumber :

if (position[i] == number) {
    return generateNumber();
}

Alternative way:

Anyways, the function generateNumber could be implemented in a better way by removing the recursive calls and wrapping the whole thing in an IIFE for encapsulation:

var generateNumber = (function() {
  var numbers = [];

  return function() {
    var number;
    do {
      number = Math.floor(Math.random() * 16);
    } while(numbers.includes(number));
    numbers.push(number);
    return number;
  }
})();

Best way:

An even better way is to prefill the array with numbers (0 through 15), shuffle them and then each time the function gets called, you just pop or shift a number from that array:

var generateNumber = (function() {
  var numbers = [];

  for(var i = 0; i < 16; i++) numbers.push(i);

  for(var i = 0; i < 16; i++) {
    var randIndex = Math.floor(Math.random() * 16);
    var temp = numbers[i];
    numbers[i] = numbers[randIndex];
    numbers[randIndex] = temp;
  }

  return function() {
    return numbers.pop();
  }
})();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM