Home > OS >  How could I restart this current function
How could I restart this current function

Time:12-20

During the use of this function you click a button that will give you a square that will display a colour within a square. However when you click the button 60 times the programme stops working because all the colours have been used. How would I then restart this process so that I can continue clicking ?

<html>
    <head>
        <script>
            var usedColors = [];
            
            function randomColour(){
                var colour=[];
                colour[0]= '#edf2fb';
                colour[1]= '#d7e3fc';
                colour[3]= '#c1d3fe';
                colour[4]= '#d1d1d1';
                colour[5]= '#e1dbd6';
                colour[6]= '#e2e2e2';
                colour[7]= '#f9f6f2';
                colour[8]='#ffc09f';
                colour[9]='#ffee93';
                colour[10]='#fcf5c7';
                colour[11]='#a0ced9';
                colour[12]='#adf7b6';
                colour[13]='#809bce';
                colour[14]='#95b8d1';
                colour[15]='#b8e0d2';
                colour[16]='#d6eadf';
                colour[17]='#eac4d5';
                colour[18]='#e8d1c5';
                colour[19]='#eddcd2';
                colour[20]='#fff1e6';
                colour[21]='#f0efeb';
                colour[22]='#eeddd3';
                colour[23]='#e8dff5';
                colour[24]='#fce1e4';
                colour[25]='#fcf4dd';
                colour[26]='#ddedea';
                colour[27]='#daeaf6';
                colour[28]='#d3ab9e';
                colour[29]='#eac9c1';
                colour[30]='#ebd8d0';
                colour[31]='#ffe5ec';
                colour[32]='#ffc2d1';
                colour[33]='#ceb5b7';
                colour[35]='#b5d6d6';
                colour[36]='#f2f5ff';
                colour[37]='#efcfe3';
                colour[38]='#eaf2d7';
                colour[39]='#b3dee2';
                colour[40]='#f8ad9d';
                colour[41]='#fbc4ab';
                colour[42]='#ffdab9';
                colour[43]='#cdb4db';
                colour[44]='#ffc8dd';
                colour[45]='#ffafcc';
                colour[46]='#bde0fe';
                colour[47]='#a2d2ff';
                colour[48]='#fdffb6';
                colour[49]='#caffbf';
                colour[50]='#9bf6ff';
                colour[51]='#a0c4ff';
                colour[52]='#ffc6ff';
                colour[53]='#a7bed3';
                colour[54]='#c6e2e9';
                colour[55]='#f1ffc4';
                colour[56]='#ffcaaf';
                colour[57]='#dab894';
                colour[58]='#fec7bc';
                colour[59]='#fcf5ee';
  
                var pick= Math.floor(Math.random()*60);
  
                if(usedColors.includes(pick)){
                    randomColour();
                }
  
                usedColors.push(pick); document.getElementById("colorpad").style.backgroundColor = colour[pick];
                console.log(usedColors);
            }
        </script>
    </head>
    <body>
        <div id="colorpad" style="height: 300px; width: 300px;">
            <button onclick="randomColour()">btn</button>
        </div>
    </body>
</html>

CodePudding user response:

Keep track of the current color:

let curr = 0;

On "Next" button click increment the curr index, and loopback with the help of the Modulo Operator %:

curr  = 1;
curr %= colour.length; // On "next" loop back to 0 if we reached the end

Finally there's your color back at 0

console.log(colour[curr]);    // '#edf2fb'

Demonstration:

const EL = (sel, EL) => (EL||document).querySelector(sel);

const colors = [
  '#edf2fb',
  '#d7e3fc',
  '#c1d3fe',
  '#d1d1d1',
  '#e1dbd6',
  '#e2e2e2',
  '#f9f6f2',
  '#ffc09f',
  '#ffee93',
  '#fcf5c7',
];

const tot = colors.length;
let curr = 0;

const curr_rand = () => curr = Math.floor(Math.random() * tot);
const curr_next = () => (curr  = 1, curr %= tot);
const applyColor = () => EL("body").style.background = colors[curr];

EL("#rand").addEventListener("click", () => {
  curr_rand();
  applyColor();
  console.log(curr);
});

EL("#next").addEventListener("click", () => {
  curr_next();
  applyColor();
  console.log(curr);
});
<button type="button" id="rand">Generate</button>
<button type="button" id="next">Next</button>

CodePudding user response:

Here's a snippet using a small factory function to be able to recolor infinitely. The recoloring is done using a randomly shuffled copy of the color array. This way you don't have to check each time if a color is already used.

Furthermore, see comments in the snippet. It uses event delegation for the handler, because it's generally not a good idea to use inline event handlers.

To keep the snippet lean, only 10 colors are used.

const colorize = randomColor(
  ['#edf2fb', '#d7e3fc', '#c1d3fe', '#d1d1d1', '#e1dbd6',
   '#e2e2e2', '#f9f6f2', '#ffc09f', '#ffee93', '#fcf5c7'] );

document.addEventListener(`click`, evt => {
  if (evt.target.id === `colorChange`) {
    return colorize(document.querySelector(`.color`));
  }
});

// randomColor is a factory function, it returns a function. 
// The function can use the inner variables as well as the 
// [colors] array from the parameter(they are 'closed over'). 
// The [colors] array is shuffled randomly (Fisher-Yates) and 
// on every call (from click) the first color from that shuffled 
// array is picked - until it's empty. If [shuffled] is empty 
// the original [color] array is reshuffled (into [shuffled]).
// This way  the coloring is restarted with a new set of 
// random colors.
function randomColor(colors){
  const shuffle = array =>
    [...Array(array.length)]
      .map((el, i) => Math.floor(Math.random() * i))
      .reduce( (a, rv, i) => 
        ([a[i], a[rv]] = [a[rv], a[i]]) && a, array.slice());
  //                                          ^ slice copies the original      
  let shuffled = shuffle(colors);
  
  // return a function
  return colorDiv => {
    const restarted = !shuffled.length;
    shuffled = shuffled.length > 0 ? shuffled : shuffle(colors);
    const nwColor = shuffled.shift();
    colorDiv.style.backgroundColor = nwColor;
    
    // for demo: color is displayed, and bold/red if [shuffled] is renewed
    colorDiv.classList[restarted ? `add` : `remove`](`restart`);
    colorDiv.dataset.color = nwColor;
  }
}
.color {
  width: 100px;
  height: 100px;
  border: 1px solid #777;
  margin: 1rem 0;
  text-align: center;
  line-height: 100px;
}

.color:before {
  content: attr(data-color);
}

.color.restart:before {
  color: red;
  font-weight: bold;
}
<div ></div>

<button id="colorChange">change</button>

CodePudding user response:

Since, the colors will be repeated after 60tries, why not instead of appending to the list, do the following:

Check if the current color is same as the last color, if it is same then call random function. Otherwise, replace the color in usedColor with the current color.

  • Related