diff --git a/main/main.cpp b/main/main.cpp index e5d2a78..87ca709 100755 --- a/main/main.cpp +++ b/main/main.cpp @@ -26,6 +26,8 @@ #include "steps/p002_step5.h" #include "steps/p002_step6.h" +bool play_modified; + static const char *TAG = "main"; uint32_t initial_game_time = 90*60*1000 + 1000; uint32_t skip_to_step = 0; diff --git a/main/main.h b/main/main.h index 551c34d..2ec30fa 100644 --- a/main/main.h +++ b/main/main.h @@ -6,6 +6,8 @@ #include +extern bool play_modified; + constexpr size_t N_STEPS = 6; #endif /* MAIN_H */ \ No newline at end of file diff --git a/main/steps/p001_step4.cpp b/main/steps/p001_step4.cpp index 6a45a10..84ea122 100644 --- a/main/steps/p001_step4.cpp +++ b/main/steps/p001_step4.cpp @@ -1,4 +1,5 @@ #include "p001_step4.h" +#include "main.h" __attribute__((unused)) static const char *TAG = "step4"; @@ -233,8 +234,11 @@ bool play_game(int time, int required_score) { target_score = required_score; score = 0; update_score(); - // set_module_time(time); - // start_module_timer(); + + if (!play_modified) { + set_module_time(time); + start_module_timer(); + } clear_board(); @@ -272,7 +276,8 @@ bool play_game(int time, int required_score) { show_board(); if (score >= required_score) { - // stop_module_timer(); + if (!play_modified) + stop_module_timer(); return true; } } @@ -307,18 +312,19 @@ bool play_game(int time, int required_score) { show_board(); if (score >= required_score) { - // stop_module_timer(); + if (!play_modified) + stop_module_timer(); return true; } } } } - // if (get_module_time() <= 0) { - // stop_module_timer(); - // strike("Out of time"); - // return false; - // } + if ((!play_modified) && get_module_time() <= 0) { + stop_module_timer(); + strike("Out of time"); + return false; + } // if (get_switch_flipped(&switch_)) { // printf("%d\n", piece); @@ -334,7 +340,8 @@ bool play_game(int time, int required_score) { // game over ESP_LOGI(TAG, "Game Over. Score: %d", score); - // stop_module_timer(); + if (!play_modified) + stop_module_timer(); strike("Out of room"); return false; } @@ -390,13 +397,16 @@ void p001_step4() { do_star_codes(&star_code, 1); init_screen(); - while (!play_game(4*60*1000, 2)) fail(); + int lines_1 = play_modified ? 2 : 2; + int lines_2 = play_modified ? 5 : 4; + int lines_3 = play_modified ? 12 : 8; + while (!play_game(4*60*1000, lines_1)) fail(); play_clip_wav(MOUNT_POINT "/partdone.wav", true, false, 0, 0); complete(); - while (!play_game(4*60*1000, 5)) fail(); + while (!play_game(4*60*1000, lines_2)) fail(); play_clip_wav(MOUNT_POINT "/partdone.wav", true, false, 0, 0); complete(); - while (!play_game(7*60*1000, 12)) fail(); + while (!play_game(6*60*1000, lines_3)) fail(); play_clip_wav(MOUNT_POINT "/stepdone.wav", true, false, 1, 0); complete(); diff --git a/main/steps/p001_step5.cpp b/main/steps/p001_step5.cpp index 622d051..82900f1 100644 --- a/main/steps/p001_step5.cpp +++ b/main/steps/p001_step5.cpp @@ -7,6 +7,7 @@ #define TIME_BLINK 35'000 #define TIME_UMMM 35'000 #define TIME_BLANK 40'000 +#define TIME_WHAT 60'000 #define TIME_PLINK 40'000 __attribute__((unused)) @@ -650,100 +651,250 @@ void p001_step5(void) { break; } case 7: { - lcd_print("Plink"); - set_module_time(TIME_PLINK); - start_module_timer(); + if (play_modified) { + // do PLINK + lcd_print("Plink"); + set_module_time(TIME_PLINK); + start_module_timer(); - std::uniform_int_distribution<> indicator_number_dist(0, 4); + std::uniform_int_distribution<> indicator_number_dist(0, 4); - // ESP_LOGI(TAG, "Green: %i, Red: %i, Yellow: %i, Blue: %i", green_indicators, red_indicators, yellow_indicators, blue_indicators); + // ESP_LOGI(TAG, "Green: %i, Red: %i, Yellow: %i, Blue: %i", green_indicators, red_indicators, yellow_indicators, blue_indicators); - const uint32_t COLORS[] = { - LEDColor::LED_COLOR_GREEN, - LEDColor::LED_COLOR_RED, - LEDColor::LED_COLOR_YELLOW, - LEDColor::LED_COLOR_BLUE, - LEDColor::LED_COLOR_PINK, - }; + const uint32_t COLORS[] = { + LEDColor::LED_COLOR_GREEN, + LEDColor::LED_COLOR_RED, + LEDColor::LED_COLOR_YELLOW, + LEDColor::LED_COLOR_BLUE, + LEDColor::LED_COLOR_PINK, + }; - int solved_times = 0; - bool failed = false; - while (solved_times < 3 && !failed) { - int indicator_numbers[5] = {indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen)}; + int solved_times = 0; + bool failed = false; + while (solved_times < 3 && !failed) { + int indicator_numbers[5] = {indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen)}; + + std::vector led_options = all_leds; + for (int i = 0; i < 5; i++) { + set_unique_leds(led_options, indicator_numbers[i], COLORS[i]); + } + + leds_flush(); + + std::uniform_int_distribution<> answer_color_dist(0, 4); + + std::map color_name_map = { + {0, "Green"}, + {1, "Red"}, + {2, "Yellow"}, + {3, "Blue"}, + {4, "Pink"}, + }; + + int answer_color = answer_color_dist(gen); + + std::string color_string = color_name_map[answer_color]; + std::string answer_num = std::to_string(indicator_numbers[answer_color]); + + // ESP_LOGI(TAG, "color string: %s", color_string.c_str()); + + lcd_print(1, 2, color_string.c_str()); + + std::string entered_string; + + KeypadKey key; + while (1) { + if (get_keypad_pressed(&key)) { + bool failed = false; + + if (key == KeypadKey::star) { + // clear + entered_string = ""; + } else if (key == KeypadKey::pound) { + // submit + if (entered_string != answer_num) { + strike("Incorrect answer!"); + failed = true; + } else { + solved_correctly = true;; + } + break; + } else { + entered_string += char_of_keypad_key(key); + } + + if (failed) { + break; + } + + lcd_clear(); + lcd_print(1, 1, "Plink"); + lcd_print(1, 2, color_string.c_str()); + lcd_print(1, 3, entered_string.c_str()); + } + if (get_module_time() <= 0) { + strike("Ran out of time!"); + break; + } + + + vTaskDelay(pdMS_TO_TICKS(10)); + } + + break; + + } + if (!failed) { + solved_correctly = true; + } + } else { + // do WHAT + lcd_print(1, 1, "What"); + set_module_time(TIME_WHAT); + start_module_timer(); + + std::uniform_int_distribution<> math_number_dist(1, 9); + + std::vector math_numbers; + std::vector math_operations; + + std::map operation_map = { + {0, '+'}, + {1, '-'}, + {2, '*'}, + {3, '/'}, + }; + + int expression_answer = -1; + std::string display_expression; + + while (expression_answer < 0) { + math_numbers = {static_cast(math_number_dist(gen)), static_cast(math_number_dist(gen)), static_cast(math_number_dist(gen)), static_cast(math_number_dist(gen))}; + std::vector possible_math_operations = {0, 1, 2, 3}; + math_operations = unique_values(possible_math_operations, 3); + + display_expression = std::to_string(static_cast(math_numbers[0])); + for (int i = 0; i < 3; i++) { + display_expression += operation_map[math_operations[i]]; + display_expression += std::to_string(static_cast(math_numbers[i + 1])); + } + + // Solve + for (int j = 0; j < 3; j++) { + bool found = false; + for (int i = 0; i < math_operations.size(); i++) { + if (math_operations[i] == 2) { + // ESP_LOGI(TAG, "i = %i, condensing %f * %f to %f", i, math_numbers[i], math_numbers[i + 1], (math_numbers[i] * math_numbers[i+1])); + math_numbers[i] = math_numbers[i] * math_numbers[i + 1]; + math_numbers.erase(math_numbers.begin() + i + 1); + math_operations.erase(math_operations.begin() + i); + found = true; + break; + } else if (math_operations[i] == 3) { + // ESP_LOGI(TAG, "i = %i, condensing %f / %f to %f", i, math_numbers[i], math_numbers[i + 1], (math_numbers[i] / math_numbers[i+1])); + math_numbers[i] = math_numbers[i] / math_numbers[i + 1]; + math_numbers.erase(math_numbers.begin() + i + 1); + math_operations.erase(math_operations.begin() + i); + found = true; + break; + } + } + if (found) continue; + for (int i = 0; i < math_operations.size(); i++) { + if (math_operations[i] == 0) { + // ESP_LOGI(TAG, "i = %i, condensing %f + %f to %f", i, math_numbers[i], math_numbers[i + 1], (math_numbers[i] + math_numbers[i+1])); + math_numbers[i] = math_numbers[i] + math_numbers[i + 1]; + math_numbers.erase(math_numbers.begin() + i + 1); + math_operations.erase(math_operations.begin() + i); + found = true; + break; + } else if (math_operations[i] == 1) { + // ESP_LOGI(TAG, "i = %i, condensing %f - %f to %f", i, math_numbers[i], math_numbers[i + 1], (math_numbers[i] - math_numbers[i+1])); + math_numbers[i] = math_numbers[i] - math_numbers[i + 1]; + math_numbers.erase(math_numbers.begin() + i + 1); + math_operations.erase(math_operations.begin() + i); + found = true; + break; + } + } + } + expression_answer = static_cast(std::floor(math_numbers[0])); + } + + // display expression + lcd_print(2, 1, display_expression.c_str()); + + // set LEDs + const uint32_t COLORS[] = { + LEDColor::LED_COLOR_BLUE, + LEDColor::LED_COLOR_RED, + LEDColor::LED_COLOR_GREEN, + LEDColor::LED_COLOR_YELLOW, + }; + + std::uniform_int_distribution<> add_sub_indicator_dist(1, 6); + std::uniform_int_distribution<> mult_div_indicator_dist(1, 3); + + int modifier_indicators[4] = {add_sub_indicator_dist(gen), add_sub_indicator_dist(gen), mult_div_indicator_dist(gen), mult_div_indicator_dist(gen)}; + + + while ((((expression_answer + (modifier_indicators[0] * 3) - modifier_indicators[1]) * std::pow(3, modifier_indicators[2])) / std::pow(2, modifier_indicators[3])) < 0) { + modifier_indicators[0] = add_sub_indicator_dist(gen); + modifier_indicators[1] = add_sub_indicator_dist(gen); + modifier_indicators[2] = mult_div_indicator_dist(gen); + modifier_indicators[3] = mult_div_indicator_dist(gen); + } + + expression_answer += modifier_indicators[0] * 3; + expression_answer -= modifier_indicators[1]; + expression_answer *= std::pow(3, modifier_indicators[2]); + expression_answer /= std::pow(2, modifier_indicators[3]); std::vector led_options = all_leds; - for (int i = 0; i < 5; i++) { - set_unique_leds(led_options, indicator_numbers[i], COLORS[i]); + for (int i = 0; i < 4; i++) { + set_unique_leds(led_options, modifier_indicators[i], COLORS[i]); } leds_flush(); - std::uniform_int_distribution<> answer_color_dist(0, 4); + std::string answer_string = std::to_string(expression_answer); + std::string entered_string = ""; - std::map color_name_map = { - {0, "Green"}, - {1, "Red"}, - {2, "Yellow"}, - {3, "Blue"}, - {4, "Pink"}, - }; - - int answer_color = answer_color_dist(gen); - - std::string color_string = color_name_map[answer_color]; - std::string answer_num = std::to_string(indicator_numbers[answer_color]); - - // ESP_LOGI(TAG, "color string: %s", color_string.c_str()); - - lcd_print(1, 2, color_string.c_str()); - - std::string entered_string; + ESP_LOGI(TAG, "Solved full answer: %s", answer_string.c_str()); KeypadKey key; + while (1) { if (get_keypad_pressed(&key)) { - bool failed = false; - if (key == KeypadKey::star) { // clear entered_string = ""; } else if (key == KeypadKey::pound) { // submit - if (entered_string != answer_num) { + if (entered_string != answer_string) { strike("Incorrect answer!"); - failed = true; } else { - solved_correctly = true;; + solved_correctly = true; } break; } else { entered_string += char_of_keypad_key(key); } - if (failed) { - break; - } - lcd_clear(); - lcd_print(1, 1, "Plink"); - lcd_print(1, 2, color_string.c_str()); - lcd_print(1, 3, entered_string.c_str()); + lcd_print(1, 1, "What"); + lcd_print(2, 1, display_expression.c_str()); + lcd_print(3, 1, entered_string.c_str()); } if (get_module_time() <= 0) { strike("Ran out of time!"); break; } - vTaskDelay(pdMS_TO_TICKS(10)); } - - break; - - } - if (!failed) { - solved_correctly = true; } + break; } default: { diff --git a/main/steps/step0.cpp b/main/steps/step0.cpp index 7210fe0..5ad9027 100644 --- a/main/steps/step0.cpp +++ b/main/steps/step0.cpp @@ -47,6 +47,12 @@ static void replay_last() { } static void do_p001() { + play_modified = false; + puzzle = 1; +} + +static void do_p001_modified() { + play_modified = true; puzzle = 1; } @@ -62,10 +68,16 @@ void step0() { StarCodeHandler star_codes[] = { { .code = "*9819", - .display_text = "Start P001", + .display_text = "Start P001DH", .should_exit = true, .callback = do_p001, }, + { + .code = "*9818", + .display_text = "Start P001DM", + .should_exit = true, + .callback = do_p001_modified, + }, { .code = "*3141", .display_text = "Start P002", diff --git a/resources/correct.raw b/resources/correct.raw new file mode 100644 index 0000000..8b68bfe Binary files /dev/null and b/resources/correct.raw differ diff --git a/resources/diffused.raw b/resources/diffused.raw new file mode 100644 index 0000000..82be6ac Binary files /dev/null and b/resources/diffused.raw differ diff --git a/resources/flash.raw b/resources/flash.raw new file mode 100644 index 0000000..f8051c1 Binary files /dev/null and b/resources/flash.raw differ diff --git a/resources/high-1.raw b/resources/high-1.raw new file mode 100644 index 0000000..7d267fd Binary files /dev/null and b/resources/high-1.raw differ diff --git a/resources/high-3.raw b/resources/high-3.raw new file mode 100644 index 0000000..2e6aaec Binary files /dev/null and b/resources/high-3.raw differ diff --git a/resources/high-6.raw b/resources/high-6.raw new file mode 100644 index 0000000..fc55b28 Binary files /dev/null and b/resources/high-6.raw differ diff --git a/resources/incorrect.raw b/resources/incorrect.raw new file mode 100644 index 0000000..434755d Binary files /dev/null and b/resources/incorrect.raw differ diff --git a/resources/low-1.raw b/resources/low-1.raw new file mode 100644 index 0000000..80f8f07 Binary files /dev/null and b/resources/low-1.raw differ diff --git a/resources/low-3.raw b/resources/low-3.raw new file mode 100644 index 0000000..4df949a Binary files /dev/null and b/resources/low-3.raw differ diff --git a/resources/low-6.raw b/resources/low-6.raw new file mode 100644 index 0000000..3394c6c Binary files /dev/null and b/resources/low-6.raw differ diff --git a/resources/partdone.raw b/resources/partdone.raw new file mode 100644 index 0000000..6b3c0e9 Binary files /dev/null and b/resources/partdone.raw differ diff --git a/resources/piano.raw b/resources/piano.raw new file mode 100644 index 0000000..7a94283 Binary files /dev/null and b/resources/piano.raw differ diff --git a/resources/ready.raw b/resources/ready.raw new file mode 100644 index 0000000..6aa4d58 Binary files /dev/null and b/resources/ready.raw differ diff --git a/resources/startup.raw b/resources/startup.raw new file mode 100644 index 0000000..2fda0d5 Binary files /dev/null and b/resources/startup.raw differ diff --git a/resources/stepdone.raw b/resources/stepdone.raw new file mode 100644 index 0000000..3b153fc Binary files /dev/null and b/resources/stepdone.raw differ diff --git a/resources/tetris.raw b/resources/tetris.raw new file mode 100644 index 0000000..3d9675b Binary files /dev/null and b/resources/tetris.raw differ