Picking a random word

So my friends and i play this weird game where we try to find the 6 degrees of separation between 2 actors. However we tend to pick actors that we already know.

So basically what i was wondering was if there was a way to make the arduino pick two random actor names out of a big list i have in the program and then display them both on my computer (or lcd, but i don't have one yet) so computer for now.

I read about the random code for the arduino but it seems to just be for numbers :-/

If anyone has any ideas how to write said program or any sites i can go to that will explain this let me know.

Do you mean a random word like 'fwiopb', or a random word from a list?

lol good point i should have clarified

I mean a random word (aka the actor name) from a list or if possible show the two actors names needed for the game

ps. I like the made up word

well actually you DID clarify already.

pick two random actor names out of a big list

Here's a rough starting point. You'll come accross a few things you'll need to sort out as you develop it - but hey - that's where the fun is.

char *actors[]={"Tom", "Dick", "Harry", "Sheila"};
long actor1;

void setup()
{
  Serial.begin(9600);
  randomSeed(666);
}

void loop()                     
{
  actor1 = random(sizeof(actors)/sizeof(char*));
  Serial.println(actors[actor1]);
  delay(1000); 
}

Wow thank you sooooo much.

It works beautifuly. I changed the code a little so that it would pick and display 2 names.

However it seems that it always uses the same pairs. I'll turn it on and push the button and it picks 2 names and if i close the serial monitor and then open it and hit the button again it picks the same 2 names. If i keep hitting it without closing it apears to be random, but if i close and open it it still uses the same pairs in the same order.

heres the code

#define BUTTON 6

char *actors[]={
"Brad Pitt", 
"Edward Nortan", 
"Ashton Kutcher", 
"Demi Moore",
"Reese Witherspoon",
"Will Smith",
"Johnny Depp",
"Tom Hanks",
"George Clooney",
"Will Ferrell",
"Nicolas Cage",
"Leonardo DiCaprio",
"Russell Crowe",
"Tom Cruise",
"Jim Carrey",
"Chris Pine",
"Nicole Kidman",
"Jude Law",
"Julia Roberts"
};
long actor1;
long actor2;

int val = 0;

void setup()
{
  Serial.begin(9600);
  randomSeed(666);
  pinMode(BUTTON, INPUT);
  Serial.println("Six Degrees of Seperation");
}

void loop()
{
  val = digitalRead(BUTTON);
  if (val == HIGH)
  {
    actor1 = random(sizeof(actors)/sizeof(char*));
    actor2 = random(sizeof(actors)/sizeof(char*));
    Serial.println();
    Serial.println(actors[actor1]);
    Serial.println();
    Serial.println(actors[actor2]);
    delay(500);
  }
  else
  {
   return;
  }
}

Any ideas why it's picking the same everytime?

Any ideas why it's picking the same everytime?

Yes.

  randomSeed(666);

...starts at the same point in the "random" sequence. There is code in the forum for initializing random using an analog input. It has some potential problems.

My suggestion is to store the random seed in EEPROM and use the stored value to intialize on power-up.

Makes sense enough why it isn't working.

However not quite sure how i should go about storing the info from the random drive to the ram and then calling it back up when i start it

thanks again

1 Like

Give this a try...

#include <EEPROM.h>


template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
    const byte* p = (const byte*)(const void*)&value;
    int i;
    for (i = 0; i < sizeof(value); i++)
        EEPROM.write(ee++, *p++);
    return i;
}


template <class T> int EEPROM_readAnything(int ee, T& value)
{
    byte* p = (byte*)(void*)&value;
    int i;
    for (i = 0; i < sizeof(value); i++)
        *p++ = EEPROM.read(ee++);
    return i;
}
 

void BetterRandomSeed( void )
{
  unsigned long __seed;
  
  EEPROM_readAnything( 0, __seed );
  
  srandom( __seed );
}


long BetterRandom( void )
{
  long __seed;
  
  __seed = random();
  
  EEPROM_writeAnything( 0, __seed );

  return( __seed );
}


long BetterRandom( long howbig )
{
  if ( howbig == 0 ) 
  {
    return 0;
  }
  return( BetterRandom() % howbig );
}


long BetterRandom( long howsmall, long howbig )
{
  if ( howsmall >= howbig ) 
  {
    return howsmall;
  }
  long diff = howbig - howsmall;
  
  return( BetterRandom(diff) + howsmall );
}


char *actors[]={
"Brad Pitt",
"Edward Nortan",
"Ashton Kutcher",
"Demi Moore",
"Reese Witherspoon",
"Will Smith",
"Johnny Depp",
"Tom Hanks",
"George Clooney",
"Will Ferrell",
"Nicolas Cage",
"Leonardo DiCaprio",
"Russell Crowe",
"Tom Cruise",
"Jim Carrey",
"Chris Pine",
"Nicole Kidman",
"Jude Law",
"Julia Roberts"
};
long actor1;
long actor2;

int val = 0;

void setup()
{
  Serial.begin( 9600 );
  BetterRandomSeed();
  Serial.println( "Six Degrees of Seperation" );
}

