blk_box_tc/main/steps/step2.cpp
2025-04-04 23:52:48 -05:00

130 lines
3.8 KiB
C++

#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<int, int> 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));
}
}