Pseudo random function help

Hi,
I am using a WAVE Shield to play songs.
I want to play all 10 songs in a random order every time until it has played all 10, then start over.
I know there should be an easy solution to this, but am kind of stuck.
My code is below and as you can see, it doesn't do what I need so far.
How can I pick 10 items at random until all 10 are picked?
Thanks.

void randomizer()
{
       songNumber = random(10);

      if (songNumber == prevSong)
       {
                    songNumber = random(10);
       }
       prevSong = songNumber;
}

Keep a simple 10 bit bit-mask in an "int".
As you select a song, set the corresponding bit.
If the bit is already set, pick another.

Can anyone give me an example of a bit mask?
Ok, I found an example. Let me make sure I understand it.
Ignoring all the transmit stuff I want to convert this for part of my random fuction.

Where I get lost is here

else{ //if bitwise and resolves to false
digitalWrite(transmit,LOW); // send 0
}

In this section I would have a new random number that has not been picked. How do I write that this has now been picked?
Say my new random number was 3. How do I write that the number 3 has now been picked and not to pick it again?

byte transmit = 7; //define our transmit pin
byte data = 170; //value to transmit, binary 10101010
byte mask = 1; //our bitmask
byte bitDelay = 100;

void setup()
{
   pinMode(transmit,OUTPUT);
}

void loop()
{
  for (mask = 00000001; mask>0; mask <<= 1) { //iterate through bit mask
    if (data & mask){ // if bitwise AND resolves to true
      digitalWrite(transmit,HIGH); // send 1
    }
    else{ //if bitwise and resolves to false
      digitalWrite(transmit,LOW); // send 0
    }
    delayMicroseconds(bitDelay); //delay
  }
}

If you're uncomfortable with explicit bit manipulation, the Arduino provides library functions:
http://arduino.cc/en/Reference/Bit
http://arduino.cc/en/Reference/BitWrite
http://arduino.cc/en/Reference/BitRead etc.

How do I write that this has now been picked?

You set the corresponding bit.

Imagine how you might do this manually.
You've got a ten-sided die (I did say "imagine"!), and a piece of paper with ten boxes.
You roll the die and it comes up "3", so you put tick in box 3, and play song 3.
You roll again and get 3 again.
You look at your sheet of paper and see a tick in box 3, so you roll again.
You get a 7, so put a tick in box 7 and rinse and repeat.

I would do it another way.
Have an array of numbers 1 to 10. Initialise them so that the number in the array matches the index. Then generate a pair of random numbers and use them as the index to swap the values in the array. Repeat this process as long as you like and play the list.
Then for next time round just repeat the swapping routine again as many times as you like.
That way all samples are played only once and the order is different every time.

Thanks for the help everyone. I might find arrays a little easier. I'll let you know which solution I try.

A bitmask is an array - it's the ultimate boolean array.

Ok. I think I get what Grumpy_Mike is saying. I should randomize the list then just play the list. Once the list is done randomize it again and then play it again.

Where I get fuzzy is here.

Then generate a pair of random numbers and use them as the index to swap the values in the array

So far I've got the code here. This will generate a random list, but it being completely random I could get the same song 10 times in a row.

int mySongs[10]={0,1,2,3,4,5,6,7,8,9};

void RandomList()
{
      randomNumber=random(10);
    int i;
          for (i = 0; i < 10; i = i + 1) 
            {
          songToPlay=random(10);
          mySongs[i] = songToPlay;
            }
}

You need a "shuffling algorithm". A general description is here...

int bitmask = 0;
for (int i = 0; i < 10; i++) {
  int song;
  do {
    song = random (10);
  } while (bitRead (bitmask, song));
  bitSet (bitmask, song);
  playSong (song);
}

Thanks AWOL. I'll try that when I get home.

Never heard of a Fisher–Yates shuffle before, interesting...

Then generate a pair of random numbers and use them as the index to swap the values in the array

int mySongs[10]={0,1,2,3,4,5,6,7,8,9};

void RandomList()
{
      int randomNumber1, randomNumber2, temp;  
  
          for (int i = 0; i < 30; i = i + 1)
            {
      // generate two numbers
         randomNumber1=random(10);
         randomNumber2=random(10);
       // swap numbers in array
          temp = mySongs[randomNumber1];
        mySongs[randomNumber1] = mySongs[randomNumber2];
       mySongs[randomNumber2] = temp
            }
}

Thanks again for the help. Both solutions seem to work.
I'll use the bit mask one because it is shorter.
:slight_smile: