340 lines
14 KiB
C++
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();
|
|
}
|
|
}
|