void loop()
{
  actor1 = BetterRandom(sizeof(actors)/sizeof(char*));
  do
  {
    actor2 = BetterRandom(sizeof(actors)/sizeof(char*));
  }
  while ( actor2 == actor1 );
  
  Serial.print(actors[actor1]);
  Serial.print( "  +  " );
  Serial.print(actors[actor2]);
  Serial.println();
  
  delay( 500 );
}

Wow that works great, thanks.

I just added the code for my button control, and changed the output view a little and it's awesome.

Any chance you might have a min or 2 to explain to me how that code works?

Thanks

Do you have specific questions or do you want an overview?

lets go with an overview lol. Also if you know of any books that will help explain the programing language that would be super.
thanks

Well, storing a number into and retrieving from EEPROM needs not really all that C++
See my pet example:

byte byte8ofEEPROM =EEPROM.read( 8);
EEPROM.write(8,byte8ofEEPROM+1);
while(byte8ofEEPROM&1);

Also if you know of any books that will help explain the programing language that would be super.

Sorry, I can't help with that one. It has been too long since I needed a C(++) book for me to be able to recommend something.

lets go with an overview

Sounds good...

The Arduino random functions are based on the functions provided in "stdlib"; a library provided with most C(++) compilers. There are two functions of interest from "stdlib": random and srandom. random takes a 32 bit seed value, performs some math on this value, and returns the result. The returned result is the seed for the next call. random uses the "Park-Miller" generator. srandom simply sets the seed value used the next time random is called.

EEPROM_writeAnything and EEPROM_readAnything are templates graciously provided by halley. A template, in this usage, is similar to a function. EEPROM_writeAnything takes a variable of any type and writes it to EEPROM. In this Sketch, it's used to write the 32-bit seed value to EEPROM address zero. EEPROM_readAnything reads data from EEPROM into a variable of any type. In this Sketch, it's used to read the 32-bit seed from address zero.

The four BetterRandom* functions take the place of the corresponding Arduino random* functions. BetterRandom( long howbig ) and BetterRandom( long howsmall, long howbig ) use BetterRandom( void ) instead of random but are otherwise identical to their Arduino cousins. BetterRandomSeed reads the 32-bit seed value from EEPROM and calls srandom to set the next seed value for random. BetterRandom( void ) calls random to get the next "random" value and saves this value to EEPROM to be used as the seed the next time setup / BetterRandomSeed is called.

This snippet of code...

  do
  {
    actor2 = BetterRandom(sizeof(actors)/sizeof(char*));
  }
  while ( actor2 == actor1 );

...ensures a different actor is printed for the second choice. After all, it isn't too difficult to find movies that include Clive Owen and Clive Owen!

May I suggest a small change for treating the EEPROM with a little bit more care?

void betterRandomSeed( void ) {
  unsigned long __seed;
  EEPROM_readAnything( 0, __seed );
  srandom( __seed );
  EEPROM_writeAnything( 0, - random());
}

Now there is no need for a betterRandom anymore, however betterRandomSeed must be called initially...

May I suggest a small change for treating the EEPROM with a little bit more care?

Have you tested to ensure your code does not interfere with the proper function of random?

Have you researched how the Park-Miller algorithm functions in the face of negative values?

The EEPROM on Atmel processors is guaranteed for 100,000 cycles. If galapagos88 lives to be 100 years old, how many times per day must he play the game to reach the guaranteed lifespan?

Alright so everything is working great. I added in command line for 3 buttons to control a point system, and to call the names up. However when my friend and i went in to add a bunch of actors names at a certian point the program started glitching out. For example it seemed like every name i added past this point it would erase a line of my serial print.

Here's the code

#include <EEPROM.h>
#define BUTTON 4
#define rbutton 5
#define bbutton 3

int red_old = 0;
int red_new = 0;
int red_button = 0;
int blue_old = 0;
int blue_new = 0;
int blue_button = 0;



template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
    const byte* p = (const byte*)(const void*)&value;
    int i;
    for (i = 0; i < sizeof(value); i++)
        EEPROM.write(ee++, *p++);
    return i;
}


template <class T> int EEPROM_readAnything(int ee, T& value)
{
    byte* p = (byte*)(void*)&value;
    int i;
    for (i = 0; i < sizeof(value); i++)
        *p++ = EEPROM.read(ee++);
    return i;
}


void BetterRandomSeed( void )
{
  unsigned long __seed;

  EEPROM_readAnything( 0, __seed );

  srandom( __seed );
}


long BetterRandom( void )
{
  long __seed;

  __seed = random();

  EEPROM_writeAnything( 0, __seed );

  return( __seed );
}


long BetterRandom( long howbig )
{
  if ( howbig == 0 )
  {
    return 0;
  }
  return( BetterRandom() % howbig );
}


long BetterRandom( long howsmall, long howbig )
{
  if ( howsmall >= howbig )
  {
    return howsmall;
  }
  long diff = howbig - howsmall;

  return( BetterRandom(diff) + howsmall );
}


