add support for modifed game

This commit is contained in:
Mitchell Marino 2026-04-10 13:38:14 -05:00
parent 3b2f8957e4
commit 5ffc2b609b
21 changed files with 247 additions and 70 deletions

View File

@ -26,6 +26,8 @@
#include "steps/p002_step5.h"
#include "steps/p002_step6.h"
bool play_modified;
static const char *TAG = "main";
uint32_t initial_game_time = 90*60*1000 + 1000;
uint32_t skip_to_step = 0;

View File

@ -6,6 +6,8 @@
#include <cstddef>
extern bool play_modified;
constexpr size_t N_STEPS = 6;
#endif /* MAIN_H */

View File

@ -1,4 +1,5 @@
#include "p001_step4.h"
#include "main.h"
__attribute__((unused))
static const char *TAG = "step4";
@ -233,8 +234,11 @@ bool play_game(int time, int required_score) {
target_score = required_score;
score = 0;
update_score();
// set_module_time(time);
// start_module_timer();
if (!play_modified) {
set_module_time(time);
start_module_timer();
}
clear_board();
@ -272,7 +276,8 @@ bool play_game(int time, int required_score) {
show_board();
if (score >= required_score) {
// stop_module_timer();
if (!play_modified)
stop_module_timer();
return true;
}
}
@ -307,18 +312,19 @@ bool play_game(int time, int required_score) {
show_board();
if (score >= required_score) {
// stop_module_timer();
if (!play_modified)
stop_module_timer();
return true;
}
}
}
}
// if (get_module_time() <= 0) {
// stop_module_timer();
// strike("Out of time");
// return false;
// }
if ((!play_modified) && get_module_time() <= 0) {
stop_module_timer();
strike("Out of time");
return false;
}
// if (get_switch_flipped(&switch_)) {
// printf("%d\n", piece);
@ -334,7 +340,8 @@ bool play_game(int time, int required_score) {
// game over
ESP_LOGI(TAG, "Game Over. Score: %d", score);
// stop_module_timer();
if (!play_modified)
stop_module_timer();
strike("Out of room");
return false;
}
@ -390,13 +397,16 @@ void p001_step4() {
do_star_codes(&star_code, 1);
init_screen();
while (!play_game(4*60*1000, 2)) fail();
int lines_1 = play_modified ? 2 : 2;
int lines_2 = play_modified ? 5 : 4;
int lines_3 = play_modified ? 12 : 8;
while (!play_game(4*60*1000, lines_1)) fail();
play_clip_wav(MOUNT_POINT "/partdone.wav", true, false, 0, 0);
complete();
while (!play_game(4*60*1000, 5)) fail();
while (!play_game(4*60*1000, lines_2)) fail();
play_clip_wav(MOUNT_POINT "/partdone.wav", true, false, 0, 0);
complete();
while (!play_game(7*60*1000, 12)) fail();
while (!play_game(6*60*1000, lines_3)) fail();
play_clip_wav(MOUNT_POINT "/stepdone.wav", true, false, 1, 0);
complete();

View File

@ -7,6 +7,7 @@
#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))
@ -650,100 +651,250 @@ void p001_step5(void) {
break;
}
case 7: {
lcd_print("Plink");
set_module_time(TIME_PLINK);
start_module_timer();
if (play_modified) {
// do PLINK
lcd_print("Plink");
set_module_time(TIME_PLINK);
start_module_timer();
std::uniform_int_distribution<> indicator_number_dist(0, 4);
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);
// 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,
};
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)};
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;
}
} else {
// do WHAT
lcd_print(1, 1, "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(2, 1, 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 < 5; i++) {
set_unique_leds(led_options, indicator_numbers[i], COLORS[i]);
for (int i = 0; i < 4; i++) {
set_unique_leds(led_options, modifier_indicators[i], COLORS[i]);
}
leds_flush();
std::uniform_int_distribution<> answer_color_dist(0, 4);
std::string answer_string = std::to_string(expression_answer);
std::string entered_string = "";
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;
ESP_LOGI(TAG, "Solved full answer: %s", answer_string.c_str());
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) {
if (entered_string != answer_string) {
strike("Incorrect answer!");
failed = true;
} else {
solved_correctly = true;;
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());
lcd_print(1, 1, "What");
lcd_print(2, 1, display_expression.c_str());
lcd_print(3, 1, 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;
}
break;
}
default: {

View File

@ -47,6 +47,12 @@ static void replay_last() {
}
static void do_p001() {
play_modified = false;
puzzle = 1;
}
static void do_p001_modified() {
play_modified = true;
puzzle = 1;
}
@ -62,10 +68,16 @@ void step0() {
StarCodeHandler star_codes[] = {
{
.code = "*9819",
.display_text = "Start P001",
.display_text = "Start P001DH",
.should_exit = true,
.callback = do_p001,
},
{
.code = "*9818",
.display_text = "Start P001DM",
.should_exit = true,
.callback = do_p001_modified,
},
{
.code = "*3141",
.display_text = "Start P002",

BIN
resources/correct.raw Normal file

Binary file not shown.

BIN
resources/diffused.raw Normal file

Binary file not shown.

BIN
resources/flash.raw Normal file

Binary file not shown.

BIN
resources/high-1.raw Normal file

Binary file not shown.

BIN
resources/high-3.raw Normal file

Binary file not shown.

BIN
resources/high-6.raw Normal file

Binary file not shown.

BIN
resources/incorrect.raw Normal file

Binary file not shown.

BIN
resources/low-1.raw Normal file

Binary file not shown.

BIN
resources/low-3.raw Normal file

Binary file not shown.

BIN
resources/low-6.raw Normal file

Binary file not shown.

BIN
resources/partdone.raw Normal file

Binary file not shown.

BIN
resources/piano.raw Normal file

Binary file not shown.

BIN
resources/ready.raw Normal file

Binary file not shown.

BIN
resources/startup.raw Normal file

Binary file not shown.

BIN
resources/stepdone.raw Normal file

Binary file not shown.

BIN
resources/tetris.raw Normal file

Binary file not shown.