blk_box_tc/main/steps/step3.cpp
2024-08-08 20:47:44 -05:00

340 lines
14 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);
static const int INDICATOR_RED[6] = {30, 0, 0, 25, 15, 10};
static const int INDICATOR_GREEN[6] = {0, 0, 30, 5, 0, 10};
static const int INDICATOR_BLUE[6] = {0, 30, 0, 0, 15, 10};
void step3(void) {
int solved_puzzles = 0;
while (solved_puzzles < 3) {
// int puzzle = puzzle_dist(gen);
int puzzle = 2;
switch (puzzle) {
case 0: {
lcd_print(&lcd, "Clear");
set_module_time(10000);
start_module_timer();
std::uniform_int_distribution<> green_indicators_dist(2, 15);
// create all green indicators
uint8_t green_indicators = green_indicators_dist(gen);
std::set<int> indicators;
// ESP_LOGI(TAG, "green indicators: %i", green_indicators);
while (indicators.size() < green_indicators) {
int led = led_picker_dist(gen);
indicators.insert(led);
// ESP_LOGI(TAG, "added green led at %i", led);
}
for (std::set<int>::iterator it = indicators.begin(); it != indicators.end(); it++) {
ESP_ERROR_CHECK(led_strip_set_pixel(leds, *it, 0, 10, 0));
}
// add non-green indicators
const int NON_GREEN_INDICATOR_RED[3] = {30, 0, 15};
const int NON_GREEN_INDICATOR_BLUE[3] = {0, 30, 15};
std::uniform_int_distribution<> non_green_indicator_color_dist(0, 2);
std::uniform_int_distribution<> remaining_indicators_dist(0, 20 - green_indicators);
int non_green_indicators = remaining_indicators_dist(gen);
std::set<int> remaining_indicators;
// ESP_LOGI(TAG, "non-green indicators: %i", non_green_indicators);
while (remaining_indicators.size() < non_green_indicators) {
int led_attempt = led_picker_dist(gen);
if (indicators.find(led_attempt) == indicators.end()) {
remaining_indicators.insert(led_attempt);
// ESP_LOGI(TAG, "added non-green led at %i", led_attempt);
}
}
for (std::set<int>::iterator it = remaining_indicators.begin(); it != remaining_indicators.end(); it++) {
int color = non_green_indicator_color_dist(gen);
ESP_ERROR_CHECK(led_strip_set_pixel(leds, *it, NON_GREEN_INDICATOR_RED[color], 0, NON_GREEN_INDICATOR_BLUE[color]));
}
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 switch combination! (step 3, puzzle 0)");
}
break;
}
vTaskDelay(pdMS_TO_TICKS(10));
}
break;
}
case 1: {
lcd_print(&lcd, "Blank");
set_module_time(10000);
start_module_timer();
std::uniform_int_distribution<> on_indicators_dist(16, 21);
uint8_t indicators_num = on_indicators_dist(gen);
std::set<int> indicators;
while (indicators.size() < indicators_num) {
indicators.insert(led_picker_dist(gen));
}
for (std::set<int>::iterator it = indicators.begin(); it != indicators.end(); it++) {
int color = led_color_dist(gen);
ESP_ERROR_CHECK(led_strip_set_pixel(leds, *it, INDICATOR_RED[color], INDICATOR_GREEN[color], INDICATOR_BLUE[color]));
}
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 was changed! (step 3, puzzle 1)");
}
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++;
// ESP_LOGI(TAG, "puzzle 1 solved (keypad)!");
}
} else {
strike("Switch state was changed! (step 3, puzzle 1)");
}
break;
}
vTaskDelay(pdMS_TO_TICKS(10));
}
}
break;
}
case 2: {
set_module_time(10000);
start_module_timer();
std::uniform_int_distribution<> lit_led_dist(0, 1);
bool rfid_lit = lit_led_dist(gen);
// ESP_LOGI(TAG, "rfid lit: %i", rfid_lit);
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);
Led rfid_led = rfid;
Led lcd_led = char_lcd;
Led speaker_led = speaker;
Led keypad_led = keypad;
Led tft_led = tft;
if (rfid_lit) {
int color = led_color_dist(gen);
ESP_ERROR_CHECK(led_strip_set_pixel(leds, rfid_led, 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, lcd_led, 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, speaker_led, 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, keypad_led, 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, tft_led, 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("Green button pressed too many times! (step 3, puzzle 2)");
break;
}
}
if ((button_state & 0b1000) == 0b1000) {
blue_button_pressed++;
if ((blue_button_pressed > 1) || !lcd_lit) {
strike("Blue button pressed too many times! (step 3, puzzle 2)");
break;
}
}
}
if (get_touch_pressed()) {
fingerprint_sensor_pressed++;
if ((fingerprint_sensor_pressed > 2) || !speaker_lit) {
strike("Fingerprint sensor pressed too many times! (step 3, puzzle 2)");
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("1 was not pressed on Keypad! (step 3, puzzle 2)");
wrong = true;
}
break;
}
case 2: {
if (keypad_string != "12") {
strike("12 was not pressed on Keypad! (step 3, puzzle 2)");
wrong = true;
}
break;
}
default: {
strike("keypad length was more than 2! (step 3, puzzle 2)");
wrong = true;
break;
}
}
if (wrong) {
break;
}
}
if (get_flipped_up_switch(&switch1) || get_flipped_up_switch(&switch2)) {
if (!tft_lit) {
strike("Switch 1 or 2 were flipped up! (step 3, puzzle 2)");
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++;
} else {
strike("Final state was not correct! (step 3, puzzle 2)");
}
break;
}
vTaskDelay(pdMS_TO_TICKS(10));
}
break;
}
case 3: {
lcd_print(&lcd, "Nothing");
set_module_time(10000);
start_module_timer();
break;
}
case 4: {
lcd_print(&lcd, "Blink");
set_module_time(10000);
start_module_timer();
break;
}
case 5: {
lcd_print(&lcd, "Ummm");
set_module_time(10000);
start_module_timer();
break;
}
case 6: {
lcd_print(&lcd, "Plank");
set_module_time(10000);
start_module_timer();
break;
}
case 7: {
lcd_print(&lcd, "What");
set_module_time(10000);
start_module_timer();
break;
}
case 8: {
lcd_print(&lcd, "Plink");
set_module_time(10000);
start_module_timer();
break;
}
}
clean_bomb();
}
}