char *actors[]={
"Brad Pitt",
"Edward Nortan",
"Ashton Kutcher",
"Demi Moore",
"Reese Witherspoon",
"Will Smith",
"Johnny Depp",
"Tom Hanks",
"George Clooney",
"Will Ferrell",
"Nicolas Cage",
"Leonardo DiCaprio",
"Russell Crowe",
"Tom Cruise",
"Jim Carrey",
"Chris Pine",
"Nicole Kidman",
"Jude Law",
"Julia Roberts",
"Kiefer Sutherland",
"Will Arnett",
"Michael C. Hall",
"Danny Devito",
"Pierce Brosnan",
"Daniel Craig",
"Sean Bean",
"Russell Crowe",
"Christian Bale",
"Bruce Willis",
"John Cusack",
"Samuel L. Jackson",
"Zooey Deschanel",
"Joseph Gordon-Levitt",
"Josh Hartnett",
"Steve Carell",
"Mike Myers",
"Dennis Quaid",
"Billy Bob Thornton",
"Brendan Fraser",
"Jason Statham",
"Eddie Murphy",
"Adam Sandler",
"Leonardo Dicaprio",
"Shia Labeouf",
"Matt Damon",
"Ben Affleck",
"Chris Cooper",
"Ryan Phillipe",
"Kristen Bell",
"Kristen Stewart",
"Timothy Olyphant",
"George Clooney",
"Jake Gyllenhaal",
"Clive Owen",
"Jody Foster",
"Matthew Mcconaughey",
"Jamie Foxx",
"Heath Ledger",
"Tina Fey",
"Keanu Reeves",
"Jack Nicholson",
"Mark Wahlberg",
"Justin Long",
"Vince Vaughn",
"Michael Douglas",
"Brittany Murphy",
"Viggo Mortensen",
"Val Kilmer",
"Steve Buscemi",
"William H. Macy",
"channing Tatum",
"Jackie Chan",
"Jet Lee",
"Mila Kunis",
"Jason Segel",
"Russell Brand",
"Jonah Hill",
"Casey Affleck",
"Morgan Freeman",
"Clint Eastwood",
"Simon Pegg",
"Andy Sandberg",
"isla Fisher",
"Harrison Ford",
"Jeff Goldblum",
"Eli Roth",
"Colin Farrell",
"Ralph Fiennes",
"Tommy Lee Jones",
"Ewan McGregor",
"Scarlett Johansson",
"Robert Downey jr",
"Terrence Howard",
"Jeff Bridges",
"Don Cheadle",
"Hayden Christensen",
"Michael Cera",
"Ellen Page",
"Michael J. Fox",
"Christopher Lloyd",
"Amy Smart",
"Anna Faris",
"Keira Knightley",
"Jennifer Garner",
"Orlando Bloom",
"Naomi Watts",
"Jack Black",
"Mel Gibson",
};
long actor1;
long actor2;

int val = 0;

void setup()
{
  Serial.begin( 9600 );
  BetterRandomSeed();
  Serial.println( "Six Degrees of Seperation" );
}

void loop()
{
   val = digitalRead(BUTTON);
  if (val == HIGH)
  {
  actor1 = BetterRandom(sizeof(actors)/sizeof(char*));
  do
  {
    actor2 = BetterRandom(sizeof(actors)/sizeof(char*));
  }
  while ( actor2 == actor1 );

  Serial.println();
  Serial.println(actors[actor1]);
  Serial.println();
  Serial.println(actors[actor2]);
  Serial.println("______________________");
  delay(1000);
  Serial.println();
  Serial.println("Who Won?");
  Serial.println();
  delay(500);
  Serial.println("Red");
  Serial.println(red_old);
  Serial.println("Blue");
  Serial.println(blue_old);
  Serial.println("_______________");
  delay( 500 );
  }
  red_button = digitalRead(rbutton);
  if (red_button == HIGH)
  {
    Serial.println("Red");
    red_new = (red_old + 1);
    Serial.println(red_new);
    red_old = (red_new);
    Serial.println("Blue");
    Serial.println(blue_old);
    delay(500);
  }
  blue_button = digitalRead(bbutton);
  if (blue_button == HIGH)
  {
    Serial.println("Red");
    Serial.println(red_old);
    Serial.println("Blue");
    blue_new = (blue_old + 1);
    Serial.println(blue_new);
    blue_old = (blue_new);
    delay(500);
  }
}

So if i add any more names after Mel Gibson that's when things start getting weird. Perhaps there is a limit on how many names i can use or perhaps some other crazy weird thing.

Any help would like always be super appreciated.

There's a TrueRandom library that doesn't require using EEPROM.
http://code.google.com/p/tinkerit/wiki/TrueRandom

There's some good C++ tutorials here:

Perhaps you're running short of RAM for your string arrays.
Have a look at using PROGMEM

@Big Oil:
There is evidence that TrueRandom isn't very random...
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1283474716/4#4

@galapagos88:
A follow-up to Grove's post... Mikal Hart has a library that simplifies accessing data stored in Flash (PROGMEM)...
http://arduiniana.org/libraries/flash/

so even though it says that i have 25,000 bytes free i could still be full on my string?