Galeforce
Galeforce

Reputation: 53

Prevent Subsequent Random Results Repeating In Javascript

On my website I have a button that selects a random quote from a list of quotes and projects the randomly selected quote into a text box. This is done using JavaScript.

Although I have this working, I'd like an additional piece of code that will prevent the directly subsequent quote being the same as the previous. I'd like any quote used to be able appear again however, just not directly following.

If possible I'd also like it so any quote used does not appear again for a minimum of another 3 clicks - but this would just be a bonus.

Anyway the code I currently have is as follows:

<head>    
  <script language="javascript"><!--
    function GenerateQuote(){var aquote=new Array;
      aquote[0]="\"Quote0\"";
      aquote[1]="\"Quote1\"";
      aquote[2]="\"Quote2\""
      aquote[3]="\"Quote3\"";
      aquote[4]="\"Quote4\"";
      aquote[5]="\"Quote5\"";
      aquote[6]="\"Quote6\"";
    rdmQuote=Math.floor(Math.random()*aquote.length);
    document.getElementById("quoteBox").value=aquote[rdmQuote];
    }
  -->
  </script>
</head>

<body>
  <textarea id="quoteBox" readonly></textarea>
  <button onClick="GenerateQuote()">Entertainment & Hobbies</button>
</body>

Thanks in advance; I'm sure it won't be too hard for you brainiacs!

Upvotes: 0

Views: 242

Answers (4)

Esailija
Esailija

Reputation: 140230

<head>
    <script type="text/javascript">
!function (){
    var quotes = ["quote0", "quote1", "quote2", "quote3", "quote4", "quote5", "quote6", "quote7", "quote8"],
        shuffleAfter = quotes.length, cur = 0;


    function shuffle( arr ) {
        var l = arr.length, j, i, tmp;

        for( i = l - 1; i > 0; --i ) {
            j = ( Math.random() * ( i + 1 ) ) >>> 0;
            tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }

        return arr;
    }

    function generateQuote(){
        var r;

        if( cur++ % shuffleAfter === 0 ) {
            shuffle(quotes);
        }

        r = quotes.shift();

        quotes.push( r );

        return r;
    }


    window.generateQuote = generateQuote;
}()
    </script>
</head>
<body>
    <textarea id="quoteBox" readonly></textarea>
    <button onClick="document.getElementById('quoteBox').value = generateQuote()">Entertainment & Hobbies</button>
</body>

Results from calling generateQuote() 27 times:

2,9,7,5,8,1,3,4,6,9,6,1,7,5,4,3,2,8,3,1,6,5,2,7,9,4,8,2

As you can see, after a full cycle the quotes are shuffled again and there is a chance the same quote will appear if it was last in the last cycle and is first in the new cycle. It should be much better than playlist shuffling in my mp3 player at least :P

Upvotes: 1

malko
malko

Reputation: 2382

you can tweak dontRepeatUntil to sweats your need There's certainly better way but this one should work

var latestQuote = []
    , dontRepeatUntil=3
    , rdmQuote = null
    , quotes=[
        "\"Quote0\""
        ,"\"Quote2\""
        ,"\"Quote3\""
        ,"\"Quote4\""
        ,"\"Quote5\""
        ,"\"Quote6\""
    ]
;
function GenerateQuote(){
if(latestQuote.length >= dontRepeatUntil){
    latestQuote = latestQuote.slice(latestQuote.length-dontRepeatUntil+1);
}
    do{
        rdmQuote=Math.floor(Math.random()*quotes.length);
    }while(latestQuote.join(',').match(new RegExp('(^|,)'+rdmQuote+'(,|$)')));
    latestQuote.push(rdmQuote);
    document.getElementById("quoteBox").value=quotes[rdmQuote];
}

Upvotes: 0

Fabrizio Calderan
Fabrizio Calderan

Reputation: 123397

  1. Fill an array of quotation, then create a copy.
  2. Scramble the copy of the array (you can just use .sort() method or even better you can look for a js implementation of Fisher-Yates alghoritm
  3. Call pop() over the array on each click event so you will generate every time a different quote until the array is fully consumed
  4. When length of the array is zero goto 1)

Reference:

Upvotes: 1

Eugen Rieck
Eugen Rieck

Reputation: 65274

use

var lastQuote=-1;

outside your function, then

var rdmQuote=lastQuote;
while (rdmQuote==lastQUote) rdmQuote=Math.floor(Math.random()*aquote.length);
lastQuote=rdmQuote;

inside your function

Upvotes: 0

Related Questions