Initial test
Dependencies: mbed wave_player mbed-rtos 4DGL-uLCD-SE SDFileSystem
Revision 5:269d04e12a9e, committed 2020-04-28
- Comitter:
- rushib1
- Date:
- Tue Apr 28 02:13:45 2020 +0000
- Parent:
- 4:c1da839b41b1
- Commit message:
- Commenting
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/main.cpp Mon Apr 27 03:38:35 2020 +0000 +++ b/main.cpp Tue Apr 28 02:13:45 2020 +0000 @@ -10,10 +10,25 @@ #include <fstream> #include <algorithm> -enum DIFF_LEVEL{NA=0, EASY=1, MED=2, HARD=3, SCORE=4}; -enum SIGN{PLUS=0, MINUS=1, MULT=2}; +using namespace std; +extern "C" void mbed_reset(); -struct Gen_Question{ +enum DIFF_LEVEL +{ + NA = 0, + EASY = 1, + MED = 2, + HARD = 3, + SCORE = 4 +}; + +/* +------------------STRUCTS +*/ + +//Define a question +struct Gen_Question +{ int num1; int num2; int sign; @@ -21,7 +36,9 @@ int ans[4]; }; -struct Game_Difficulty{ +//Define difficulty +struct Game_Difficulty +{ bool is_selected; enum DIFF_LEVEL level; int ans_time; @@ -30,31 +47,29 @@ int score_mult; }; -struct Game_Settings{ +//Define game settings +struct Game_Settings +{ Game_Difficulty new_diff; int score; - int live_left; + int live_left; int q_on; bool is_timeout; bool is_lose; }; - -Game_Settings new_game = {.q_on=1, .live_left = 3, .new_diff.is_selected=false, .is_timeout=true, .is_lose =false}; - - -void print_high_score(); -int* read_high_score(); +Game_Settings new_game = {.q_on = 1, .live_left = 3, .new_diff.is_selected = false, .is_timeout = true, .is_lose = false}; /* ------------------CONSTS */ -//const int EASY_TIME =20; -//const int MED_TIME =15; -//const int HARD_TIME =10; +const int EASY_TIME = 20; +const int MED_TIME = 15; +const int HARD_TIME = 10; -volatile bool homescreen = true; -volatile bool boot_vid = true; +const int EASY_NUM_Q = 7; +const int MED_NUM_Q = 10; +const int HARD_NUM_Q = 15; /* ------------------I/O VARS @@ -63,7 +78,7 @@ RawSerial bluemod(p28, p27); Serial pc(USBTX, USBRX); uLCD_4DGL uLCD(p9, p10, p11); -DigitalIn pb(p12); +InterruptIn pb(p12); /* ------------------LED VARS @@ -77,23 +92,59 @@ ------------------AUDIO VARS */ -FILE *wave_file; AnalogOut DACount(p18); wave_player waver(&DACount); /* ------------------GENERAL VARS */ +volatile bool homescreen = true; volatile char bnum = '0'; - +/* +------------------THREAD VARS +*/ Mutex lcd_mutex; Mutex blue_mutex; +Mutex sd_mutex; Thread thread1, thread2, thread3; -void main_screen() +/* +------------------PROTOTYPES +*/ + +void wav_thread(); +void boot_video(); +void print_main_screen(); +void print_high_score(); +int *read_high_score(); +bool count_distinct(int arr[], int n); +void gen_ans(Gen_Question *gen_new_q); +void game_questions(Gen_Question *gen_new_q); +void print_game_over(); +void print_win_game(); +void print_score_game(); +void life_count_check(); +void check_correct_ans(Gen_Question check_new_q); +void reset_program(); +void reset_scores(); +void check_new_highscore(); +void init(); +void print_high_score(); +int *read_high_score(); +void write_high_score(int *score_arr); +void bluetooth_thread(); +bool get_bluetooth_button(); +void get_button(); +void rgb_led_difficulty(); + + + +//PRINT THE INTRO SCREEN + +void print_main_screen() { - //pc.printf("MAIN_SCREEN\r\n"); + //pc.printf("print_main_screen\r\n"); uLCD.cls(); uLCD.text_height(1); uLCD.text_width(1); @@ -120,37 +171,109 @@ homescreen = false; } -bool count_distinct(int arr[], int n) +//PRINT THE WIN GAME SCREEN + +void print_win_game() +{ + uLCD.cls(); + uLCD.locate(2, 7); + uLCD.text_height(2); + uLCD.text_width(2); + uLCD.color(GREEN); + uLCD.printf("YOU WIN"); + uLCD.rectangle(0, 0, 127, 127, 0xA89C94); +} + +//PRINT THE GAME OVER SCREEN + +void print_game_over() { - int res = 1; - // Pick all elements one by one - for (int i = 1; i < n; i++) + uLCD.cls(); + uLCD.locate(0, 7); + uLCD.text_height(2); + uLCD.text_width(2); + uLCD.color(0xFC776A); + uLCD.printf("GAME OVER"); + uLCD.rectangle(0, 0, 127, 127, 0xA89C94); +} + +//PRINT THE CURRENT GAME SCORE + +void print_score_game() +{ + uLCD.cls(); + uLCD.locate(4, 3); + uLCD.text_height(2); + uLCD.text_width(2); + uLCD.color(GREEN); + uLCD.printf("SCORE"); + uLCD.rectangle(0, 0, 127, 127, 0xA89C94); + uLCD.text_height(1); + uLCD.text_width(1); + uLCD.locate(7, 7); + uLCD.printf("%i", new_game.score); +} + +/* +Show difficulty selected with RGB led +Set difficulty parameters +Or go to high score screen + +Get based on value from bluetooth button +*/ +void rgb_led_difficulty() +{ + //pc.printf("%i\r\n",bnum - 48); + new_game.new_diff.level = static_cast<DIFF_LEVEL>(bnum - 48); + //pc.printf("%i\r\n",new_game.new_diff.level); + if (new_game.new_diff.level == EASY) { - int j = 0; - for (j = 0; j < i; j++) - if (arr[i] == arr[j]) - break; - // If not printed earlier, then print it - if (i == j) - res++; + myRGBled.write(0.0, 1.0, 0.0); //green + new_game.new_diff.is_selected = true; + new_game.new_diff.ans_time = EASY_TIME; + new_game.new_diff.max_num = 10; + new_game.new_diff.num_of_q = EASY_NUM_Q; // 7 + new_game.score = 50; + new_game.new_diff.score_mult = 10; } - if (res == 4) + else if (new_game.new_diff.level == MED) { - return false; + myRGBled.write(1.0, 0.2, 0.0); //yellow = red + some green + new_game.new_diff.is_selected = true; + new_game.new_diff.ans_time = MED_TIME; + new_game.new_diff.max_num = 15; + new_game.new_diff.num_of_q = MED_NUM_Q; + new_game.score = 200; + new_game.new_diff.score_mult = 50; } - else + else if (new_game.new_diff.level == HARD) { - return true; + myRGBled.write(1.0, 0.0, 0.0); //red + new_game.new_diff.is_selected = true; + new_game.new_diff.ans_time = HARD_TIME; + new_game.new_diff.max_num = 10; + new_game.new_diff.num_of_q = HARD_NUM_Q; + new_game.score = 300; + new_game.new_diff.score_mult = 100; + } + else if (new_game.new_diff.level == SCORE) + { + myRGBled.write(0.5, 0.5, 0.5); + new_game.new_diff.is_selected = true; } } - +/* +Random generate quesitons with +,-,* +Use difficulty paramter max_num defining the upper random range +Generate incorrect questions +*/ void gen_ans(Gen_Question *gen_new_q) { //rand()%(max-min + 1) + min; gen_new_q->num1 = rand() % (new_game.new_diff.max_num + 1 - 0) + 0; gen_new_q->num2 = rand() % (new_game.new_diff.max_num + 1 - 1) + 1; gen_new_q->sign = rand() % (3 + 1 - 1) + 1; - + switch (gen_new_q->sign) { case 1: @@ -181,6 +304,36 @@ } } +/* +Check if all the answers generated are distinct +*/ +bool count_distinct(int arr[], int n) +{ + int res = 1; + // Pick all elements one by one + for (int i = 1; i < n; i++) + { + int j = 0; + for (j = 0; j < i; j++) + if (arr[i] == arr[j]) + break; + // If not printed earlier, then print it + if (i == j) + res++; + } + if (res == 4) + { + return false; + } + else + { + return true; + } +} + +/* +Handles generating a question, checking distinctness and printing to the screen +*/ void game_questions(Gen_Question *gen_new_q) { gen_ans(gen_new_q); @@ -201,7 +354,7 @@ uLCD.text_height(2); uLCD.text_width(2); uLCD.color(0xFC766A); - uLCD.printf("Q%i",new_game.q_on); + uLCD.printf("Q%i", new_game.q_on); uLCD.text_height(1); uLCD.text_width(1); @@ -256,61 +409,12 @@ uLCD.line(0, 115, 127, 115, 0xA89C94); } -void game_over() -{ - uLCD.cls(); - uLCD.locate(0, 7); - uLCD.text_height(2); - uLCD.text_width(2); - uLCD.color(0xFC776A); - uLCD.printf("GAME OVER"); - uLCD.rectangle(0, 0, 127, 127, 0xA89C94); -} - -void win_game() -{ - uLCD.cls(); - uLCD.locate(2, 7); - uLCD.text_height(2); - uLCD.text_width(2); - uLCD.color(GREEN); - uLCD.printf("YOU WIN"); - uLCD.rectangle(0, 0, 127, 127, 0xA89C94); - -} - -void score_game() -{ - uLCD.cls(); - uLCD.locate(1, 3); - uLCD.text_height(2); - uLCD.text_width(2); - uLCD.color(GREEN); - uLCD.printf("SCORE"); - uLCD.rectangle(0, 0, 127, 127, 0xA89C94); - uLCD.text_height(1); - uLCD.text_width(1); - uLCD.locate(7, 7); - uLCD.printf("%i",new_game.score); -} - -void life_count_check() -{ - life[0] = 0; - life[1] = 0; - life[2] = 0; - - for (int i = 0; i < new_game.live_left; i++) - { - life[i] = 1; - } - if (new_game.live_left == 0) - { - new_game.is_lose = true; - - } -} - +/* +Check if question was answered correctly +Wait on bluetooth ans or timeout +Prints correct, incorrect, or timeout as necessary +Removes lives as necessary +*/ void check_correct_ans(Gen_Question check_new_q) { if (new_game.is_timeout) @@ -358,12 +462,54 @@ } } +/* +Set LEDs for lives correctly +If No more lives then print lose screen +*/ +void life_count_check() +{ + life[0] = 0; + life[1] = 0; + life[2] = 0; + for (int i = 0; i < new_game.live_left; i++) + { + life[i] = 1; + } + if (new_game.live_left == 0) + { + new_game.is_lose = true; + } +} + +/* +Used initially to call bluetooth button click gathering +Only used on the main screen +*/ +void bluetooth_thread() +{ + while (true) + { + if (bluemod.readable()) + { + bool n_timeout = get_bluetooth_button(); + } + else + { + Thread::yield(); + } + Thread::wait(100); + } +} + +/* +Gets button clicks from bluetooth +*/ bool get_bluetooth_button() { //pc.printf("BLUETOOTH\r\n"); bnum = '0'; - //blue_mutex.lock(); + blue_mutex.lock(); if (bluemod.getc() == '!') { if (bluemod.getc() == 'B') @@ -383,10 +529,15 @@ } } } - //blue_mutex.unlock(); + blue_mutex.unlock(); return true; } +/* +Prints timer during main game +Checks if the bluetooth gives a button click +If button is clicked stops timer then checks answer +*/ void get_button() { int timer = new_game.new_diff.ans_time; @@ -399,7 +550,8 @@ if (bluemod.readable()) { new_game.is_timeout = get_bluetooth_button(); - if(new_game.is_timeout == false){ + if (new_game.is_timeout == false) + { break; } } @@ -408,143 +560,131 @@ uLCD.color(BLACK); uLCD.printf("%i", timer); timer = timer - 1; - - } -} - -void bluetooth_thread() -{ - while (true) - { - if (bluemod.readable()) - { - bool n_timeout = get_bluetooth_button(); - } - else - { - Thread::yield(); - } - Thread::wait(100); } } -void rgb_led_difficulty() -{ - //pc.printf("%i\r\n",bnum - 48); - new_game.new_diff.level = static_cast<DIFF_LEVEL>(bnum - 48); - //pc.printf("%i\r\n",new_game.new_diff.level); - if (new_game.new_diff.level == EASY) - { - myRGBled.write(0.0, 1.0, 0.0); //green - new_game.new_diff.is_selected = true; - new_game.new_diff.ans_time = 20; - new_game.new_diff.max_num = 10; - new_game.new_diff.num_of_q = 7; // 7 - new_game.score = 50; - new_game.new_diff.score_mult = 10; - } - else if (new_game.new_diff.level == MED) - { - myRGBled.write(1.0, 0.2, 0.0); //yellow = red + some green - new_game.new_diff.is_selected = true; - new_game.new_diff.ans_time = 15; - new_game.new_diff.max_num = 15; - new_game.new_diff.num_of_q = 10; - new_game.score = 200; - new_game.new_diff.score_mult = 50; - } - else if (new_game.new_diff.level == HARD) - { - myRGBled.write(1.0, 0.0, 0.0); //red - new_game.new_diff.is_selected = true; - new_game.new_diff.ans_time = 10; - new_game.new_diff.max_num = 10; - new_game.new_diff.num_of_q = 15; - new_game.score = 300; - new_game.new_diff.score_mult = 100; - } - else if (new_game.new_diff.level == SCORE) - { - myRGBled.write(0.5, 0.5, 0.5); - new_game.new_diff.is_selected = true; - print_high_score(); - } -} - +/* +Plays background music +*/ void wav_thread() { while (true) { - //pc.printf("AUDIO\r\n"); + FILE *wave_file; wave_file = fopen("/sd/audio/intro.wav", "r"); waver.play(wave_file); fclose(wave_file); } } -void boot_video_thread() +/* +Plays bootup video +*/ +void boot_video() { - while (true) - { - //pc.printf("BootVID\r\n"); - //PLAY VIDEO BOOT - if (boot_vid) - { - //lcd_mutex.lock(); - uLCD.media_init(); - uLCD.set_sector_address(0x0, 0x0); - uLCD.display_video(0, 0); - boot_vid = false; - //lcd_mutex.unlock(); - } - else - { - Thread::yield(); - } - } + uLCD.media_init(); + uLCD.set_sector_address(0x0, 0x0); + uLCD.display_video(0, 0); } -void write_high_score(int* score_arr){ +/* +write high scores to file +*/ +void write_high_score(int *score_arr) +{ std::ofstream score_file; score_file.open("/sd/score/score.txt"); if (score_file.is_open()) { - //score_file << "300\n200\n100\n"; - score_file << score_arr[0] << "\n" << score_arr[1] << "\n" << score_arr[2] << "\n"; - score_file.close(); + //score_file << "300\n200\n100\n"; + score_file << score_arr[0] << "\n" + << score_arr[1] << "\n" + << score_arr[2] << "\n"; + score_file.close(); } } - -int* read_high_score() +/* +read high scores from file +*/ +int *read_high_score() { - int* score_val = new int[3]; - //printf("read_high_score\n\r"); + int *score_val = new int[3]; + printf("read_high_score\n\r"); std::ifstream infile("/sd/score/score.txt"); - wait(0.2); - if (infile.is_open()) + while(!infile){ + std::ifstream infile("/sd/score/score.txt"); + wait(1); + } + if (infile) { + printf("file open\n\r"); std::string line; int i = 0; - while (std::getline(infile, line)) { + while (std::getline(infile, line)) + { // using printf() in all tests for consistency //printf("%s", line.c_str()); score_val[i] = atoi(line.c_str()); i++; } - infile.close(); } + infile.close(); + //.printf("%i \n\r", strerror(errno)); pc.printf("%i \n\r", score_val[0]); pc.printf("%i \n\r", score_val[1]); pc.printf("%i \n\r", score_val[2]); - + return score_val; } -void print_high_score(){ - - int* score_arr= read_high_score(); - +/* +check if there is a new highscore +if so shift high scores as necessary +*/ +void check_new_highscore() +{ + int *new_score_arr = read_high_score(); + for (int i = 0; i < 3; i++) + { + if (new_score_arr[i] < new_game.score) + { + int j = 1; + while (i <= j) + { + new_score_arr[j + 1] = new_score_arr[j]; + j--; + } + new_score_arr[i] = new_game.score; + //pc.printf("high score found"); + write_high_score(new_score_arr); + break; + } + } + delete[] new_score_arr; +} + +/* +Rest high scores to 0 +*/ +void reset_scores() +{ + mkdir("/sd/score", 0777); + std::ofstream score_file; + score_file.open("/sd/score/score.txt"); + if (score_file.is_open()) + { + score_file << "30\n20\n10\n"; + score_file.close(); + } +} + +//PRINT THE STORES HIGH SCORES +void print_high_score() +{ + //pc.printf("GET SCORE"); + int *score_arr = read_high_score(); + pc.printf("PRINTING SCORES"); uLCD.cls(); uLCD.text_height(1); uLCD.text_width(1); @@ -556,78 +696,63 @@ uLCD.printf("1) %i", score_arr[0]); uLCD.locate(3, 8); uLCD.color(0x669DB2); - uLCD.printf("2) %i", score_arr[1]); + uLCD.printf("2) %i", score_arr[1]); uLCD.locate(3, 10); uLCD.color(0xFC776A); - uLCD.printf("3) %i", score_arr[2]); + uLCD.printf("3) %i", score_arr[2]); uLCD.rectangle(0, 0, 127, 127, 0xA89C94); - delete[] score_arr; + delete[] score_arr; } -void check_new_highscore(){ - int* new_score_arr = read_high_score(); - for (int i = 0; i < 3; i++) - { - if (new_score_arr[i]< new_game.score){ - int j = 1; - while(i<=j){ - new_score_arr[j+1] = new_score_arr[j]; - j--; - } - new_score_arr[i] = new_game.score; - pc.printf("high score found"); - write_high_score(new_score_arr); - break; - } - } - delete[] new_score_arr; -} -void reset_scores(){ - mkdir("/sd/score", 0777); - std::ofstream score_file; - score_file.open("/sd/score/score.txt"); - if (score_file.is_open()) - { - score_file << "0\n0\n0\n"; - score_file.close(); - } -} - +/* +Initialize mbed paramters +set lives +start boot video +*/ void init() { + // while(1){ +// print_high_score(); // reset_scores(); -// wait(2); +// wait(5); // } + pb.mode(PullUp); + pb.rise(&reset_program); uLCD.baudrate(3000000); srand(time(NULL)); life[0] = 1; life[1] = 1; life[2] = 1; - //thread1.start(boot_video_thread); - boot_vid = false; + boot_video(); } - +/* +reset mbed +*/ +void reset_program() +{ + mbed_reset(); +} int main() { + //START PLAYING MUSIC + thread2.start(wav_thread); init(); -// pc.printf("MAIN_INIT\r\n\n"); - thread2.start(wav_thread); + //pc.printf("MAIN_INIT\r\n\n"); while (true) { //pc.printf("MAIN_LOOP\r\n"); - //ONCE VIDEO STOPS PLAYING - if (boot_vid == false) - { - thread1.terminate(); + //IF HOMESCREEN PRINTED ONCE DONT PRINT AGAIN if (homescreen) { - main_screen(); + print_main_screen(); } - //pc.printf("MAIN_PRINT\r\n"); + //WAIT UNTIL DIFFICULTY IS SELECTED + //IF SELECTED TURN ON LED COLOR + //TURN OFF BLUETOOTH THREAD DONT WANT if (new_game.new_diff.is_selected == false) { thread3.start(bluetooth_thread); @@ -636,12 +761,23 @@ else { thread3.terminate(); + if(new_game.new_diff.level == SCORE){ + thread2.terminate(); + DACount = 0.0; + print_high_score(); + + } break; } - } + Thread::wait(100); } - if(new_game.new_diff.level != SCORE){ + //WHEN NOT SELECTED HIGH SCORE LEVL + if (new_game.new_diff.level != SCORE) + { + //KEEP PRINTING QUESTIONS UNTIL DEFINED DIFFICULTY + //CHECK ANSWERS, LIVES + //PRINT LOSE OR WIN GAME SCREENS while (new_game.q_on <= new_game.new_diff.num_of_q) { thread3.terminate(); @@ -652,17 +788,23 @@ new_game.q_on++; wait(2.2); life_count_check(); - if(new_game.is_lose == true){ - game_over(); + if (new_game.is_lose == true) + { + print_game_over(); break; } } - if(new_game.is_lose == false){ - win_game(); + if (new_game.is_lose == false) + { + print_win_game(); } + //CALCULATE SCORE OF THE GAME PRINT + //PRINT HIGH SCORES wait(2.5); new_game.score = new_game.score + new_game.live_left * 100; - score_game(); + print_score_game(); + thread2.terminate(); + DACount = 0.0; wait(2); check_new_highscore(); wait(0.5);