#include "step5.h" __attribute__((unused)) static const char *TAG = "step5"; static const int TIMES_TO_SOLVE = 9; static std::random_device rd; static std::mt19937 gen(rd()); static std::uniform_int_distribution<> puzzle_dist(0, 7); static std::uniform_int_distribution<> led_picker_dist(0, 20); static std::uniform_int_distribution<> led_color_dist(0, 5); void set_unique_leds(std::vector& input_options, const int num, const int r, const int g, const int b) { for (int i = 0; i < num; i++) { std::uniform_int_distribution<> led_option_dist(0, input_options.size() - 1); int led = led_option_dist(gen); ESP_ERROR_CHECK(led_strip_set_pixel(leds, input_options[led], r, g, b)); input_options.erase(input_options.begin() + led); } } void set_unique_leds_random_color(std::vector& input_options, const int num, const int* r, const int* g, const int* b) { for (int i = 0; i < num; i++) { std::uniform_int_distribution<> led_option_dist(0, input_options.size() - 1); int led = led_option_dist(gen); std::uniform_int_distribution<> led_color_dist(0, sizeof(r) - 1); int color = led_color_dist(gen); ESP_ERROR_CHECK(led_strip_set_pixel(leds, input_options[led], r[color], g[color], b[color])); input_options.erase(input_options.begin() + led); } } std::vector unique_values(std::vector& input_options, int num) { std::vector output_vec; for (int i = 0; i < num; i++) { std::uniform_int_distribution<> option_num_dist(0, input_options.size() - 1); int option_num = option_num_dist(gen); output_vec.push_back(input_options[option_num]); input_options.erase(input_options.begin() + option_num); } return output_vec; } bool submit_0(int green_indicators) { uint8_t state = get_switch_state(); uint8_t flipped_state = 0; flipped_state |= (state & 0b1) << 3; flipped_state |= (state & 0b10) << 1; flipped_state |= (state & 0b100) >> 1; flipped_state |= (state & 0b1000) >> 3; if (flipped_state == green_indicators) { return true; } else { strike("Incorrect Switches"); return false; } } bool submit_1(int num_indicators, std::string pressed_keys, uint8_t starting_switch_state) { if (num_indicators < 18) { if (get_switch_state() == 0b1111) { if (pressed_keys == "") { return true; } else { strike("Incorrect keypad!"); return false; } } else { strike("Incorrect switches!"); return false; } } else { if (starting_switch_state == get_switch_state()) { if (pressed_keys == "ADCB") { return true; } else { strike("Incorrect keypad!"); return false; } } else { strike("Switches changed!"); return false; } } } bool submit_2(bool* lit_leds, int green_pressed, int blue_pressed, int fingerprint_pressed, std::string keypad_string) { uint8_t switch_state = get_switch_state() & 0b11; bool rfid_correct = (lit_leds[0] && (green_pressed == 1)) || (!lit_leds[0] && (green_pressed == 0)); ESP_LOGI(TAG, "rfid_correct: %i", rfid_correct); bool lcd_correct = (lit_leds[1] && (blue_pressed == 1)) || (!lit_leds[1] && (blue_pressed == 0)); ESP_LOGI(TAG, "lcd_correct: %i", lcd_correct); bool speaker_correct = (lit_leds[2] && (fingerprint_pressed == 2)) || (!lit_leds[2] && (fingerprint_pressed == 0)); ESP_LOGI(TAG, "speaker_correct: %i", speaker_correct); bool keypad_correct = (lit_leds[3] && (keypad_string == "12")) || (!lit_leds[3] && (keypad_string == "")); ESP_LOGI(TAG, "keypad_correct: %i", keypad_correct); bool tft_correct = (lit_leds[4] && (switch_state == 0b11)) || !lit_leds[4]; ESP_LOGI(TAG, "tft_correct: %i", tft_correct); if (rfid_correct && lcd_correct && speaker_correct && keypad_correct && tft_correct) { return true; } else { strike("Incorrect state!"); return false; } } bool submit_4(int* button_colors, int* switch_colors, uint8_t initial_switch_state) { if (button_colors[0] == 0 && button_colors[1] == 1 && button_colors[2] == 2 && button_colors[3] == 3) { uint8_t switch_state = get_switch_state(); bool correct = true; for (int i = 0; i < 4; i++) { if (switch_colors[i] == 2) { if ((((switch_state ^ initial_switch_state) >> i) & 0b1) != 1) { correct = false; break; } } else { if (((switch_state >> i) & 0b1) != (switch_colors[i] & 0b1)) { correct = false; break; } } } if (correct) { return true; } strike("Incorrect switches!"); return false; } else { strike("Incorrect buttons!"); return false; } } bool submit_5(std::array indicator_numbers, std::array buttons_pressed) { if (buttons_pressed != indicator_numbers) { ESP_LOGI(TAG, "Button State: %i, %i, %i, %i, Indicator Numbers: %i, %i, %i, %i", buttons_pressed[0], buttons_pressed[1], buttons_pressed[2], buttons_pressed[3], indicator_numbers[0], indicator_numbers[1], indicator_numbers[2], indicator_numbers[3]); strike("Wrong button state!"); return false; } uint8_t switch_state = get_switch_state(); for (int i = 0; i < 4; i++) { ESP_LOGI(TAG, "Switch State: %i, Indicator Number: %i", ((switch_state >> i) & 0b1), indicator_numbers[i]); if (((switch_state >> i) & 0b1) == (indicator_numbers[i] & 0b1)) { strike("Wrong switch state!"); return false; } } return true; } bool submit_6(bool* buttons_cycling, bool button_turned_on, int led_off) { for (int i = 0; i < sizeof(buttons_cycling); i++) { if ((buttons_cycling[i] == true) || (button_turned_on == false && led_off != -1)) { strike("Incorrect!"); return false; } } return true; } void step5(void) { StarCodeHandler star_codes[] = { { .code = "*2648", .display_text = "Starting...", .should_exit = true, .callback = nullptr, }, }; int len = sizeof(star_codes)/sizeof(StarCodeHandler); do_star_codes(star_codes, len); std::vector all_leds; for (int i = 0; i < 21; i++) { all_leds.push_back(i); } const int INDICATOR_RED[6] = {20, 0, 0, 10, 10, 5}; const int INDICATOR_GREEN[6] = {0, 0, 10, 5, 0, 7}; const int INDICATOR_BLUE[6] = {0, 10, 0, 0, 5, 5}; static std::uniform_int_distribution<> led_number_dist(0, 21); int last_cycle_tick = xTaskGetTickCount(); int scrambled_times = 0; while (scrambled_times < 5) { if ((xTaskGetTickCount() - last_cycle_tick) > pdMS_TO_TICKS(100)) { clean_bomb(); std::vector led_options = all_leds; set_unique_leds_random_color(led_options, led_number_dist(gen), INDICATOR_RED, INDICATOR_GREEN, INDICATOR_BLUE); ESP_ERROR_CHECK(led_strip_refresh(leds)); last_cycle_tick = xTaskGetTickCount(); scrambled_times++; } } clean_bomb(); int solved_puzzles = 0; while (solved_puzzles < TIMES_TO_SOLVE) { lcd_set_cursor(&lcd, 1, 1); bool solved_correctly = false; int puzzle = puzzle_dist(gen); // int puzzle = 2; switch (puzzle) { case 0: { lcd_print(&lcd, "Clear"); set_module_time(30000); start_module_timer(); std::vector indicator_options = all_leds; // set green std::uniform_int_distribution<> green_indicators_dist(1, 15); uint8_t green_indicators = green_indicators_dist(gen); set_unique_leds(indicator_options, green_indicators, 0, 10, 0); // set non-green const int NON_GREEN_INDICATOR_RED[3] = {20, 0, 10}; const int NON_GREEN_INDICATOR_GREEN[3] = {0, 0, 0}; const int NON_GREEN_INDICATOR_BLUE[3] = {0, 10, 5}; std::uniform_int_distribution<> non_green_indicators_dist(0, (20 - green_indicators)); set_unique_leds_random_color(indicator_options, non_green_indicators_dist(gen), NON_GREEN_INDICATOR_RED, NON_GREEN_INDICATOR_GREEN, NON_GREEN_INDICATOR_BLUE); ESP_ERROR_CHECK(led_strip_refresh(leds)); // wait for submit KeypadKey key; while (1) { if (get_module_time() <= 0 || (get_pressed_keypad(&key) && (char_of_keypad_key(key) == '#'))) { solved_correctly = submit_0(green_indicators); break; } vTaskDelay(pdMS_TO_TICKS(10)); } break; } case 1: { lcd_print(&lcd, "Blank"); set_module_time(40000); start_module_timer(); std::uniform_int_distribution<> on_indicators_dist(16, 21); uint8_t indicators_num = on_indicators_dist(gen); std::vector indicator_options = all_leds; const int INDICATOR_RED[6] = {20, 0, 0, 10, 10, 5}; const int INDICATOR_GREEN[6] = {0, 0, 10, 5, 0, 7}; const int INDICATOR_BLUE[6] = {0, 10, 0, 0, 5, 5}; set_unique_leds_random_color(indicator_options, indicators_num, INDICATOR_RED, INDICATOR_BLUE, INDICATOR_GREEN); ESP_ERROR_CHECK(led_strip_refresh(leds)); uint8_t starting_switch_state = get_switch_state(); std::string pressed_keys; KeypadKey key; while (1) { if (get_pressed_keypad(&key)) { char keypad_char = char_of_keypad_key(key); if (keypad_char == '#') { solved_correctly = submit_1(indicators_num, pressed_keys, starting_switch_state); break; } else { pressed_keys += char_of_keypad_key(key); } } if (get_module_time() <= 0) { solved_correctly = submit_1(indicators_num, pressed_keys, starting_switch_state); break; } vTaskDelay(pdMS_TO_TICKS(10)); } break; } case 2: { set_module_time(40000); start_module_timer(); std::map idx_to_led_map = { {0, 10}, {1, 12}, {2, 9}, {3, 11}, {4, 6}, }; std::uniform_int_distribution<> lit_led_dist(0, 1); // rfid, lcd, speaker, keypad, tft bool lit_leds[5] = {static_cast(lit_led_dist(gen)), static_cast(lit_led_dist(gen)), static_cast(lit_led_dist(gen)), static_cast(lit_led_dist(gen)), static_cast(lit_led_dist(gen))}; for (int i = 0; i < 5; i++) { if (lit_leds[i]) { int color = led_color_dist(gen); ESP_ERROR_CHECK(led_strip_set_pixel(leds, idx_to_led_map[i], INDICATOR_RED[color], INDICATOR_GREEN[color], INDICATOR_BLUE[color])); } } ESP_ERROR_CHECK(led_strip_refresh(leds)); int green_button_pressed = 0; int blue_button_pressed = 0; int fingerprint_sensor_pressed = 0; std::string keypad_string; KeypadKey key; ButtonKey button; while (1) { if (get_pressed_button(&button)) { uint8_t button_state = get_button_state(); if ((button_state & 0b1) == 0b1) { green_button_pressed++; if ((green_button_pressed > 1) || !lit_leds[0]) { strike("Too many times!"); break; } } if ((button_state & 0b1000) == 0b1000) { blue_button_pressed++; if ((blue_button_pressed > 1) || !lit_leds[1]) { strike("Too many times!"); break; } } } if (get_touch_pressed()) { fingerprint_sensor_pressed++; // ESP_LOGI(TAG, "touch sensor pressed"); if ((fingerprint_sensor_pressed > 2) || !lit_leds[2]) { strike("Too many times!"); break; } } if (get_pressed_keypad(&key)) { char keypad_char = char_of_keypad_key(key); if (keypad_char == '#') { solved_correctly = submit_2(lit_leds, green_button_pressed, blue_button_pressed, fingerprint_sensor_pressed, keypad_string); break; } else { // ESP_LOGI(TAG, "pressed %c", char_of_keypad_key(key)); keypad_string += char_of_keypad_key(key); } } if (get_module_time() <= 0) { solved_correctly = submit_2(lit_leds, green_button_pressed, blue_button_pressed, fingerprint_sensor_pressed, keypad_string); break; } vTaskDelay(pdMS_TO_TICKS(10)); } break; } case 3: { lcd_print(&lcd, "Nothing"); set_module_time(25000); start_module_timer(); const int COLOR_RED[5] = {0, 20, 10, 0}; const int COLOR_GREEN[5] = {20, 0, 10, 0}; const int COLOR_BLUE[5] = {0, 0, 0, 20}; static std::uniform_int_distribution<> color_dist(0, 3); int tft_color = color_dist(gen); int speaker_color = color_dist(gen); int s3_color = color_dist(gen); ESP_ERROR_CHECK(led_strip_set_pixel(leds, 6, COLOR_RED[tft_color], COLOR_GREEN[tft_color], COLOR_BLUE[tft_color])); ESP_ERROR_CHECK(led_strip_set_pixel(leds, 9, COLOR_RED[speaker_color], COLOR_GREEN[speaker_color], COLOR_BLUE[speaker_color])); ESP_ERROR_CHECK(led_strip_set_pixel(leds, 14, COLOR_RED[s3_color], COLOR_GREEN[s3_color], COLOR_BLUE[s3_color])); ESP_ERROR_CHECK(led_strip_refresh(leds)); int buttons_pressed = 0; ButtonKey button; while (1) { if (get_pressed_button(&button)) { buttons_pressed++; uint8_t button_state = get_button_state(); if (buttons_pressed == 1) { if ((button_state >> tft_color) != 0b1) { strike("Wrong button!"); break; } } else if (buttons_pressed == 2) { if ((button_state >> speaker_color) != 0b1) { strike("Wrong button!"); break; } } else if (buttons_pressed == 3) { if ((button_state >> s3_color) != 0b1) { strike("Wrong button!"); } else { solved_correctly = true; break; } } } if (get_module_time() <= 0) { strike("Ran out of time!"); break; } vTaskDelay(pdMS_TO_TICKS(10)); } break; } case 4: { lcd_print(&lcd, "Blink"); set_module_time(35000); start_module_timer(); // buttons const int BUTTON_COLOR_RED[4] = {0, 20, 10, 0}; const int BUTTON_COLOR_GREEN[4] = {10, 0, 5, 0}; const int BUTTON_COLOR_BLUE[4] = {0, 0, 0, 10}; static std::uniform_int_distribution<> button_color_dist(0, 3); int button_colors[4] = {button_color_dist(gen), button_color_dist(gen), button_color_dist(gen), button_color_dist(gen)}; for (int i = 0; i < 4; i++) { ESP_ERROR_CHECK(led_strip_set_pixel(leds, (20 - i), BUTTON_COLOR_RED[button_colors[i]], BUTTON_COLOR_GREEN[button_colors[i]], BUTTON_COLOR_BLUE[button_colors[i]])); } // switches const int SWITCH_COLOR_RED[3] = {20, 0, 10}; const int SWITCH_COLOR_GREEN[3] = {0, 10, 5}; static std::uniform_int_distribution<> switch_color_dist(0, 2); int switch_colors[4] = {switch_color_dist(gen), switch_color_dist(gen), switch_color_dist(gen), switch_color_dist(gen)}; for (int i = 0; i < 4; i++) { ESP_ERROR_CHECK(led_strip_set_pixel(leds, (16 - i), SWITCH_COLOR_RED[switch_colors[i]], SWITCH_COLOR_GREEN[switch_colors[i]], 0)); } ESP_ERROR_CHECK(led_strip_refresh(leds)); ButtonKey button; KeypadKey key; uint8_t starting_switch_state = get_switch_state(); while (1) { if (get_pressed_button(&button)) { uint8_t button_state = get_button_state(); for (int i = 0; i < 4; i++) { if (((button_state >> i) & 0b1) == 0b1) { button_colors[i]++; if (button_colors[i] > 3) { button_colors[i] = 0; } ESP_ERROR_CHECK(led_strip_set_pixel(leds, (20 - i), BUTTON_COLOR_RED[button_colors[i]], BUTTON_COLOR_GREEN[button_colors[i]], BUTTON_COLOR_BLUE[button_colors[i]])); } } ESP_ERROR_CHECK(led_strip_refresh(leds)); } if (get_module_time() <= 0 || (get_pressed_keypad(&key) && (char_of_keypad_key(key) == '#'))) { solved_correctly = submit_4(button_colors, switch_colors, starting_switch_state); break; } vTaskDelay(pdMS_TO_TICKS(10)); } break; } case 5: { lcd_print(&lcd, "Ummm"); set_module_time(35000); start_module_timer(); std::uniform_int_distribution<> indicator_number_dist(0, 5); const int INDICATOR_RED[4] = {0, 20, 10, 0}; const int INDICATOR_GREEN[4] = {10, 0, 5, 0}; const int INDICATOR_BLUE[4] = {0, 0, 0, 10}; // green, red, yellow, blue std::array indicator_numbers = {indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen)}; std::vector indicator_options = all_leds; for (int i = 0; i < 4; i++) { set_unique_leds(indicator_options, indicator_numbers[i], INDICATOR_RED[i], INDICATOR_GREEN[i], INDICATOR_BLUE[i]); } ESP_ERROR_CHECK(led_strip_refresh(leds)); std::array buttons_pressed = {0, 0, 0, 0}; ButtonKey button; KeypadKey key; while (1) { if (get_pressed_button(&button)) { uint8_t button_state = get_button_state(); bool failed = false; for (int i = 0; i < 4; i++) { if (((button_state >> i) & 0b1) == 0b1) { buttons_pressed[i]++; if (buttons_pressed[i] > indicator_numbers[i]) { strike("Too many times!"); failed = true; break; } } } if (failed) { break; } } if (get_module_time() <= 0 || (get_pressed_keypad(&key) && (char_of_keypad_key(key) == '#'))) { ESP_LOGI(TAG, "Keypad Char: %c, time: %lu", char_of_keypad_key(key), get_module_time()); solved_correctly = submit_5(indicator_numbers, buttons_pressed); break; } vTaskDelay(pdMS_TO_TICKS(10)); } break; } case 6: { lcd_print(&lcd, "Plank"); set_module_time(40000); start_module_timer(); std::uniform_int_distribution<> led_color_dist(0, 5); std::uniform_int_distribution<> led_off_dist(-1, 3); // red, purple, blue, white, green, yellow const uint8_t COLORS_RED[6] = {20, 10, 0, 5, 0, 10}; const uint8_t COLORS_GREEN[6] = {0, 0, 0, 7, 10, 5}; const uint8_t COLORS_BLUE[6] = {0, 10, 10, 5, 0, 0}; int button_colors[4]; bool buttons_cycling[4]; int led_off = led_off_dist(gen); for (int i = 0; i < 4; i++) { if (led_off != i) { button_colors[i] = led_color_dist(gen); ESP_ERROR_CHECK(led_strip_set_pixel(leds, (20 - i), COLORS_RED[button_colors[i]], COLORS_GREEN[button_colors[i]], COLORS_BLUE[button_colors[i]])); buttons_cycling[i] = true; } else { button_colors[i] = -1; buttons_cycling[i] = false; } } ESP_ERROR_CHECK(led_strip_refresh(leds)); const uint8_t CORRECT_COLORS[4] = {4, 0, 5, 2}; TickType_t lastCycleTime = xTaskGetTickCount(); bool button_turned_on = false; ButtonKey button; KeypadKey key; std::uniform_int_distribution<> led_turn_on_dist(0, 3); while (1) { if (get_pressed_button(&button)) { uint8_t button_state = get_button_state(); bool failed = false; for (int i = 0; i < 4; i++) { if (((button_state >> i) & 0b1) == 0b1) { if (button_colors[i] == -1) { if (button_turned_on) { strike("Pressed after on!"); failed = true; break; } else if (led_turn_on_dist(gen) == 0) { button_turned_on = true; led_strip_set_pixel(leds, (20 - i), COLORS_RED[CORRECT_COLORS[i]], COLORS_GREEN[CORRECT_COLORS[i]], COLORS_BLUE[CORRECT_COLORS[i]]); led_strip_refresh(leds); } } else if (button_colors[i] != CORRECT_COLORS[i]) { strike("Wrong time!"); failed = true; break; } else { buttons_cycling[i] = false; } } } if (failed) { break; } } if ((xTaskGetTickCount() - lastCycleTime) >= pdMS_TO_TICKS(500)) { for (int i = 0; i < 4; i++) { if (buttons_cycling[i]) { button_colors[i]++; if (button_colors[i] > 5) { button_colors[i] = 0; } ESP_ERROR_CHECK(led_strip_set_pixel(leds, (20 - i), COLORS_RED[button_colors[i]], COLORS_GREEN[button_colors[i]], COLORS_BLUE[button_colors[i]])); } } ESP_ERROR_CHECK(led_strip_refresh(leds)); lastCycleTime = xTaskGetTickCount(); } get_pressed_keypad(&key); if (get_module_time() <= 0 || (get_pressed_keypad(&key) && (char_of_keypad_key(key) == '#'))) { solved_correctly = submit_6(buttons_cycling, button_turned_on, led_off); break; } vTaskDelay(pdMS_TO_TICKS(10)); } break; } case 7: { lcd_print(&lcd, "What"); set_module_time(55000); 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_set_cursor(&lcd, 1, 2); lcd_print(&lcd, display_expression.c_str()); // set LEDs // blue, red, green, yellow const int INDICATOR_RED[4] = {0, 20, 0, 10}; const int INDICATOR_GREEN[4] = {0, 0, 10, 5}; const int INDICATOR_BLUE[4] = {10, 0, 0, 0}; 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 < 4; i++) { set_unique_leds(led_options, modifier_indicators[i], INDICATOR_RED[i], INDICATOR_GREEN[i], INDICATOR_BLUE[i]); } ESP_ERROR_CHECK(led_strip_refresh(leds)); std::string answer_string = std::to_string(expression_answer); std::string entered_string = ""; ESP_LOGI(TAG, "Solved full answer: %s", answer_string.c_str()); KeypadKey key; while (1) { if (get_pressed_keypad(&key)) { if (key == KeypadKey::star) { // clear entered_string = ""; } else if (key == KeypadKey::pound) { // submit if (entered_string != answer_string) { strike("Incorrect answer!"); break; } else { solved_correctly = true; } break; } else { entered_string += char_of_keypad_key(key); } lcd_clear(&lcd); lcd_set_cursor(&lcd, 1, 1); lcd_print(&lcd, "What"); lcd_set_cursor(&lcd, 1, 2); lcd_print(&lcd, display_expression.c_str()); lcd_set_cursor(&lcd, 1, 3); lcd_print(&lcd, entered_string.c_str()); } if (get_module_time() <= 0) { strike("Ran out of time!"); break; } vTaskDelay(pdMS_TO_TICKS(10)); } break; } case 8: { lcd_print(&lcd, "Plink"); set_module_time(40000); start_module_timer(); 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); // green, red, yellow, blue, purple const int INDICATOR_RED[5] = {0, 20, 10, 0, 10}; const int INDICATOR_GREEN[5] = {10, 0, 5, 0, 0}; const int INDICATOR_BLUE[5] = {0, 0, 0, 10, 5}; 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], INDICATOR_RED[i], INDICATOR_GREEN[i], INDICATOR_BLUE[i]); } ESP_ERROR_CHECK(led_strip_refresh(leds)); std::uniform_int_distribution<> answer_color_dist(0, 4); std::map color_name_map = { {0, "Green"}, {1, "Red"}, {2, "Yellow"}, {3, "Blue"}, {4, "Purple"}, }; 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_set_cursor(&lcd, 1, 2); lcd_print(&lcd, color_string.c_str()); std::string entered_string; KeypadKey key; while (1) { if (get_pressed_keypad(&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); lcd_set_cursor(&lcd, 1, 1); lcd_print(&lcd, "Plink"); lcd_set_cursor(&lcd, 1, 2); lcd_print(&lcd, color_string.c_str()); lcd_set_cursor(&lcd, 1, 3); lcd_print(&lcd, 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; } } } stop_module_timer(); if (solved_correctly) { solved_puzzles++; play_raw(MOUNT_POINT "/correct.pcm"); vTaskDelay(pdMS_TO_TICKS(500)); solved_correctly = false; } else { vTaskDelay(pdMS_TO_TICKS(3000)); } clear_all_pressed_released(); clean_bomb(); } }