« Week 2 assignment: Many Smileys | Main | Week 3: Fun with Object Oriented Programming »

Simple Simon v2

I went ahead and made Simple Simon v2. It now has fully debounced input, it echoes user input, and blinks while waiting.

Still haven't gotten around to the harder/easier routine, and the fancy win.

Read more for the complete source code...

// Simple Simon game for Physical Computing
// Version 2.0
//
// Gian Pablo Villamil (gian.pablo@gmail.com)
// September 18, 2006
//
// Changes from V1.0
//
// No use of constants in for loop (done)
// Debugged GetAnswer (debounce) (done)
// Blink while idle (done)
// Echo input (done)
// Fancy win routine
//
// Arduino blinks LEDs in a randomly chosen sequence. Player must press
// matching switches in same sequence.
//
// If correct, green LED lights and game is made harder (shorter delay, longer sequence)
// If wrong, red LED lights and game is made easier (longer delay)
//
// Required parts
// Game sequence - red, green, blue, yellow LEDs
// Scoring - red, green LED
// Input - four momentary switches

// Define the pin assignments for the output LEDs

#define GameLEDStartPin 2
#define GameLEDEndPin 5
#define LoseLEDPin 6
#define WinLEDPin 7

#define DebounceTime 10 // debounce time in milliseconds
#define BlinkTime 250 // blink time during input

// Define the pin assignments for the answer switches

#define AnsSwitchStartPin 8
#define AnsSwitchEndPin 11

// Define the arrays to hold the "challenge" sequence and
// the user response.
//
// In the GameArray and AnswerArray, the values are:
// 0 = yellow
// 1 = blue
// 2 = green
// 3 = red

int maxGameLength = 10;
int GameValues = GameLEDEndPin - GameLEDStartPin ;
int GameArray[10];
int AnswerArray[10];

// Define starting game state

int curGameLength = 4; // four blinks
int curGameDelay = 1000; // 1 second

// Define turn score and total score

int turnScore = 0 ;
int totalScore = 0 ;
int rightAnswer ;

// counter for debouncing routine

long SwitchDownTime ;

void setup () {

pinMode(LoseLEDPin, OUTPUT);
pinMode(WinLEDPin, OUTPUT);

for (int i = GameLEDStartPin; i <= GameLEDEndPin; i++) {
pinMode(i, OUTPUT);
}

for (int i = AnsSwitchStartPin; i <= AnsSwitchEndPin; i++) {
pinMode(i, INPUT);
}

}

// Main loop - should be easy to follow

void loop () {
randomizeGame () ;
showGame () ;
getAnswer () ;
checkAnswer () ;
if (rightAnswer) {
Success();
MakeHarder();
}
else
{
Failure();
MakeEasier();
}

}

// Fill the game array with random values between 0 and 3

void randomizeGame () {
for (int i = 1; i <= curGameLength; i++) {
GameArray[i] = random(0,GameValues+1); // what's up with this? 0 to 3 returns max of 2
}
}

// Blink the LEDs according to the values in the game array

void showGame () {
for (int i = 1; i <= curGameLength; i++) {
digitalWrite(GameArray[i]+GameLEDStartPin, HIGH);
delay(curGameDelay); // long pause to show game
digitalWrite(GameArray[i]+GameLEDStartPin, LOW);
delay(curGameDelay/2); // short pause to ensure separation is clear
}

}

// Get the user's answer and store it in the answer array
// Must check debounce routine

void getAnswer () {
int finishedAnswer = false ;
for (int i = 1; i <= curGameLength; i++) {
finishedAnswer = false;
while (!finishedAnswer ) {
for (int j = 0; j <= GameValues; j++) { // poll the switches
InputBlink();
if (digitalRead(AnsSwitchStartPin+j)) {
SwitchDownTime = millis() ;
digitalWrite(GameLEDStartPin+j, HIGH);
while (digitalRead(AnsSwitchStartPin+j)) {InputBlink();} // wait for switch to be released
digitalWrite(GameLEDStartPin+j, LOW);
AnswerArray[i] = j;
if (millis() - SwitchDownTime > DebounceTime) { // time out will go here
finishedAnswer = true;
} // end if
} // end if
} // for
} // end while
} // end for
} // end GetAnswer

// Compare each element of the game and answer arrays
// If they match, increase the turn score
// If the turnscore equals length of the game, then it's right

void checkAnswer () {
turnScore = 0;
rightAnswer = false;
for (int i = 1; i<= curGameLength; i++) {
if (GameArray[i] == AnswerArray[i]) {
turnScore = turnScore + 1;
}
}
if (turnScore == curGameLength) {rightAnswer = true;}
}

// Reward the user - flash the green LED

void Success () {
digitalWrite(LoseLEDPin, LOW);
digitalWrite(WinLEDPin, HIGH);
delay(1000);
digitalWrite(WinLEDPin, LOW);
totalScore = totalScore + 1;
}

// Punish the user - flash the red LED

void Failure () {
digitalWrite(WinLEDPin, LOW);
digitalWrite(LoseLEDPin, HIGH);
delay(1000);
digitalWrite(LoseLEDPin, LOW);
}

// Make the game harder - reduce delay and/or increase length

void MakeHarder () {
}

// Make the game easier - increase delay and/or decrease length
// Maybe make it smart by looking at turnscore/gamelength

void MakeEasier () {
}

//
//
void InputBlink() {
if (millis() % BlinkTime > (BlinkTime / 2)) {
digitalWrite(WinLEDPin, LOW);
digitalWrite(LoseLEDPin, HIGH);
}
else {
digitalWrite(LoseLEDPin, LOW);
digitalWrite(WinLEDPin, HIGH);
}

}

TrackBack

TrackBack URL for this entry:
http://itp.nyu.edu/~gpv206/cgi-bin/mt/mt-tb.cgi/11

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)