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);
}
}