
Simon: A Memory Game
Dependencies: 4DGL-uLCD-SE PinDetect mbed
main.cpp
- Committer:
- cmathis
- Date:
- 2014-10-21
- Revision:
- 2:c92f0e749b94
- Parent:
- 1:cd222334a4fe
File content as of revision 2:c92f0e749b94:
/*********************************/ // ECE 4180 Lab 4 // Colton Mathis, Taylor Hawley /*********************************/ #include "mbed.h" #include "uLCD_4DGL.h" #include "PinDetect.h" #include "Speaker.h" // pushbutton interrupts with debounce PinDetect pb1(p25, PullUp); PinDetect pb2(p26, PullUp); PinDetect pb3(p23, PullUp); PinDetect pb4(p24, PullUp); // four LED outputs DigitalOut led1(p7); DigitalOut led2(p9); DigitalOut led3(p8); DigitalOut led4(p6); // speaker object Speaker mySpeaker(p21); // LCD object uLCD_4DGL uLCD(p28, p27, p29); // analog input for seeding rand() function AnalogIn adcReading(p18); AnalogIn pot(p19); // variable declarations int levels[16]; int levelsIndex; int level; int buttonPressed; int buttonPushes; int failed; int start = 1; int randomSeed; float volume; // function prototypes void enableInterrupts(); void disableInterrupts(); void startGame(); void setLevels(); void playSequence(); void pushOne(); void pushTwo(); void pushThree(); void pushFour(); void failedGame(); void endGame(); int main() { // read in value from analog input as unsigned short instead of float // and seed the rand() function with the value randomSeed = adcReading.read_u16(); srand(randomSeed); uLCD.baudrate(3000000); while(1) { volume = pot.read(); // only initialize these variables at the start of each game if(start == 1){ failed = 0; level = 0; buttonPressed = 0; buttonPushes = 0; levelsIndex = 0; startGame(); } start = 0; // generate and play the sequence of LEDs (and sounds) that the player copies setLevels(); playSequence(); // enable the four pushbutton interrupts enableInterrupts(); // wait in this loop until the user pushes buttons the same number of times as the current level // or until the user has pushed an incorrect button while(buttonPushes != level && failed == 0){ volume = pot.read(); wait(0.1); } // if the user has failed, disable the pushbutton interrupts, notify the user that they failed, // and then set start=1 so that the game restarts from level 1 if(failed == 1){ disableInterrupts(); failedGame(); start = 1; } // if the user has completed all of the levels without failing, disable the pushbutton interrupts, // notify the user that they won, and set start=1 so that the game restarts from level 1 if(level == 10 && failed == 0){ disableInterrupts(); endGame(); start = 1; } // if the user has not failed or completed all of the levels, disable the interrupts and continue disableInterrupts(); // set buttonpushes=0 to record the button presses for the next level buttonPushes = 0; // wait a short amount of time before starting the next game if(start==1){ wait(2); } } } void enableInterrupts(){ // set the four pushbutton interrupts to trigger on a falling edge pb1.attach_deasserted(&pushOne); pb2.attach_deasserted(&pushTwo); pb3.attach_deasserted(&pushThree); pb4.attach_deasserted(&pushFour); // start the four interrupts (default sample frequency is 20ms) pb1.setSampleFrequency(); pb2.setSampleFrequency(); pb3.setSampleFrequency(); pb4.setSampleFrequency(); } void disableInterrupts(){ // disable four interrupts by setting their service routine to NULL pointer pb1.attach_deasserted(NULL); pb2.attach_deasserted(NULL); pb3.attach_deasserted(NULL); pb4.attach_deasserted(NULL); } // this function is called at the beginning of the game void startGame(){ uLCD.cls(); uLCD.display_control(PORTRAIT); uLCD.color(BLUE); uLCD.text_width(2); uLCD.text_height(2); uLCD.locate(2, 3); uLCD.printf("SIMON"); // start up LED/uLCD sequence led1 = 1; uLCD.filled_rectangle(0, 0, 63, 40, 0x00CC00); wait(0.5); led1 = 0; uLCD.filled_rectangle(0, 0, 63, 40, 0x000000); led2 = 1; uLCD.filled_rectangle(64, 0, 127, 40, 0xFF0000); wait(0.5); led2 = 0; uLCD.filled_rectangle(64, 0, 127, 40, 0x000000); led3 = 1; uLCD.filled_rectangle(64, 87, 127, 127, 0x0000FF); wait(0.5); led3 = 0; uLCD.filled_rectangle(64, 87, 127, 127, 0x000000); led4 = 1; uLCD.filled_rectangle(0, 87, 63, 127, 0xCCCC00); wait(0.5); led4 = 0; uLCD.filled_rectangle(0, 87, 63, 127, 0x000000); wait(2); uLCD.cls(); } void setLevels(){ // "levels" array is a sequence of numbers 1-4 that determines which LEDs will light up // during a given level --- grows by 1 value each level level++; levels[level-1] = rand()%4 + 1; // display the current level on the uLCD uLCD.color(BLUE); uLCD.text_width(2); uLCD.text_height(2); uLCD.locate(2, 2); uLCD.printf("Level"); uLCD.locate(4, 4); uLCD.printf("%d", level); wait(1); } void playSequence(){ // play the sequence of LEDs defined in the "levels" array along with the corresponding notes for(int i = 0; i < level; i++){ switch(levels[i]){ case 1: led1 = 1; mySpeaker.PlayNote(659.26, 0.50, volume); led1 = 0; wait(0.025); break; case 2: led2 = 1; mySpeaker.PlayNote(554.00, 0.50, volume); led2 = 0; wait(0.025); break; case 3: led3 = 1; mySpeaker.PlayNote(440.00, 0.50, volume); led3 = 0; wait(0.025); break; case 4: led4 = 1; mySpeaker.PlayNote(329.63, 0.50, volume); led4 = 0; wait(0.025); break; default: while(1){ led1 = !led1; wait(0.5); } } } } // ISR for pushbutton 1 interrupt void pushOne(){ buttonPushes++; led1 = 1; mySpeaker.PlayNote(659.26, 0.25, volume); led1 = 0; if(levels[buttonPushes-1] != 1){ failed = 1; } } // ISR for pushbutton 2 interrupt void pushTwo(){ buttonPushes++; led2 = 1; mySpeaker.PlayNote(554.00, 0.25, volume); led2 = 0; if(levels[buttonPushes-1] != 2){ failed = 1; } } // ISR for pushbutton 3 interrupt void pushThree(){ buttonPushes++; led3 = 1; mySpeaker.PlayNote(440.00, 0.25, volume); led3 = 0; if(levels[buttonPushes-1] != 3){ failed = 1; } } // ISR for pushbutton 4 interrupt void pushFour(){ buttonPushes++; led4 = 1; mySpeaker.PlayNote(329.63, 0.25, volume); led4 = 0; if(levels[buttonPushes-1] != 4){ failed = 1; } } // this function is called when the user fails the game void failedGame(){ uLCD.cls(); uLCD.color(RED); uLCD.text_width(2); uLCD.text_height(2); uLCD.locate(2, 2); uLCD.printf("Game"); uLCD.locate(2, 4); uLCD.printf("Over"); mySpeaker.PlayNote(147.00, 0.60, volume); mySpeaker.PlayNote(139.00, 0.60, volume); mySpeaker.PlayNote(131.00, 0.60, volume); mySpeaker.PlayNote(123.00, 1.60, volume); } // this function is called if the user completes all levels void endGame(){ uLCD.cls(); uLCD.color(GREEN); uLCD.text_width(2); uLCD.text_height(2); uLCD.locate(2, 2); uLCD.printf("YOU"); uLCD.locate(2, 4); uLCD.printf("WIN!"); int time = 0.01; mySpeaker.PlayNote(392.00, 0.33, volume); wait(time); mySpeaker.PlayNote(349.23, 0.17, volume); wait(time); mySpeaker.PlayNote(311.13, 0.33, volume); wait(time); mySpeaker.PlayNote(311.13, 0.17, volume); wait(time); mySpeaker.PlayNote(311.13, 0.33, volume); wait(time); mySpeaker.PlayNote(349.23, 0.17, volume); wait(time); mySpeaker.PlayNote(392.00, 0.33, volume); wait(time); mySpeaker.PlayNote(392.00, 0.17, volume); wait(time); mySpeaker.PlayNote(392.00, 0.165, volume); wait(time); mySpeaker.PlayNote(349.23, 0.165, volume); wait(time); mySpeaker.PlayNote(311.13, 0.17, volume); wait(time); mySpeaker.PlayNote(349.23, 0.165, volume); wait(time); mySpeaker.PlayNote(392.00, 0.165, volume); wait(time); mySpeaker.PlayNote(349.23, 0.17, volume); wait(time); mySpeaker.PlayNote(311.13, 0.33, volume); wait(time); mySpeaker.PlayNote(293.66, 0.17, volume); wait(time); mySpeaker.PlayNote(311.13, 0.5, volume); }