HELP!! Game w/ Shift Register

I posted about this a while ago pertaining to a different question related to this project. To my dismay, my question was never answered. But luckily, about two weeks later, I found out the issue. But I’ve now been confronted with a different, more difficult problem.

Here’s the basics of how it works:

I am trying to duplicate a project I did with my BS2e (BASIC Stamp II model E), except this time, I am making it more complex, I’m using more LED’s, a screen, a CdS light sensor, and a 74HC595 shift register. I have never used shift registers before. I needed to use one this time because of all the LED’s I was using, and all the extra knobs and whistles. This game has two options: 1) “Light-Stopper”; this game is like those games you find at an arcade where there is a huge plastic dome with lights in a circle, and you have to get the lights to stop on the one bulb closest to you (I think it’s called jackpot). 2) “Simon”; just like the memory-testing game, Simon. I am currently developing the “Light-Stopper” part, But I am having some problems. First off, here’s how this game works:

There are 7 LED’s, arranged in a horizontal line. In the middle is a RGB LED (so I guess you could say the total amount of LEDs is 9). One LED lights up at a time from left to right, and right to left (only one LED is on at any given time. To make i clearer, the pattern just looks like the light is getting ‘bounced’ back and forth, from right to left, and vice-versa). The shift register only controls the 3 LEDs on the left, and the 3 on the right. The middle RGB is controlled directly via 3 of the ATmega168’s digital pins (via PWM on pins 9, 10, & 11). Don’t worry about the four LEDs for the simon game now. There is a IR detector for input. When the user presses any button on a remote (just any IR remote from a TV, VCR, etc), it ‘stops’ the movement of the pattern (one LED is now lit, and stays lit). If they happen to get the timing right, and they stop the pattern when the middle RGB LED is lit, then they win. Pretty simple, but the programming is actually much more complicated with the shift register involved.

Lucky for me, there was sample code on the Arduino website on the 595 shift register. I implemented it into this project.

