blk_box_tc/main/steps/step5.cpp

909 lines
36 KiB
C++

#include "step5.h"
#define TIME_CLEAR 30'000
#define TIME_PLANK 40'000
#define TIME_EMPTY 40'000
#define TIME_NOTHING 25'000
#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))
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<int>& input_options, const int num, const uint32_t color) {
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);
led_set(input_options[led], color);
input_options.erase(input_options.begin() + led);
}
}
void set_unique_leds_random_color(std::vector<int>& input_options, const int num, const uint32_t* COLORS, size_t COLORS_len) {
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, COLORS_len - 1);
int color = led_color_dist(gen);
led_set(input_options[led], COLORS[color]);
input_options.erase(input_options.begin() + led);
}
}
std::vector<int> unique_values(std::vector<int>& input_options, int num) {
std::vector<int> 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<int, 4> indicator_numbers, std::array<int, 4> 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) {
StarCodeEntry star_code = {
.code = "*2648",
.display_text = "Starting...",
.delay_ticks = pdMS_TO_TICKS(2000),
.callback = nullptr, // TODO
};
add_star_code(star_code);
std::vector<int> all_leds;
for (int i = 0; i < 21; i++) {
all_leds.push_back(i);
}
const uint32_t COLORS[] = {
LEDColor::LED_COLOR_RED,
LEDColor::LED_COLOR_BLUE,
LEDColor::LED_COLOR_GREEN,
LEDColor::LED_COLOR_YELLOW,
LEDColor::LED_COLOR_PINK,
LEDColor::LED_COLOR_WHITE,
};
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<int> led_options = all_leds;
set_unique_leds_random_color(led_options, led_number_dist(gen), COLORS, sizeof(COLORS)/sizeof(COLORS[0]));
leds_flush();
last_cycle_tick = xTaskGetTickCount();
scrambled_times++;
}
}
clean_bomb();
int solved_puzzles = 0;
while (solved_puzzles < TIMES_TO_SOLVE) {
lcd_set_cursor_pos(1, 1);
bool solved_correctly = false;
int puzzle = puzzle_dist(gen);
switch (puzzle) {
case 0: {
lcd_print("Clear");
set_module_time(TIME_CLEAR);
start_module_timer();
std::vector<int> 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, LEDColor::LED_COLOR_GREEN);
// set non-green
const uint32_t NON_GREEN_COLORS[] = {
LEDColor::LED_COLOR_RED,
LEDColor::LED_COLOR_BLUE,
LEDColor::LED_COLOR_PINK,
};
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_COLORS, sizeof(NON_GREEN_COLORS)/sizeof(NON_GREEN_COLORS[0]));
leds_flush();
// wait for submit
KeypadKey key;
while (1) {
if (get_module_time() <= 0 || (get_keypad_pressed(&key) && (char_of_keypad_key(key) == '#'))) {
solved_correctly = submit_0(green_indicators);
break;
}
vTaskDelay(pdMS_TO_TICKS(10));
}
break;
}
case 1: {
lcd_print("Blank");
set_module_time(TIME_BLANK);
start_module_timer();
std::uniform_int_distribution<> on_indicators_dist(16, 21);
uint8_t indicators_num = on_indicators_dist(gen);
std::vector<int> indicator_options = all_leds;
set_unique_leds_random_color(indicator_options, indicators_num, COLORS, sizeof(COLORS)/sizeof(COLORS[0]));
leds_flush();
uint8_t starting_switch_state = get_switch_state();
std::string pressed_keys;
KeypadKey key;
while (1) {
if (get_keypad_pressed(&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(TIME_EMPTY);
start_module_timer();
std::map<int, int> 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<bool>(lit_led_dist(gen)), static_cast<bool>(lit_led_dist(gen)), static_cast<bool>(lit_led_dist(gen)), static_cast<bool>(lit_led_dist(gen)), static_cast<bool>(lit_led_dist(gen))};
for (int i = 0; i < 5; i++) {
if (lit_leds[i]) {
int color = led_color_dist(gen);
led_set(idx_to_led_map[i], COLORS[color]);
}
}
leds_flush();
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_button_pressed(&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_keypad_pressed(&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("Nothing");
set_module_time(TIME_NOTHING);
start_module_timer();
const uint32_t COLORS[] = {
LEDColor::LED_COLOR_GREEN,
LEDColor::LED_COLOR_RED,
LEDColor::LED_COLOR_YELLOW,
LEDColor::LED_COLOR_BLUE,
};
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);
led_set(IndicatorLED::LED_TFT, COLORS[tft_color]);
led_set(IndicatorLED::LED_SPEAKER, COLORS[speaker_color]);
led_set(IndicatorLED::LED_S3, COLORS[s3_color]);
leds_flush();
int buttons_pressed = 0;
ButtonKey button;
while (1) {
if (get_button_pressed(&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("Blink");
set_module_time(TIME_BLINK);
start_module_timer();
// buttons
const uint32_t BUTTON_COLORS[] = {
LEDColor::LED_COLOR_GREEN,
LEDColor::LED_COLOR_RED,
LEDColor::LED_COLOR_YELLOW,
LEDColor::LED_COLOR_BLUE,
};
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++) {
led_set(IndicatorLED::LED_B1 - i, BUTTON_COLORS[button_colors[i]]);
}
// switches
const uint32_t SWITCH_COLOR[] = {
LEDColor::LED_COLOR_RED,
LEDColor::LED_COLOR_GREEN,
LEDColor::LED_COLOR_YELLOW,
};
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++) {
led_set(IndicatorLED::LED_S1 - i, SWITCH_COLOR[switch_colors[i]]);
}
leds_flush();
ButtonKey button;
KeypadKey key;
uint8_t starting_switch_state = get_switch_state();
while (1) {
if (get_button_pressed(&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;
}
led_set(IndicatorLED::LED_B1 - i, BUTTON_COLORS[button_colors[i]]);
}
}
leds_flush();
}
if (get_module_time() <= 0 || (get_keypad_pressed(&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("Ummm");
set_module_time(TIME_UMMM);
start_module_timer();
std::uniform_int_distribution<> indicator_number_dist(0, 5);
const uint32_t COLORS[] = {
LEDColor::LED_COLOR_GREEN,
LEDColor::LED_COLOR_RED,
LEDColor::LED_COLOR_YELLOW,
LEDColor::LED_COLOR_BLUE,
};
// green, red, yellow, blue
std::array<int, 4> indicator_numbers = {indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen), indicator_number_dist(gen)};
std::vector<int> indicator_options = all_leds;
for (int i = 0; i < 4; i++) {
set_unique_leds(indicator_options, indicator_numbers[i], COLORS[i]);
}
leds_flush();
std::array<int, 4> buttons_pressed = {0, 0, 0, 0};
ButtonKey button;
KeypadKey key;
while (1) {
if (get_button_pressed(&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_keypad_pressed(&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("Plank");
set_module_time(TIME_PLANK);
start_module_timer();
std::uniform_int_distribution<> led_color_dist(0, 5);
std::uniform_int_distribution<> led_off_dist(-1, 3);
const uint32_t COLORS[] = {
LEDColor::LED_COLOR_RED,
LEDColor::LED_COLOR_PINK,
LEDColor::LED_COLOR_BLUE,
LEDColor::LED_COLOR_WHITE,
LEDColor::LED_COLOR_GREEN,
LEDColor::LED_COLOR_YELLOW,
};
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);
led_set(IndicatorLED::LED_B1 - i, COLORS[button_colors[i]]);
buttons_cycling[i] = true;
} else {
button_colors[i] = -1;
buttons_cycling[i] = false;
}
}
leds_flush();
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_button_pressed(&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_set(IndicatorLED::LED_B1 - i, COLORS[CORRECT_COLORS[i]]);
leds_flush();
}
} 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 (uint32_t i = 0; i < 4; i++) {
if (buttons_cycling[i]) {
button_colors[i]++;
if (button_colors[i] > 5) {
button_colors[i] = 0;
}
led_set(IndicatorLED::LED_B1 - i, COLORS[button_colors[i]]);
}
}
leds_flush();
lastCycleTime = xTaskGetTickCount();
}
if (get_module_time() <= 0 || (get_keypad_pressed(&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("What");
set_module_time(TIME_WHAT);
start_module_timer();
std::uniform_int_distribution<> math_number_dist(1, 9);
std::vector<float> math_numbers;
std::vector<int> math_operations;
std::map<int, char> operation_map = {
{0, '+'},
{1, '-'},
{2, '*'},
{3, '/'},
};
int expression_answer = -1;
std::string display_expression;
while (expression_answer < 0) {
math_numbers = {static_cast<float>(math_number_dist(gen)), static_cast<float>(math_number_dist(gen)), static_cast<float>(math_number_dist(gen)), static_cast<float>(math_number_dist(gen))};
std::vector<int> possible_math_operations = {0, 1, 2, 3};
math_operations = unique_values(possible_math_operations, 3);
display_expression = std::to_string(static_cast<int>(math_numbers[0]));
for (int i = 0; i < 3; i++) {
display_expression += operation_map[math_operations[i]];
display_expression += std::to_string(static_cast<int>(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<int>(std::floor(math_numbers[0]));
}
// display expression
lcd_print(1, 2, 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<int> led_options = all_leds;
for (int i = 0; i < 4; i++) {
set_unique_leds(led_options, modifier_indicators[i], COLORS[i]);
}
leds_flush();
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_keypad_pressed(&key)) {
if (key == KeypadKey::star) {
// clear
entered_string = "";
} else if (key == KeypadKey::pound) {
// submit
if (entered_string != answer_string) {
strike("Incorrect answer!");
} else {
solved_correctly = true;
}
break;
} else {
entered_string += char_of_keypad_key(key);
}
lcd_clear();
lcd_print(1, 1, "What");
lcd_print(1, 2, display_expression.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;
}
case 8: {
lcd_print("Plink");
set_module_time(TIME_PLINK);
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);
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)};
std::vector<int> 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<int, std::string> 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;
}
}
}
stop_module_timer();
if (solved_correctly) {
solved_puzzles++;
play_clip_wav(MOUNT_POINT "/partdone.wav", true, false, 0, 0);
vTaskDelay(pdMS_TO_TICKS(500));
solved_correctly = false;
} else {
vTaskDelay(pdMS_TO_TICKS(3000));
}
play_clip_wav(MOUNT_POINT "/stepdone.wav", true, false, 1, 0);
clean_bomb();
}
}