#include "step2.h" __attribute__((unused)) static const char *TAG = "step2"; static const int NUM_SOLVES = 4; // one: 0b00000110 // seven: 0b00000111 static const uint8_t SSEG_NUMS[8] = {0b00111111, 0b01011011, 0b01001111, 0b01100110, 0b01101101, 0b01111101, 0b01111111, 0b01101111}; static const uint8_t SSEG_MAPS[5][4] = { {0b0101101, 0b1111010, 0b1000010, 0b1010100}, {0b01000101, 0b00100100, 0b00110110, 0b01111011}, {0b00101010, 0b00000010, 0b00010111, 0b00111100}, {0b00111000, 0b01010010, 0b00101011, 0b00111010}, {0b01000111, 0b00011001, 0b01111000, 0b00111110} }; static const uint32_t INDICATOR_COLORS[5] = { LEDColor::LED_COLOR_RED, LEDColor::LED_COLOR_BLUE, LEDColor::LED_COLOR_GREEN, LEDColor::LED_COLOR_YELLOW, LEDColor::LED_COLOR_WHITE, }; // random number generators static std::random_device rd; static std::mt19937 gen(rd()); static std::uniform_int_distribution<> answer_dist(0, 7); static std::uniform_int_distribution<> map_dist(0, 4); static std::uniform_int_distribution<> display_dist(0, 3); static std::uniform_int_distribution<> random_segment_dist(0, 127); static int answer = 0; static uint8_t answer_sseg = SSEG_NUMS[0]; static char answer_char = '0'; static uint8_t display_map[4] = {0b00000000, 0b00000000, 0b00000000, 0b00000000}; static int chosen_map = 0; std::map number_map = { {0, 0}, {1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 8}, {7, 9}, }; static void new_puzzle(void) { // scramble lights for (int i = 0; i < 5; i++) { led_set(IndicatorLED::LED_SPEAKER, INDICATOR_COLORS[map_dist(gen)]); leds_flush(); uint8_t random_segments[4] = {0, 0, 0, 0}; for (int i = 0; i < 4; i++) { random_segments[i] = random_segment_dist(gen); } set_module_sseg_raw(random_segments); vTaskDelay(pdMS_TO_TICKS(100)); } answer = answer_dist(gen); answer_sseg = SSEG_NUMS[answer]; // convert answer to number value to account for missing 1 and 7 answer = number_map[answer]; answer_char = '0' + answer; // ESP_LOGI(TAG, "Answer: %i", answer); chosen_map = map_dist(gen); for (int i = 0; i < 4; ++i) { display_map[i] = SSEG_MAPS[chosen_map][i]; } // ESP_LOGI(TAG, "Chosen Map: %i", chosen_map); led_set(IndicatorLED::LED_SPEAKER, INDICATOR_COLORS[chosen_map]); leds_flush(); for (int i = 0; i < 8; i++) { bool bit = (answer_sseg >> i) & 1; if (bit == 1) { // choose display and flip bit int display = display_dist(gen); display_map[display] ^= (1 << i); // ESP_LOGI(TAG, "Flipping bit %i on display %i", i, display); } } set_module_sseg_raw(display_map); } void step2(void) { KeypadKey key; int solved_times = 0; new_puzzle(); int strike_time = 0; while(solved_times < NUM_SOLVES) { // for every bit in the answer- if (get_keypad_pressed(&key)) { lcd_clear(); char c = char_of_keypad_key(key); // ESP_LOGI(TAG, "Pressed: %c", c); if (c == answer_char) { solved_times++; if (solved_times < NUM_SOLVES) { play_clip_wav(MOUNT_POINT "/partdone.wav", true, false, 0, 0); clean_bomb(); new_puzzle(); } else { play_clip_wav(MOUNT_POINT "/stepdone.wav", true, false, 1, 0); clear_module_sseg(); } } else { strike_time = xTaskGetTickCount(); strike("Incorrect Character!"); } } if (strike_time != 0 && xTaskGetTickCount() - strike_time > pdMS_TO_TICKS(5000)) { strike_time = 0; lcd_clear(); } vTaskDelay(pdMS_TO_TICKS(10)); } }