skip to Main Content

My project includes a function that generates three random numbers from the basket and maps each to a button. The idea is that each time you press a button you will get three new numbers and the number you pressed will be removed from the array. However, whenever the startTurn function is called, it spits out the same 3 numbers.

const repeat = (arr, n) => Array(n).fill(arr).flat();
let basket = repeat(["red", "orange", "yellow", "green", "blue", "purple"], 3);

function newGame() {
  basket = repeat(["red", "orange", "yellow", "green", "blue", "purple"], 3);
  console.log(basket);
  startTurn();
}


const button1 = document.querySelector('#button1');
const button2 = document.querySelector('#button2');
const button3 = document.querySelector('#button3');
const button4 = document.querySelector('#new-game');

let turncount = 0;
let choice = [];

function startTurn(){
  while(choice.length <= 3){
    let r = Math.floor(Math.random() * (basket.length)) ;
    if(choice.indexOf(r) === -1) choice.push(r);
  }
  button1.style.backgroundColor = basket[choice[0]];
  button2.style.backgroundColor = basket[choice[1]];
  button3.style.backgroundColor = basket[choice[2]];
  console.log(basket.length);
  console.log(basket[choice])
}

2

Answers


  1. The problem is caused by this

    ...
    while(choice.length <= 3){
    ...
    

    Since your choice array is declared at Global Scope, once it gets filled up, that’s it. It will no longer be able to access that while loop.

    As every time startTurn() is called, the same old choice array with initial 3 generations will keep on repeating.

    If you want it randomized each time and still have choice accessible at Global Scope, then empty choice each time before the loop starts.

    function startTurn(){
      // Empty choice, so that it regenerates
      choice = [];
    
      while(choice.length <= 3){
        let r = Math.floor(Math.random() * (basket.length)) ;
        if(choice.indexOf(r) === -1) choice.push(r);
      }
      button1.style.backgroundColor = basket[choice[0]];
      button2.style.backgroundColor = basket[choice[1]];
      button3.style.backgroundColor = basket[choice[2]];
      console.log(basket.length);
      console.log(basket[choice])
    }
    

    Here’s a barebones working example

    const repeat = (arr, n) => Array(n).fill(arr).flat();
    let basket = repeat(["red", "orange", "yellow", "green", "blue", "purple"], 3);
    
    function newGame() {
      basket = repeat(["red", "orange", "yellow", "green", "blue", "purple"], 3);
      // console.log(basket);
      startTurn();
    }
    
    
    const button1 = document.querySelector('#button1');
    const button2 = document.querySelector('#button2');
    const button3 = document.querySelector('#button3');
    const button4 = document.querySelector('#new-game');
    
    let turncount = 0;
    let choice = [];
    
    function startTurn(){
      choice = []
      while(choice.length <= 3){
        let r = Math.floor(Math.random() * (basket.length)) ;
        if(choice.indexOf(r) === -1) choice.push(r);
      }
      button1.style.backgroundColor = basket[choice[0]];
      button2.style.backgroundColor = basket[choice[1]];
      button3.style.backgroundColor = basket[choice[2]];
      // console.log(basket.length);
      // console.log(basket[choice])
    }
    .button {
      padding: 8px;
      border: none;
      border-radius: 4px;
      
      color: white;
      background: #555;
    }
    <!DOCTYPE html>
    <html>
    <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
    
    <button class="button" id="button1" > Button 1 </button>
    <button class="button" id="button2" > Button 2 </button>
    <button class="button" id="button3" > Button 3 </button>
    <button class="button" id="new-game" onclick="newGame()" > New Game </button>
    
    </body>
    </html>
    Login or Signup to reply.
  2. Here is a rewrite of your JavaScript part using a simple shuffle for each game. I reduced the colors such that they will not be repeated in the buttons.

    function shfl(a){ // Durstenfeld shuffle
     for(let j,i=a.length;i>1;){
      j=Math.floor(Math.random()*i--);
      if (i!=j) [a[i],a[j]]=[a[j],a[i]]
     }
     return a
    }
    const basket = ["red", "orange", "yellow", "green", "blue", "purple"],
          btns=document.querySelectorAll("button[id^=button]");
    
    function startTurn(){
      shfl(basket);
      btns.forEach((b,i)=>b.style.backgroundColor=basket[i]);
    }
    startTurn();
    .button {
      padding: 8px;
      border: none;
      border-radius: 4px;    
      color: white;
      background: #555;
    }
    <button class="button" id="button1" > Button 1 </button>
    <button class="button" id="button2" > Button 2 </button>
    <button class="button" id="button3" > Button 3 </button>
    <button class="button" id="new-game" onclick="startTurn()" > New Game </button>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search