106 lines
3.4 KiB
C++
106 lines
3.4 KiB
C++
#ifndef STEP_5_HPP
|
|
#define STEP_5_HPP
|
|
|
|
#include "../drivers/bottom_half.h"
|
|
#include <iostream>
|
|
#include <random>
|
|
|
|
static const char *STEP5_TAG = "step5";
|
|
|
|
Led speaker_led = speaker;
|
|
|
|
const uint8_t SSEG_NUMS[10] = {0b00111111, 0b00000110, 0b01011011, 0b01001111, 0b01100110, 0b01101101, 0b01111101, 0b00000111, 0b01111111, 0b01101111};
|
|
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}
|
|
};
|
|
|
|
const int INDICATOR_RED[5] = {60, 0, 0, 35, 20};
|
|
const int INDICATOR_GREEN[5] = {0, 0, 60, 25, 20};
|
|
const int INDICATOR_BLUE[5] = {0, 60, 0, 0, 20};
|
|
|
|
// random number generators
|
|
std::random_device rd;
|
|
std::mt19937 gen(rd());
|
|
std::uniform_int_distribution<> answer_dist(0, 9);
|
|
std::uniform_int_distribution<> map_dist(0, 4);
|
|
std::uniform_int_distribution<> display_dist(0, 3);
|
|
std::uniform_int_distribution<> random_segment_dist(0, 127);
|
|
|
|
int answer = 0;
|
|
uint8_t answer_sseg = SSEG_NUMS[0];
|
|
char answer_char = '0';
|
|
uint8_t display_map[4] = {0b00000000, 0b00000000, 0b00000000, 0b00000000};
|
|
int chosen_map = 0;
|
|
|
|
void new_puzzle(void) {
|
|
// scramble lights
|
|
for (int i = 0; i < 5; i++) {
|
|
led_strip_set_pixel(leds, speaker_led, INDICATOR_RED[map_dist(gen)], INDICATOR_GREEN[map_dist(gen)], INDICATOR_BLUE[map_dist(gen)]);
|
|
led_strip_refresh(leds);
|
|
|
|
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];
|
|
answer_char = '0' + answer;
|
|
// ESP_LOGI(STEP5_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(STEP5_TAG, "Chosen Map: %i", chosen_map);
|
|
|
|
ESP_ERROR_CHECK(led_strip_set_pixel(leds, speaker_led, INDICATOR_RED[chosen_map], INDICATOR_GREEN[chosen_map], INDICATOR_BLUE[chosen_map]));
|
|
ESP_ERROR_CHECK(led_strip_refresh(leds));
|
|
|
|
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(STEP5_TAG, "Flipping bit %i on display %i", i, display);
|
|
}
|
|
}
|
|
}
|
|
|
|
void step5(void) {
|
|
KeypadKey key;
|
|
int solved_times = 0;
|
|
|
|
new_puzzle();
|
|
while(solved_times < 3) {
|
|
// for every bit in the answer-
|
|
set_module_sseg_raw(display_map);
|
|
if (get_pressed_keypad(&key)) {
|
|
char c = char_of_keypad_key(key);
|
|
// ESP_LOGI(STEP0_TAG, "Pressed: %c", c);
|
|
if (c == answer_char) {
|
|
solved_times++;
|
|
if (solved_times < 3) {
|
|
new_puzzle();
|
|
} else {
|
|
uint8_t display_tmp[4] = {0b00000000, 0b00000000, 0b00000000, 0b00000000};
|
|
set_module_sseg_raw(display_tmp);
|
|
}
|
|
} else {
|
|
strike("Incorrect Character!");
|
|
}
|
|
}
|
|
vTaskDelay(pdMS_TO_TICKS(10));
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* STEP_5_HPP */ |