Dependencies: mbed wave_player mbed-rtos 4DGL-uLCD-SE SDFileSystem
Diff: main.cpp
- Revision:
- 3:6e41a5ce16c2
- Parent:
- 2:acd4656312d8
- Child:
- 4:c1da839b41b1
diff -r acd4656312d8 -r 6e41a5ce16c2 main.cpp --- a/main.cpp Sun Apr 26 00:47:37 2020 +0000 +++ b/main.cpp Mon Apr 27 03:14:16 2020 +0000 @@ -10,17 +10,51 @@ #include <fstream> #include <algorithm> -using namespace std; +enum DIFF_LEVEL{NA=0, EASY=1, MED=2, HARD=3, SCORE=4}; +enum SIGN{PLUS=0, MINUS=1, MULT=2}; + +struct Gen_Question{ + int num1; + int num2; + int sign; + int corr_ans; + int ans[4]; +}; + +struct Game_Difficulty{ + bool is_selected; + enum DIFF_LEVEL level; + int ans_time; + int max_num; + int num_of_q; + int score_mult; +}; + +struct Game_Settings{ + Game_Difficulty new_diff; + int score; + 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(); /* ------------------CONSTS */ +//const int EASY_TIME =20; +//const int MED_TIME =15; +//const int HARD_TIME =10; volatile bool homescreen = true; -volatile bool diff_selected = false; volatile bool boot_vid = true; -bool timeout = true; -bool game_is_over = false; /* ------------------I/O VARS @@ -50,14 +84,8 @@ /* ------------------GENERAL VARS */ -int difficulty = 0; -string scores; -int score_val[3]; -volatile char bnum; -int ans[4]; -int corr_ans; -char sign; -int live_left = 3; +volatile char bnum = '0'; + Mutex lcd_mutex; Mutex blue_mutex; @@ -65,23 +93,17 @@ void main_screen() { - - //while(true){ - // if(homescreen){ - pc.printf("MAIN_SCREEN\r\n"); - lcd_mutex.lock(); + //pc.printf("MAIN_SCREEN\r\n"); uLCD.cls(); - uLCD.text_height(1.9); - uLCD.text_width(1.9); - uLCD.color(WHITE); + uLCD.text_height(1); + uLCD.text_width(1); + uLCD.color(0xF0F6F7); uLCD.locate(6, 1); uLCD.printf("MATH FUN"); - //MAKE MATH FUN BLINK uLCD.locate(1, 4); - uLCD.text_height(1.3); uLCD.printf("Difficulty"); - uLCD.text_height(1.3); - uLCD.text_width(1.9); + uLCD.text_height(1); + uLCD.text_width(1); uLCD.locate(3, 6); uLCD.color(GREEN); uLCD.printf("1) Easy"); @@ -91,25 +113,16 @@ uLCD.locate(3, 10); uLCD.color(RED); uLCD.printf("3) Very Uneasy"); - uLCD.color(BLUE); + uLCD.color(0x669DB2); uLCD.locate(1, 13); uLCD.printf("4) High Scores"); - lcd_mutex.unlock(); - //pc.printf("thread 1\r\n"); + uLCD.rectangle(0, 0, 127, 127, 0xA89C94); homescreen = false; - // Thread::wait(100); - // } - // else{ - // Thread::yield(); - // } - //} } bool count_distinct(int arr[], int n) { - int res = 1; - // Pick all elements one by one for (int i = 1; i < n; i++) { @@ -117,12 +130,10 @@ for (j = 0; j < i; j++) if (arr[i] == arr[j]) break; - - // If not printed earlier, then print it + // If not printed earlier, then print it if (i == j) res++; } - if (res == 4) { return false; @@ -133,67 +144,64 @@ } } -void gen_ans(int &num1, int &num2, int sign_val) +void gen_ans(Gen_Question *gen_new_q) { - - switch (sign_val) + //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: - sign = '*'; - ans[0] = num1 * num2; - ans[1] = (num1 + (rand() % (10 + 1 - 1) + 1)) * num2; - ans[2] = (num1 * num2) + (rand() % (20 + 1 - 1) + 1); - ans[3] = (num1 * num2) + (rand() % (20 + 1 - 1) + 1); + gen_new_q->sign = '*'; + gen_new_q->ans[0] = gen_new_q->num1 * gen_new_q->num2; + gen_new_q->ans[1] = (gen_new_q->num1 + (rand() % (10 + 1 - 1) + 1)) * gen_new_q->num2; + gen_new_q->ans[2] = (gen_new_q->num1 * gen_new_q->num2) + (rand() % (20 + 1 - 1) + 1); + gen_new_q->ans[3] = (gen_new_q->num1 * gen_new_q->num2) + (rand() % (20 + 1 - 1) + 1); break; case 2: - sign = '+'; - ans[0] = num1 + num2; - ans[1] = (num1 + (rand() % (10 + 1 - 1) + 1)) + num2; - ans[2] = (num1 + num2) - (rand() % ((num1 + num2) + 1 - 1) + 1); - ans[3] = (num1 * num2) + (rand() % (10 + 1 - 1) + 1); + gen_new_q->sign = '+'; + gen_new_q->ans[0] = gen_new_q->num1 + gen_new_q->num2; + gen_new_q->ans[1] = (gen_new_q->num1 + (rand() % (10 + 1 - 1) + 1)) + gen_new_q->num2; + gen_new_q->ans[2] = (gen_new_q->num1 + gen_new_q->num2) - (rand() % ((gen_new_q->num1 + gen_new_q->num2) + 1 - 1) + 1); + gen_new_q->ans[3] = (gen_new_q->num1 * gen_new_q->num2) + (rand() % (10 + 1 - 1) + 1); break; case 3: - sign = '-'; - //rand()%(max-min + 1) + min; - while (num1 == num2) + gen_new_q->sign = '-'; + while (gen_new_q->num1 == gen_new_q->num2) { - num1 = (rand() % ((num1 + 2) - 1 + 1) + 1); + gen_new_q->num1 = (rand() % ((gen_new_q->num1 + 2) - 1 + 1) + 1); } - ans[0] = num1 - num2; - ans[1] = (num1 - num2) * -1 + (rand() % (10 + 1 - 1) + 1); - ans[2] = num1 + num2 - (rand() % (10 + 1 - 1) + 1); - ans[3] = num1 * num2 - (rand() % (20 + 1 - 1) + 1); - break; - case 4: - sign = '/'; - ans[0] = num1 - num2; + gen_new_q->ans[0] = gen_new_q->num1 - gen_new_q->num2; + gen_new_q->ans[1] = (gen_new_q->num1 - gen_new_q->num2) * -1 + (rand() % (10 + 1 - 1) + 1); + gen_new_q->ans[2] = gen_new_q->num1 + gen_new_q->num2 - (rand() % (10 + 1 - 1) + 1); + gen_new_q->ans[3] = gen_new_q->num1 * gen_new_q->num2 - (rand() % (20 + 1 - 1) + 1); break; } } -void game_questions() +void game_questions(Gen_Question *gen_new_q) { - int gen1 = rand() % (10 + 1 - 0) + 0; - int gen2 = rand() % (10 + 1 - 1) + 1; - int gen_sign = rand() % (3 + 1 - 1) + 1; - gen_ans(gen1, gen2, gen_sign); - bool reroll = count_distinct(ans, 4); + gen_ans(gen_new_q); + bool reroll = count_distinct(gen_new_q->ans, 4); while (reroll) { - gen_ans(gen1, gen2, gen_sign); - reroll = count_distinct(ans, 4); + gen_ans(gen_new_q); + reroll = count_distinct(gen_new_q->ans, 4); //pc.printf("reroll\r\n"); } - corr_ans = ans[0]; - random_shuffle(&ans[0], &ans[3]); - + gen_new_q->corr_ans = gen_new_q->ans[0]; + //pc.printf("%i\r\n", gen_new_q->ans[0]); + //pc.printf("%i\r\n", gen_new_q->corr_ans); + random_shuffle(&(gen_new_q->ans[0]), &(gen_new_q->ans[3])); uLCD.cls(); uLCD.locate(2, 1); uLCD.text_height(2); uLCD.text_width(2); uLCD.color(0xFC766A); - uLCD.printf("Q1"); + uLCD.printf("Q%i",new_game.q_on); uLCD.text_height(1); uLCD.text_width(1); @@ -209,7 +217,7 @@ uLCD.locate(2, 4); uLCD.text_height(2); uLCD.text_width(2); - uLCD.printf("%i%c%i=", gen1, sign, gen2); + uLCD.printf("%i%c%i=", gen_new_q->num1, gen_new_q->sign, gen_new_q->num2); uLCD.text_height(1); uLCD.text_width(1); @@ -219,7 +227,7 @@ uLCD.color(0x669DB2); uLCD.locate(8, 7); - uLCD.printf("%i", ans[0]); + uLCD.printf("%i", gen_new_q->ans[0]); uLCD.color(0xFC766A); uLCD.locate(2, 9); @@ -227,7 +235,7 @@ uLCD.color(0x669DB2); uLCD.locate(8, 9); - uLCD.printf("%i", ans[1]); + uLCD.printf("%i", gen_new_q->ans[1]); uLCD.color(0xFC766A); uLCD.locate(2, 11); @@ -235,7 +243,7 @@ uLCD.color(0x669DB2); uLCD.locate(8, 11); - uLCD.printf("%i", ans[2]); + uLCD.printf("%i", gen_new_q->ans[2]); uLCD.color(0xFC766A); uLCD.locate(2, 13); @@ -243,10 +251,11 @@ uLCD.color(0x669DB2); uLCD.locate(8, 13); - uLCD.printf("%i", ans[3]); + uLCD.printf("%i", gen_new_q->ans[3]); uLCD.line(0, 115, 127, 115, 0xA89C94); } + void game_over() { uLCD.cls(); @@ -255,8 +264,34 @@ uLCD.text_width(2); uLCD.color(0xFC776A); uLCD.printf("GAME OVER"); - game_is_over = true; - wait(2); + 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() @@ -265,19 +300,20 @@ life[1] = 0; life[2] = 0; - for (int i = 0; i < live_left; i++) + for (int i = 0; i < new_game.live_left; i++) { life[i] = 1; } - if (live_left == 0) + if (new_game.live_left == 0) { - game_over(); + new_game.is_lose = true; + } } -void check_correct_ans() +void check_correct_ans(Gen_Question check_new_q) { - if (timeout) + if (new_game.is_timeout) { //pc.printf("TIMEOUT\r\n"); uLCD.cls(); @@ -286,7 +322,7 @@ uLCD.text_width(2); uLCD.color(0xF0F6F7); uLCD.printf("TIME"); - live_left--; + new_game.live_left--; //wait(2); } else @@ -294,7 +330,7 @@ //pc.printf("%i\r\n", corr_ans); //pc.printf("%i\r\n", ans[(bnum-'0' -1)]); - if (corr_ans == ans[(bnum - '0') - 1]) + if (check_new_q.corr_ans == check_new_q.ans[(bnum - '0') - 1]) { uLCD.cls(); @@ -303,6 +339,7 @@ uLCD.text_width(2); uLCD.color(GREEN); uLCD.printf("CORRECT"); + new_game.score = new_game.score + new_game.new_diff.score_mult; //wait(2); //pc.printf("CORRECT\r\n"); } @@ -315,7 +352,7 @@ uLCD.text_width(2); uLCD.color(RED); uLCD.printf("INCORRECT"); - live_left--; + new_game.live_left--; //wait(2); } } @@ -324,8 +361,9 @@ bool get_bluetooth_button() { - pc.printf("BLUETOOTH\r\n"); - blue_mutex.lock(); + //pc.printf("BLUETOOTH\r\n"); + bnum = '0'; + //blue_mutex.lock(); if (bluemod.getc() == '!') { if (bluemod.getc() == 'B') @@ -338,21 +376,21 @@ { if (bhit == '1') { - pc.printf("%c\r\n", bnum); + //pc.printf("%c\r\n", bnum); blue_mutex.unlock(); return false; } } } } - blue_mutex.unlock(); + //blue_mutex.unlock(); return true; } void get_button() { - int timer = 10; - timeout = true; + int timer = new_game.new_diff.ans_time; + new_game.is_timeout = true; while (timer != 0) { uLCD.locate(15, 1); @@ -360,8 +398,8 @@ uLCD.printf("%i", timer); if (bluemod.readable()) { - timeout = get_bluetooth_button(); - if(timeout == false){ + new_game.is_timeout = get_bluetooth_button(); + if(new_game.is_timeout == false){ break; } } @@ -370,12 +408,10 @@ uLCD.color(BLACK); uLCD.printf("%i", timer); timer = timer - 1; - //pc.printf("%i\r\n", x); + } } - - void bluetooth_thread() { while (true) @@ -394,22 +430,44 @@ void rgb_led_difficulty() { - difficulty = bnum - 48; - //pc.printf("%i\r\n",difficulty); - if (difficulty == 1) + //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 - diff_selected = true; + 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 (difficulty == 2) + else if (new_game.new_diff.level == MED) { myRGBled.write(1.0, 0.2, 0.0); //yellow = red + some green - diff_selected = true; + 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 (difficulty == 3) + else if (new_game.new_diff.level == HARD) { myRGBled.write(1.0, 0.0, 0.0); //red - diff_selected = true; + 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(); } } @@ -417,7 +475,7 @@ { while (true) { - pc.printf("AUDIO\r\n"); + //pc.printf("AUDIO\r\n"); wave_file = fopen("/sd/audio/intro.wav", "r"); waver.play(wave_file); fclose(wave_file); @@ -446,21 +504,116 @@ } } +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(); + } +} + + +int* read_high_score() +{ + 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()) + { + std::string line; + int i = 0; + 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(); + } + 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(); + + uLCD.cls(); + uLCD.text_height(1); + uLCD.text_width(1); + uLCD.color(0xF0F6F7); + uLCD.locate(4, 1); + uLCD.printf("HIGH SCORES"); + uLCD.locate(3, 6); + uLCD.color(0xFC776A); + uLCD.printf("1) %i", score_arr[0]); + uLCD.locate(3, 8); + uLCD.color(0x669DB2); + uLCD.printf("2) %i", score_arr[1]); + uLCD.locate(3, 10); + uLCD.color(0xFC776A); + uLCD.printf("3) %i", score_arr[2]); + uLCD.rectangle(0, 0, 127, 127, 0xA89C94); + 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 = i; + while(j<2){ + 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(); + } +} + void init() { +// while(1){ +// reset_scores(); +// wait(2); +// } uLCD.baudrate(3000000); srand(time(NULL)); life[0] = 1; life[1] = 1; life[2] = 1; - thread1.start(boot_video_thread); + //thread1.start(boot_video_thread); + boot_vid = false; } + int main() { - init(); - pc.printf("MAIN_INIT\r\n\n"); +// pc.printf("MAIN_INIT\r\n\n"); thread2.start(wav_thread); while (true) { @@ -475,8 +628,7 @@ main_screen(); } //pc.printf("MAIN_PRINT\r\n"); - //break; - if (diff_selected == false) + if (new_game.new_diff.is_selected == false) { thread3.start(bluetooth_thread); rgb_led_difficulty(); @@ -487,14 +639,33 @@ break; } } - Thread::wait(200); + Thread::wait(100); } - while (!game_is_over) - { - game_questions(); - get_button(); - check_correct_ans(); + if(new_game.new_diff.level != SCORE){ + while (new_game.q_on <= new_game.new_diff.num_of_q) + { + thread3.terminate(); + Gen_Question new_q; + game_questions(&new_q); + get_button(); + check_correct_ans(new_q); + new_game.q_on++; + wait(2.2); + life_count_check(); + if(new_game.is_lose == true){ + game_over(); + break; + } + } + if(new_game.is_lose == false){ + win_game(); + } + wait(2.5); + new_game.score = new_game.score + new_game.live_left * 100; + score_game(); wait(2); - life_count_check(); + check_new_highscore(); + wait(0.5); + print_high_score(); } } \ No newline at end of file