The problem is, it is acting erratically, and it doesn’t quite work. When it runs through the ‘light stopper’ sequence, after a while, the sequence stops, and some random LEDs light up. Also, when you stop the sequence on the middle LED, it keeps the LED next to the middle HIGH, and it does not go to the “Winner” subroutine. What’s wrong? Should I post a video of this problem? PLEASSEE help!! :’(

Here’s the first half of the code:

int btnPin = 2;    // Digital 2 ; 'Toggle' Button
int irPin = 3;     // Digital 3 ; IR Detector
int bryPin = 5;   // Digital 5 ; Bottom Right Yellow LED
int trgPin = 6;   // Digital 6 ; Top Right Green LED
int blgPin = 7;   // Digital 7 ; Bottom Left Green LED
int tlyPin = 8;   // Digital 8 ; Top Left Yellow LED
int clockPin = 13; // Digital 9 ; SH_CP on Shift Register      
int latchPin = 4; // Digital 10 ; ST_CP on Shift Register  
int dataPin = 12;    // Digital 11 ; DATA on Shift register  
int blPin = 10;    // Digital (PWM) 9 ; Red RGB LED
int cdsPin = 2;   // Analog 2 ; CdS Cell
int rdPin = 9;    // Digital (PWM) 10 ; Blue RGB LED
int gnPin = 11;    // Digital (PWM) 11 ; Green RGB LED

int irval = 1;
int btnval = 1;
int cdsval = 0;
int pos = 0;
int i = 0;;
int b;
int mdl = false;
int prev = 0;
int time = 0;

void setup()
{
  Serial.begin(9600);
  time = 25;                  // How fast the pattern will go
  pinMode(latchPin, OUTPUT);
  pinMode(btnPin, INPUT);
  //pinMode(irPin, INPUT);
  pinMode(bryPin, OUTPUT);
  pinMode(trgPin, OUTPUT);
  pinMode(tlyPin, OUTPUT);
  pinMode(blPin, OUTPUT);
  pinMode(rdPin, OUTPUT);
  pinMode(gnPin, OUTPUT);
  clearLCD();
  Serial.print(0xFE, BYTE);
  Serial.print(0x0C, BYTE);
  determineBacklight();
  delay(100);
  selectLineOne();
  delay(100);
  Serial.print("Main Menu");
  delay(500);
  for(i = 0; i < 10; i++) {     // Fancy stuff
    scrollLeft();
    delay(100);
  }
  delay(1000);
}

void loop()
{  
  clearLCD();
  pos = 130;
  selectLineCustom();
  Serial.print("Select Menu");
  pos = 197;
  selectLineCustom();
  Serial.print("Option");
  delay(700);
  for(i = 0; i < 15; i++) {    // More fancy stuff
    scrollLeft();
    delay(100);
  }
  clearLCD();
  mainMenu();
}

void selectLineOne(){  //puts the cursor at line 0 char 0.
   Serial.print(0xFE, BYTE);   //command flag
   Serial.print(128, BYTE);    //position
}
void selectLineTwo(){  //puts the cursor at line 0 char 0.
   Serial.print(0xFE, BYTE);   //command flag
   Serial.print(192, BYTE);    //position
}
void selectLineCustom() {
   Serial.print(0xFE, BYTE);
   Serial.print(pos, BYTE);
   pos = 0;
}
void scrollRight() {
  Serial.print(0xFE, BYTE);
  Serial.print(0x1C, BYTE);
}
void scrollLeft() {
  Serial.print(0xFE, BYTE);
  Serial.print(0x18, BYTE);
}
void clearLCD(){
   Serial.print(0xFE, BYTE);   //command flag
   Serial.print(0x01, BYTE);   //clear command.
}
void determineBacklight() {
  cdsval = analogRead(cdsPin);
  if(cdsval < 500) {
    backlightOn();
  }
  else if(cdsval > 500) {
    backlightOff();
  }
}

void backlightOn(){  //turns on the backlight
    Serial.print(0x7C, BYTE);   //command flag for backlight stuff
    Serial.print(157, BYTE);    //light level.
}
void backlightOff(){  //turns off the backlight
    Serial.print(0x7C, BYTE);   //command flag for backlight stuff
    Serial.print(128, BYTE);     //light level for off.
}
void serCommand(){   //a general function to call the command flag for issuing all other commands   
  Serial.print(0xFE, BYTE);
}
void End() {                // I use this for debugging
  delay(500);
  End();
}
void mainMenu() {
  Serial.print("Press toggle to switch options");
  delay(2000);
  clearLCD();
  Serial.print("Press select to select an option");
  delay(2000);
  clearLCD();
  Serial.print("Light-Stopper");
  option1();
}
void option1() {                // This keeps the LCD at the menu option "Light Stopper
    pinMode(irPin, INPUT);      // until a button on the remote or 'toggle' is pressed
    delay(100);
    irval = digitalRead(irPin);
    btnval = digitalRead(btnPin);
    if(irval == 0 && btnval == 0) {
      clearLCD();
      Serial.print("??");
    }
    else if(irval == 0 && btnval == 1) {
      clearLCD();
      Serial.print("Light-Stopper");
      lightStopper();
    }
    else if(irval == 1 && btnval == 0) {
      clearLCD();
      Serial.print("Simon");
      option2();
    }
    else if(irval == 1 && btnval == 1) { 
      option1();
    }
}
void option2() {                            // ...And this one keeps it at "Simon" 
    pinMode(irPin, INPUT);                  // menu option until a button is presses
    delay(100);
    irval = digitalRead(irPin);
    btnval = digitalRead(btnPin);
    if(irval == 0 && btnval == 0) {
      Serial.print("??");
    }
    else if(irval == 0 && btnval == 1) {
      clearLCD();
      Serial.print("Simon");
      Simon();
    }
    else if(irval == 1 && btnval == 0) {
      clearLCD();
      Serial.print("Light-Stopper");
      option1();
    }
    else if(irval == 1 && btnval == 1) {
      option2();
    }
}
void Simon() {                              // (still haven't gotten to this yet...
  Serial.print("Under Construction!");
  delay(1000);
  Simon();
}

…And the other half:

int btnPin = 2;    // Digital 2 ; 'Toggle' Button
int irPin = 3;     // Digital 3 ; IR Detector
int bryPin = 5;   // Digital 5 ; Bottom Right Yellow LED
int trgPin = 6;   // Digital 6 ; Top Right Green LED
int blgPin = 7;   // Digital 7 ; Bottom Left Green LED
int tlyPin = 8;   // Digital 8 ; Top Left Yellow LED
int clockPin = 13; // Digital 9 ; SH_CP on Shift Register      
int latchPin = 4; // Digital 10 ; ST_CP on Shift Register  
int dataPin = 12;    // Digital 11 ; DATA on Shift register  
int blPin = 10;    // Digital (PWM) 9 ; Red RGB LED
int cdsPin = 2;   // Analog 2 ; CdS Cell
int rdPin = 9;    // Digital (PWM) 10 ; Blue RGB LED
int gnPin = 11;    // Digital (PWM) 11 ; Green RGB LED

int irval = 1;
int btnval = 1;
int cdsval = 0;
int pos = 0;
int i = 0;;
int b;
int mdl = false;
int prev = 0;
int time = 0;

void setup()
{
  Serial.begin(9600);
  time = 25;                  // How fast the pattern will go
  pinMode(latchPin, OUTPUT);
  pinMode(btnPin, INPUT);
  //pinMode(irPin, INPUT);
  pinMode(bryPin, OUTPUT);
  pinMode(trgPin, OUTPUT);
  pinMode(tlyPin, OUTPUT);
  pinMode(blPin, OUTPUT);
  pinMode(rdPin, OUTPUT);
  pinMode(gnPin, OUTPUT);
  clearLCD();
  Serial.print(0xFE, BYTE);
  Serial.print(0x0C, BYTE);
  determineBacklight();
  delay(100);
  selectLineOne();
  delay(100);
  Serial.print("Main Menu");
  delay(500);
  for(i = 0; i < 10; i++) {     // Fancy stuff
    scrollLeft();
    delay(100);
  }
  delay(1000);
}

void loop()
{  
  clearLCD();
  pos = 130;
  selectLineCustom();
  Serial.print("Select Menu");
  pos = 197;
  selectLineCustom();
  Serial.print("Option");
  delay(700);
  for(i = 0; i < 15; i++) {    // More fancy stuff
    scrollLeft();
    delay(100);
  }
  clearLCD();
  mainMenu();
}

void selectLineOne(){  //puts the cursor at line 0 char 0.
   Serial.print(0xFE, BYTE);   //command flag
   Serial.print(128, BYTE);    //position
}
void selectLineTwo(){  //puts the cursor at line 0 char 0.
   Serial.print(0xFE, BYTE);   //command flag
   Serial.print(192, BYTE);    //position
}
void selectLineCustom() {
   Serial.print(0xFE, BYTE);
   Serial.print(pos, BYTE);
   pos = 0;
}
void scrollRight() {
  Serial.print(0xFE, BYTE);
  Serial.print(0x1C, BYTE);
}
void scrollLeft() {
  Serial.print(0xFE, BYTE);
  Serial.print(0x18, BYTE);
}
void clearLCD(){
   Serial.print(0xFE, BYTE);   //command flag
   Serial.print(0x01, BYTE);   //clear command.
}
void determineBacklight() {
  cdsval = analogRead(cdsPin);
  if(cdsval < 500) {
    backlightOn();
  }
  else if(cdsval > 500) {
    backlightOff();
  }
}

void backlightOn(){  //turns on the backlight
    Serial.print(0x7C, BYTE);   //command flag for backlight stuff
    Serial.print(157, BYTE);    //light level.
}
void backlightOff(){  //turns off the backlight
    Serial.print(0x7C, BYTE);   //command flag for backlight stuff
    Serial.print(128, BYTE);     //light level for off.
}
void serCommand(){   //a general function to call the command flag for issuing all other commands   
  Serial.print(0xFE, BYTE);
}
void End() {                // I use this for debugging
  delay(500);
  End();
}
void mainMenu() {
  Serial.print("Press toggle to switch options");
  delay(2000);
  clearLCD();
  Serial.print("Press select to select an option");
  delay(2000);
  clearLCD();
  Serial.print("Light-Stopper");
  option1();
}
void option1() {                // This keeps the LCD at the menu option "Light Stopper
    pinMode(irPin, INPUT);      // until a button on the remote or 'toggle' is pressed
    delay(100);
    irval = digitalRead(irPin);
    btnval = digitalRead(btnPin);
    if(irval == 0 && btnval == 0) {
      clearLCD();
      Serial.print("??");
    }
    else if(irval == 0 && btnval == 1) {
      clearLCD();
      Serial.print("Light-Stopper");
      lightStopper();
    }
    else if(irval == 1 && btnval == 0) {
      clearLCD();
      Serial.print("Simon");
      option2();
    }
    else if(irval == 1 && btnval == 1) { 
      option1();
    }
}
void option2() {                            // ...And this one keeps it at "Simon" 
    pinMode(irPin, INPUT);                  // menu option until a button is presses
    delay(100);
    irval = digitalRead(irPin);
    btnval = digitalRead(btnPin);
    if(irval == 0 && btnval == 0) {
      Serial.print("??");
    }
    else if(irval == 0 && btnval == 1) {
      clearLCD();
      Serial.print("Simon");
      Simon();
    }
    else if(irval == 1 && btnval == 0) {
      clearLCD();
      Serial.print("Light-Stopper");
      option1();
    }
    else if(irval == 1 && btnval == 1) {
      option2();
    }
}
void Simon() {                              // (still haven't gotten to this yet...
  Serial.print("Under Construction!");
  delay(1000);
  Simon();
}

You might want to run some code that works “just” the shift registers first, to be sure nothing else in your program is “upsetting” the flow. Use any of the examples at the site, then let them run a sequence for half an hour to see if there’s anything irregular going on that isn’t covered by the tutorials.

Also, post a pic of your breadboard - I’ve seen 595’s misbehave due to wiring and code.

Otherwise, unless the chips are “factory sweeps” they are completely reliable to do as they’re told :slight_smile:

Ok. I solved that problem. It had to do with some haphazard if…else statements. But thanks for the tip; that’s exactly what I did (and always do) to solve the error. Singling out the variables is the way to go.

Here’s a pic with it turned on:
E:\DCIM\100CANON\IMG_1462

…And turned off:
E:\DCIM\100CANON\IMG_1464

The funny thing is, in that first pic with it turned on, all those LED’s actually aren’t on; only one was when I photographed it. They are moving too fast for the camera to pick up! I also noticed that with a 9V battery hooked up to the whole thing, it was drawing a max of 150ma, which isn’t wayyy too much, but despite that, the text on the screen was too dull, and if you turned on the backlight, forget it; you won’t be able to see the text at all. The thing is, I’m using 9V batteries that are at about 7.8V, but even then, shouldn’t the regulator on board be able to supply enough power? It’s a standard 7805 (not LDO). I mean, 150ma won’t drain the battery fast, will it?

Here’s another problem I’m facing: The game is too easy! For the ‘select’ button (the button that selects menu options and ‘stops’ the game sequence), I am using a remote (just any TV, VCR, etc. remote), and there is a 38Khz IR detector on the breadboard. When the game detects a LOW signal from the IR detector (it goes LOW when it sees IR light), it stops the LED sequence. I haven’t noticed any delay from the pulsing of IR light @ the remote, to the actual detection of the light from the ATmega168, so I don’t think that’s what’s making it really easy. Could it be that it takes a few ms for the game to detect the IR light, and given human reaction time, it gives the player an advantage (EX: if you hit the button too far ahead of time, that mistake will be accommodated for in the delay)? Or could it be that AND/OR the fact that there is no ‘cheating’ prevention. Let me explain: When you push the button on the remote, the remote doesn’t just send a REALLY quick 1-3ms bust, it actually sends one longer than that. Well, if the game detects the pulse at the LED right next to the middle (jackpot) LED, and pauses on that LED, then continues, and the remote is still sending the IR pulses after the game continues, then it thinks you have hit the button right on time when the middle LED is lit. (Do you see what I mean?). Or could it be that and/or a combination of something else? Thanks for the help!! ;D

EDIT: I guess I can’t add a pic unless it’s posted on the net :’(. I can email it to you if you want; just give me your email.

Ok. I solved that problem. It had to do with some haphazard if…else statements. But thanks for the tip; that’s exactly what I did (and always do) to solve the error. Singling out the variables is the way to go.

Here’s a pic with it turned on:
E:\DCIM\100CANON\IMG_1462

…And turned off:
E:\DCIM\100CANON\IMG_1464

The funny thing is, in that first pic with it turned on, all those LED’s actually aren’t on; only one was when I photographed it. They are moving too fast for the camera to pick up! I also noticed that with a 9V battery hooked up to the whole thing, it was drawing a max of 150ma, which isn’t wayyy too much, but despite that, the text on the screen was too dull, and if you turned on the backlight, forget it; you won’t be able to see the text at all. The thing is, I’m using 9V batteries that are at about 7.8V, but even then, shouldn’t the regulator on board be able to supply enough power? It’s a standard 7805 (not LDO). I mean, 150ma won’t drain the battery fast, will it?

Here’s another problem I’m facing: The game is too easy! For the ‘select’ button (the button that selects menu options and ‘stops’ the game sequence), I am using a remote (just any TV, VCR, etc. remote), and there is a 38Khz IR detector on the breadboard. When the game detects a LOW signal from the IR detector (it goes LOW when it sees IR light), it stops the LED sequence. I haven’t noticed any delay from the pulsing of IR light @ the remote, to the actual detection of the light from the ATmega168, so I don’t think that’s what’s making it really easy. Could it be that it takes a few ms for the game to detect the IR light, and given human reaction time, it gives the player an advantage (EX: if you hit the button too far ahead of time, that mistake will be accommodated for in the delay)? Or could it be that AND/OR the fact that there is no ‘cheating’ prevention. Let me explain: When you push the button on the remote, the remote doesn’t just send a REALLY quick 1-3ms bust, it actually sends one longer than that. Well, if the game detects the pulse at the LED right next to the middle (jackpot) LED, and pauses on that LED, then continues, and the remote is still sending the IR pulses after the game continues, then it thinks you have hit the button right on time when the middle LED is lit. (Do you see what I mean?). Or could it be that and/or a combination of something else? Thanks for the help!! ;D

EDIT: I guess I can’t add a pic unless it’s posted on the net :’(. I can email it to you if you want; just give me your email.

Hey that’s great. If you can find a way to upload the pix to one of the photo hosting sites, then it sounds like a good example for other members to refer to.

You can piggy-back 595’s and they’ll only draw as much current as a single IC because there’s only a maximum of 8 LEDs on at any one time.

150mA isn’t much at all, but how long a battery lasts varies depending on type and brand.

To measure the IR response, you might want to separate the code and test it individually using the serial monitor for feed-back to determine if there’s any latency.

When a pulse is received, you need to perform the evaluation at the precise moment it arrives. While that evaluation is done, the LEDs continue, but the evaluation doesn’t. So your taking a snap shot of the LEDs as they were the moment the pulse is received, then evaluating, then reporting, then resuming detection.

If you look up “debounce” I suspect it might be the solution your looking for :slight_smile:

Ok. I’ll try to get the photos up on Flikr soon; after all, that breadboard is chock full of stuff; I don’t think there’s a single row that’s empty!!

If you look up “debounce” I suspect it might be the solution your looking for

That’s a good idea. How might I go about doing that? Shall I just use a boolean variable to say “if an IR light has been detected in this run-around on a previous LED, then ignore all following IR light until loop repeats”?

Oops. I just realized I didn’t copy the second half of the code before. I’ll get that up here, too.

That’s a good idea. How might I go about doing that? Shall I just use a boolean variable to say “if an IR light has been detected in this run-around on a previous LED, then ignore all following IR light until loop repeats”?

If the IR streams then it won’t matter how long the bebounce is, the user could sit there holding the button down and eventually score a hit. So if that’s the case, you’ll need to use a method to detect when the user has taken their finger “off” the button, before allowing detection to resume.

A boolean can do the job. The moment it goes high, do an evaluation, the moment it goes low, look for it to go high again.

Whew! Ok, that ‘streaming’ of the IR light from the remote contributed a little to it, so I fixed that wish a switch…case statement. I also shortened the time in which it lights the center LED and checks the IR detector. Now it’s harder, and cooler, I have to admit! I’m going to try to post dome pics/videos (maybe some on YouTube) soon. But It’s still a work-in-progress.

Here’s the new code:

int btnPin = 2;    // Digital 2 ; 'Toggle' Button
int irPin = 3;     // Digital 3 ; IR Detector
int bryPin = 5;   // Digital 5 ; Bottom Right Yellow LED
int trgPin = 6;   // Digital 6 ; Top Right Green LED
int blgPin = 7;   // Digital 7 ; Bottom Left Green LED
int tlyPin = 8;   // Digital 8 ; Top Left Yellow LED
int clockPin = 13; // Digital 9 ; SH_CP on Shift Register      
int latchPin = 4; // Digital 10 ; ST_CP on Shift Register  
int dataPin = 12;    // Digital 11 ; DATA on Shift register  
int blPin = 10;    // Digital (PWM) 9 ; Red RGB LED
int cdsPin = 2;   // Analog 2 ; CdS Cell
int rdPin = 9;    // Digital (PWM) 10 ; Blue RGB LED
int gnPin = 11;    // Digital (PWM) 11 ; Green RGB LED

int irval = 1;
int btnval = 1;
int cdsval = 0;
int pos = 0;
int i = 0;;
int i2 = 0;
int i3 = 0;
int b = 0;
boolean mdl = false;
int hit = 0;
int time = 0;
int mdltime = 0;
long randomNumber;

void setup()
{
  Serial.begin(9600);
  time = 25;
  mdltime = 5;
  randomSeed(analogRead(0));
  pinMode(latchPin, OUTPUT);
  pinMode(btnPin, INPUT);
  pinMode(irPin, INPUT);
  pinMode(bryPin, OUTPUT);
  pinMode(trgPin, OUTPUT);
  pinMode(tlyPin, OUTPUT);
  pinMode(blPin, OUTPUT);
  pinMode(rdPin, OUTPUT);
  pinMode(gnPin, OUTPUT);
  clearLCD();
  Serial.print(0xFE, BYTE);
  Serial.print(0x0C, BYTE);
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, 0);
  digitalWrite(latchPin, 1);
  determineBacklight();
  delay(100);
  selectLineOne();
  delay(100);
  Serial.print("Main Menu");
  delay(500);
  for(i = 0; i < 10; i++) {
    scrollLeft();
    delay(100);
  }
  delay(1000);
}

void loop()
{  
  clearLCD();
  pos = 130;
  selectLineCustom();
  Serial.print("Select Menu");
  pos = 197;
  selectLineCustom();
  Serial.print("Option");
  delay(700);
  for(i = 0; i < 15; i++) {
    scrollLeft();
    delay(100);
  }
  clearLCD();
  mainMenu();
}

void selectLineOne(){  //puts the cursor at line 0 char 0.
   Serial.print(0xFE, BYTE);   //command flag
   Serial.print(128, BYTE);    //position
}
void selectLineTwo(){  //puts the cursor at line 0 char 0.
   Serial.print(0xFE, BYTE);   //command flag
   Serial.print(192, BYTE);    //position
}
void selectLineCustom() {
   Serial.print(0xFE, BYTE);
   Serial.print(pos, BYTE);
   pos = 0;
}
void scrollRight() {
  Serial.print(0xFE, BYTE);
  Serial.print(0x1C, BYTE);
}
void scrollLeft() {
  Serial.print(0xFE, BYTE);
  Serial.print(0x18, BYTE);
}
void clearLCD(){
   Serial.print(0xFE, BYTE);   //command flag
   Serial.print(0x01, BYTE);   //clear command.
}
void determineBacklight() {
  cdsval = analogRead(cdsPin);
  if(cdsval < 500) {
    backlightOn();
  }
  else if(cdsval > 500) {
    backlightOff();
  }
}

void backlightOn(){  //turns on the backlight
    Serial.print(0x7C, BYTE);   //command flag for backlight stuff
    Serial.print(157, BYTE);    //light level.
}
void backlightOff(){  //turns off the backlight
    Serial.print(0x7C, BYTE);   //command flag for backlight stuff
    Serial.print(128, BYTE);     //light level for off.
}
void serCommand(){   //a general function to call the command flag for issuing all other commands   
  Serial.print(0xFE, BYTE);
}
void End() {
  delay(500);
  End();
}
void mainMenu() {
  Serial.print("Press toggle to switch options");
  delay(2000);
  clearLCD();
  Serial.print("Press select to select an option");
  delay(2000);
  clearLCD();
  Serial.print("Light-Stopper");
  option1();
}
void option1() {
    irval = digitalRead(irPin);
    btnval = digitalRead(btnPin);
    if(irval == 0 && btnval == 0) {
      clearLCD();
      Serial.print("??");
    }
    else if(irval == 0 && btnval == 1) {
      clearLCD();
      Serial.print("Light-Stopper");
      delay(1000);
      lightStopper();
    }
    else if(irval == 1 && btnval == 0) {
      clearLCD();
      Serial.print("Simon");
      option2();
    }
    else if(irval == 1 && btnval == 1) { 
      option1();
    }
}
void option2() {
    irval = digitalRead(irPin);
    btnval = digitalRead(btnPin);
    if(irval == 0 && btnval == 0) {
      Serial.print("??");
    }
    else if(irval == 0 && btnval == 1) {
      clearLCD();
      Serial.print("Simon");
      Simon();
    }
    else if(irval == 1 && btnval == 0) {
      clearLCD();
      Serial.print("Light-Stopper");
      option1();
    }
    else if(irval == 1 && btnval == 1) {
      option2();
    }
}
void Simon() {
  Serial.print("Under Construction!");
  delay(1000);
  Simon();
}

…And some more:

void lightStopper() {
  clearLCD();
  // light each pin one by one using a function A
  for (int j = 6; j > 0; j--) {
    b = j;
    lightShiftPinA(j);
    delay(time);
    check2();
    if(j == 4) {
      digitalWrite(latchPin, 0);
      shiftOut(dataPin, clockPin, 0);
      digitalWrite(latchPin, 1);
      analogWrite(blPin, 255);
      mdl = true;
      for(i = 0; i < mdltime; i++) {     // TIME ! ! ! !
        check2();
        delay(1);
      }
      analogWrite(blPin, 0);
      mdl = false;
    }
  } 

 // light each pin one by one using a function B
  for (int j = 1; j < 7; j++) {
    b = j;
    lightShiftPinB(j);
    delay(time);
    check();
    if(j == 3) {
      digitalWrite(latchPin, 0);
      shiftOut(dataPin, clockPin, 0);
      digitalWrite(latchPin, 1);
      analogWrite(rdPin, 255);
      mdl = true;
      for(i = 0; i < mdltime; i++) {     // TIME ! ! ! !
        check();
        delay(1);
      }
      analogWrite(rdPin, 0);
      mdl = false;
    }
  } 
  lightStopper();
}
void check() {
  irval = digitalRead(irPin);
  if(irval == 0) {
    switch (b) {
    case 1:
        Wrong();
        for(i = 0; i < 5; i++) {
          shiftOut(dataPin, clockPin, 1);
          delay(100);
        }
        clearLCD();
        break;
    case 2:
        Wrong();
        for(i = 0; i < 5; i++) {
          shiftOut(dataPin, clockPin, 2);
          delay(100);
        }
        clearLCD();
        break;
    case 3:
      if(mdl == true) {
        mdl = false;
        Loser();          
        lightStopper();
      }
      Wrong();
      for(i = 0; i < 5; i++) {
        shiftOut(dataPin, clockPin, 3);
        delay(100);
      }
      clearLCD();
      break;
    case 4:
        Wrong();
        for(i = 0; i < 5; i++) {
          shiftOut(dataPin, clockPin, 4);
          delay(100);
        }
        clearLCD();
        break;
    case 5:
        Wrong();
        for(i = 0; i < 5; i++) {
          shiftOut(dataPin, clockPin, 5);
          delay(100);
        }
        clearLCD();
        break;
    case 6:
        Wrong();
        for(i = 0; i < 5; i++) {
          shiftOut(dataPin, clockPin, 6);
          delay(100);
        } 
        clearLCD();
        break;
    }
  }
}
void check2() {
  irval = digitalRead(irPin);
  if(irval == 0) {
    switch (b) {
    case 6:
        Wrong();
        for(i = 0; i < 5; i++) {
          shiftOut(dataPin, clockPin, 1);
          delay(100);
        }
        clearLCD();
        break;
    case 5:
        Wrong();
        for(i = 0; i < 5; i++) {
          shiftOut(dataPin, clockPin, 2);
          delay(100);
        }
        clearLCD();
        break;
    case 4:
      if(mdl == true) {
        mdl = false;
        Winner();           
        lightStopper();
      }
        Wrong();
        for(i = 0; i < 5; i++) {
          shiftOut(dataPin, clockPin, 3);
          delay(100);
        }
        clearLCD();
        break;
    case 3:
        Wrong();
        for(i = 0; i < 5; i++) {
          shiftOut(dataPin, clockPin, 4);
          delay(100);
        }
        clearLCD();
        break;
    case 2:
        Wrong();
        for(i = 0; i < 5; i++) {
          shiftOut(dataPin, clockPin, 5);
          delay(100);
        }
        clearLCD();
        break;
    case 1:
        Wrong();
        for(i = 0; i < 5; i++) {
          shiftOut(dataPin, clockPin, 6);
          delay(100);
        } 
        clearLCD();
        break;
    }
  }
}
void lightShiftPinA(int p) {
  //defines a local variable
  int pin;

  //this is line uses a bitwise operator
  //shifting a bit left using << is the same
  //as multiplying the decimal number by two. 
  pin = 1<< p;

  //ground latchPin and hold low for as long as you are transmitting
  digitalWrite(latchPin, 0);
  //move 'em out
  shiftOut(dataPin, clockPin, pin);   
  //return the latch pin high to signal chip that it 
  //no longer needs to listen for information
  digitalWrite(latchPin, 1);

}

//This function uses that fact that each bit in a byte
//is 2 times greater than the one before it to
//shift the bits higher
void lightShiftPinB(int p) {
  //defines a local variable
  int pin;

  //start with the pin = 1 so that if 0 is passed to this
  //function pin 0 will light. 
  pin = 1;

  for (int x = 0; x < p; x++) {
    pin = pin * 2; 
  }

  //ground latchPin and hold low for as long as you are transmitting
  digitalWrite(latchPin, 0);
  //move 'em out
  shiftOut(dataPin, clockPin, pin);   
  //return the latch pin high to signal chip that it 
  //no longer needs to listen for information
  digitalWrite(latchPin, 1);

}

…And finally the rest:

void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
  // This shifts 8 bits out MSB first, 
  //on the rising edge of the clock,
  //clock idles low

  //internal function setup
  int i=0;
  int pinState;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, OUTPUT);

  //clear everything out just in case to
  //prepare shift register for bit shifting
  digitalWrite(myDataPin, 0);
  digitalWrite(myClockPin, 0);

  //for each bit in the byte myDataOut?
  //NOTICE THAT WE ARE COUNTING DOWN in our for loop
  //This means that %00000001 or "1" will go through such
  //that it will be pin Q0 that lights. 
  for (i=7; i>=0; i--)  {
    digitalWrite(myClockPin, 0);

    //if the value passed to myDataOut and a bitmask result 
    // true then... so if we are at i=6 and our value is
    // %11010100 it would the code compares it to %01000000 
    // and proceeds to set pinState to 1.
    if ( myDataOut & (1<<i) ) {
      pinState= 1;
    }
    else {      
      pinState= 0;
    }

    //Sets the pin to HIGH or LOW depending on pinState
    digitalWrite(myDataPin, pinState);
    //register shifts bits on upstroke of clock pin  
    digitalWrite(myClockPin, 1);
    //zero the data pin after shift to prevent bleed through
    digitalWrite(myDataPin, 0);
  }

  //stop shifting
  digitalWrite(myClockPin, 0);
}
void Winner() {
  i2 = 0;
  analogWrite(rdPin, 0);
  clearLCD();
  for(i3 = 0; i3 < 5; i3++) {
    Serial.print("WINNER!!");
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, 255);
    digitalWrite(latchPin, 1);
    for(i = 255; i > 0; i--) {
      i2 = i2 + 1;
      analogWrite(blPin, i);
      analogWrite(gnPin, i2);
      delay(1);
    }
    clearLCD();
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, 0);
    digitalWrite(latchPin, 1);
    for(i = 0; i < 256; i++) {
      i2 = i2 - 1;
      analogWrite(blPin, i);
      analogWrite(gnPin, i2);
      delay(1);
    } 
  }
  analogWrite(gnPin, 0);
  analogWrite(blPin, 0);
}
void Loser() {
  clearLCD();
  for(i = 0; i < 5; i++) {
    Serial.print("LOSER!!");
    delay(300);
    clearLCD();
    delay(300);
  }
}
void Wrong() {
  randomNumber = random(6);
  switch (randomNumber) {
    case 0:
      Serial.print("Not Quite!");
      break;
    case 1:
      Serial.print("Ouch!");
      break;
    case 2:
      Serial.print("Nope...");
      break;
    case 3:
      Serial.print("Wrong!");
      break;
    case 4:
      Serial.print("Try Again!");
      break;
    case 5:
      Serial.print("Darn!");
      break;
  }
}

Let me also give credit to the original author of the tutorial programs for shiftOut on the Arduino website.