#include "step5.h" 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; } 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 < ) { lcd_set_cursor(&lcd, 1, 1); int puzzle = puzzle_dist(gen); // int puzzle = 6; bool solved_correctly = false; 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] = {30, 0, 15}; const int NON_GREEN_INDICATOR_GREEN[3] = {0, 0, 0}; const int NON_GREEN_INDICATOR_BLUE[3] = {0, 30, 15}; 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 time while (1) { if (get_module_time() <= 0) { uint8_t state = get_switch_state(); uint8_t flipped_state = 0; flipped_state |= (state & 0x01) << 3; flipped_state |= (state & 0x02) << 1; flipped_state |= (state & 0x04) >> 1; flipped_state |= (state & 0x08) >> 3; if (flipped_state == green_indicators) { solved_puzzles++; } else { strike("Incorrect Switches"); } 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)); // ESP_LOGI(TAG, "puzzle 1 LEDs set (%i leds)", indicators_num); if (indicators_num < 18) { while (1) { if (get_module_time() <= 0) { if (get_switch_state() == 0b1111) { solved_puzzles++; // ESP_LOGI(TAG, "puzzle 1 solved (switches)!"); } else { strike("Switch State Changed"); } break; } vTaskDelay(pdMS_TO_TICKS(10)); } } else { uint8_t starting_switch_state = get_switch_state(); KeypadKey key; std::string pressed_keys; while (1) { if (get_pressed_keypad(&key)) { pressed_keys += char_of_keypad_key(key); // ESP_LOGI(TAG, "key %c pressed", char_of_keypad_key(key)); } if (get_module_time() <= 0) { if (starting_switch_state == get_switch_state()) { if (pressed_keys == "ADCB") { solved_puzzles++; solved_correctly = true; // ESP_LOGI(TAG, "puzzle 1 solved (keypad)!"); } } else { strike("Switches Changed!"); } break; } vTaskDelay(pdMS_TO_TICKS(10)); } } break; } case 2: { set_module_time(25000); start_module_timer(); std::uniform_int_distribution<> lit_led_dist(0, 1); bool rfid_lit = lit_led_dist(gen); bool lcd_lit = lit_led_dist(gen); bool speaker_lit = lit_led_dist(gen); bool keypad_lit = lit_led_dist(gen); bool tft_lit = lit_led_dist(gen); if (rfid_lit) { int color = led_color_dist(gen); ESP_ERROR_CHECK(led_strip_set_pixel(leds, 10, INDICATOR_RED[color], INDICATOR_GREEN[color], INDICATOR_BLUE[color])); } if (lcd_lit) { int color = led_color_dist(gen); ESP_ERROR_CHECK(led_strip_set_pixel(leds, 12, INDICATOR_RED[color], INDICATOR_GREEN[color], INDICATOR_BLUE[color])); } if (speaker_lit) { int color = led_color_dist(gen); ESP_ERROR_CHECK(led_strip_set_pixel(leds, 9, INDICATOR_RED[color], INDICATOR_GREEN[color], INDICATOR_BLUE[color])); } if (keypad_lit) { int color = led_color_dist(gen); ESP_ERROR_CHECK(led_strip_set_pixel(leds, 11, INDICATOR_RED[color], INDICATOR_GREEN[color], INDICATOR_BLUE[color])); } if (tft_lit) { int color = led_color_dist(gen); ESP_ERROR_CHECK(led_strip_set_pixel(leds, 6, INDICATOR_RED[color], INDICATOR_GREEN[color], INDICATOR_BLUE[color])); } ESP_ERROR_CHECK(led_strip_refresh(leds)); int green_button_pressed = 0; // ESP_LOGI(TAG, "green pressed: %i", green_button_pressed); int blue_button_pressed = 0; int fingerprint_sensor_pressed = 0; std::string keypad_string; ButtonKey button; KeypadKey key; SwitchKey switch1 = s1; SwitchKey switch2 = s2; while (1) { if (get_pressed_button(&button)) { uint8_t button_state = get_button_state(); // ESP_LOGI(TAG, "Button pressed! (%i)", button_state()); if ((button_state & 0b1) == 0b1) { green_button_pressed++; if ((green_button_pressed > 1) || !rfid_lit) { strike("Too many times!"); break; } } if ((button_state & 0b1000) == 0b1000) { blue_button_pressed++; if ((blue_button_pressed > 1) || !lcd_lit) { strike("Too many times!"); break; } } } if (get_touch_pressed()) { fingerprint_sensor_pressed++; if ((fingerprint_sensor_pressed > 2) || !speaker_lit) { strike("Too many times!"); break; } } if (get_pressed_keypad(&key)) { bool wrong = false; keypad_string += char_of_keypad_key(key); switch (keypad_string.length()) { case 1: { if (keypad_string != "1") { strike("Incorrect Keypad!"); wrong = true; } break; } case 2: { if (keypad_string != "12") { strike("Incorrect Keypad!"); wrong = true; } break; } default: { strike("Incorrect Keypad!"); wrong = true; break; } } if (wrong) { break; } } if (get_flipped_up_switch(&switch1) || get_flipped_up_switch(&switch2)) { if (!tft_lit) { strike("Incorrect Switches"); break; } } if (get_module_time() <= 0) { bool rfid_correct = !(rfid_lit && (green_button_pressed != 1)); bool lcd_correct = !(lcd_lit && (blue_button_pressed != 1)); bool speaker_correct = !(speaker_lit && (fingerprint_sensor_pressed != 2)); bool keypad_correct = !(keypad_lit && (keypad_string != "12")); bool tft_correct = !(tft_lit && ((get_switch_state() & 0b11) != 0b11)); if (rfid_correct && lcd_correct && speaker_correct && keypad_correct && tft_correct) { solved_puzzles++; solved_correctly = true; } else { strike("Incorrect state!"); } 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, 0}; const int COLOR_GREEN[5] = {20, 0, 10, 0, 0}; const int COLOR_BLUE[5] = {0, 0, 0, 20, 0}; static std::uniform_int_distribution<> color_dist(0, 4); 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_puzzles++; 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; SwitchKey switch_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 (button_colors[0] == 0 && button_colors[1] == 1 && button_colors[2] == 2 && button_colors[3] == 3) { // check switch state 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 ^ starting_switch_state) >> i) & 0b1) != 1) { correct = false; break; } } else { if (((switch_state >> i) & 0b1) != (switch_colors[i] & 0b1)) { correct = false; break; } } } if (correct) { solved_puzzles++; solved_correctly = true; break; } } } if (get_flipped_switch(&switch_key)) { if (button_colors[0] == 0 && button_colors[1] == 1 && button_colors[2] == 2 && button_colors[3] == 3) { // check switch state 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 ^ starting_switch_state) >> i) & 0b1) != 1) { correct = false; break; } } else { if (((switch_state >> i) & 0b1) != (switch_colors[i] & 0b1)) { correct = false; break; } } } if (correct) { solved_puzzles++; solved_correctly = true; break; } } } if (get_module_time() <= 0) { // check button state if (button_colors[0] == 0 && button_colors[1] == 1 && button_colors[2] == 2 && button_colors[3] == 3) { // check switch state uint8_t switch_state = get_switch_state(); bool correct = true; // ESP_LOGI(TAG, "starting switch state: %i, current switch state: %i", starting_switch_state, switch_state); for (int i = 0; i < 4; i++) { if (switch_colors[i] == 2) { // ESP_LOGI(TAG, "color yellow triggered: %i", (((switch_state ^ starting_switch_state) >> i) & 0b1)); if ((((switch_state ^ starting_switch_state) >> i) & 0b1) != 1) { correct = false; break; } } else { // ESP_LOGI(TAG, "color green or red triggered: %i != %i", ((switch_state >> i) & 0b1), (switch_colors[i] & 0b1)); if (((switch_state >> i) & 0b1) != (switch_colors[i] & 0b1)) { correct = false; break; } } } if (correct) { solved_puzzles++; solved_correctly = true; } else { strike("Wrong switch state!"); } } else { strike("Wrong button 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; 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) { buttons_pressed[i]++; if (buttons_pressed[i] > indicator_numbers[i]) { strike("Too many times!"); break; } } } } if (get_module_time() <= 0) { // check for correct button presses for (int i = 0; i < 4; i++) { if (buttons_pressed == indicator_numbers) { strike("Wrong button state!"); break; } } uint8_t switch_state = get_switch_state(); // check for correct switch states for (int i = 0; i < 4; i++) { if (((switch_state >> i) & 0b1) == (indicator_numbers[i] & 0b1)) { strike("Wrong switch state!"); break; } } solved_puzzles++; solved_correctly = true; 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; std::uniform_int_distribution<> led_turn_on_dist(0, 3); 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) { if (button_colors[i] == -1) { 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!"); break; } else { buttons_cycling[i] = false; } } } bool success = true; for (int i = 0; i < sizeof(buttons_cycling); i++) { if ((buttons_cycling[i] == true) || (button_turned_on == false && led_off != -1)) { success = false; break; } } if (success) { solved_puzzles++; solved_correctly = true; break; } } if ((xTaskGetTickCount() - lastCycleTime) >= pdMS_TO_TICKS(500)) { ESP_LOGI(TAG, "Cycling LEDs"); 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(); } if (get_module_time() <= 0) { bool success = true; for (int i = 0; i < sizeof(buttons_cycling); i++) { if ((buttons_cycling[i] == true) || (button_turned_on == false && led_off != -1)) { strike("Ran out of time!"); success = false; break; } } if (success) { solved_puzzles++; solved_correctly = true; } break; } vTaskDelay(pdMS_TO_TICKS(10)); } break; } case 7: { lcd_print(&lcd, "What"); set_module_time(50000); 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()); // ESP_LOGI(TAG, "Display expression: %s", display_expression.c_str()); // ESP_LOGI(TAG, "Solved expression answer: %i", static_cast(expression_answer)); // 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]) * (3 ^ modifier_indicators[2])) / (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 *= 3 ^ modifier_indicators[2]; expression_answer /= 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!"); } else { solved_puzzles++; 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)) { if (key == KeypadKey::star) { // clear entered_string = ""; } else if (key == KeypadKey::pound) { // submit if (entered_string != answer_num) { strike("Incorrect answer!"); } else { solved_times++; } break; } else { entered_string += char_of_keypad_key(key); } 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_puzzles++; solved_correctly = true; } } } stop_module_timer(); if (solved_correctly) { play_raw(MOUNT_POINT "/correct.pcm"); vTaskDelay(pdMS_TO_TICKS(500)); solved_correctly = false; } else { vTaskDelay(pdMS_TO_TICKS(3000)); } clean_bomb(); } }