blk_box_tc/main/steps/step3.cpp
2024-08-12 13:41:40 -05:00

957 lines
42 KiB
C++

#include "step3.h"
static const char *TAG = "step3";
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 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<int>& 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<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;
}
void step3(void) {
set_module_time(20000);
start_module_timer();
// wait
while (get_module_time() > 0) {
vTaskDelay(10);
}
std::vector<int> 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, 5};
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<int> 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 < 3) {
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(15000);
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, 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(30000);
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;
const int INDICATOR_RED[6] = {20, 0, 0, 10, 10, 5};
const int INDICATOR_GREEN[6] = {0, 0, 10, 5, 0, 5};
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(30000);
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(20000);
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(30000);
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(30000);
start_module_timer();
std::uniform_int_distribution<> indicator_number_dist(0, 5);
const int INDICATOR_RED[4] = {0, 20, 10, 10};
const int INDICATOR_GREEN[4] = {10, 0, 5, 5};
const int INDICATOR_BLUE[4] = {0, 0, 0, 10};
// 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], INDICATOR_RED[i], INDICATOR_GREEN[i], INDICATOR_BLUE[i]);
}
ESP_ERROR_CHECK(led_strip_refresh(leds));
std::array<int, 4> 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, 5, 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(40000);
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_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<int>(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<int> 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(15000);
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<int> 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<int, std::string> 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();
}
}