add support for modifed game

This commit is contained in:
2026-04-10 13:38:14 -05:00
parent 3b2f8957e4
commit 5ffc2b609b
21 changed files with 247 additions and 70 deletions
+2
View File
@@ -26,6 +26,8 @@
#include "steps/p002_step5.h" #include "steps/p002_step5.h"
#include "steps/p002_step6.h" #include "steps/p002_step6.h"
bool play_modified;
static const char *TAG = "main"; static const char *TAG = "main";
uint32_t initial_game_time = 90*60*1000 + 1000; uint32_t initial_game_time = 90*60*1000 + 1000;
uint32_t skip_to_step = 0; uint32_t skip_to_step = 0;
+2
View File
@@ -6,6 +6,8 @@
#include <cstddef> #include <cstddef>
extern bool play_modified;
constexpr size_t N_STEPS = 6; constexpr size_t N_STEPS = 6;
#endif /* MAIN_H */ #endif /* MAIN_H */
+23 -13
View File
@@ -1,4 +1,5 @@
#include "p001_step4.h" #include "p001_step4.h"
#include "main.h"
__attribute__((unused)) __attribute__((unused))
static const char *TAG = "step4"; static const char *TAG = "step4";
@@ -233,8 +234,11 @@ bool play_game(int time, int required_score) {
target_score = required_score; target_score = required_score;
score = 0; score = 0;
update_score(); update_score();
// set_module_time(time);
// start_module_timer(); if (!play_modified) {
set_module_time(time);
start_module_timer();
}
clear_board(); clear_board();
@@ -272,7 +276,8 @@ bool play_game(int time, int required_score) {
show_board(); show_board();
if (score >= required_score) { if (score >= required_score) {
// stop_module_timer(); if (!play_modified)
stop_module_timer();
return true; return true;
} }
} }
@@ -307,18 +312,19 @@ bool play_game(int time, int required_score) {
show_board(); show_board();
if (score >= required_score) { if (score >= required_score) {
// stop_module_timer(); if (!play_modified)
stop_module_timer();
return true; return true;
} }
} }
} }
} }
// if (get_module_time() <= 0) { if ((!play_modified) && get_module_time() <= 0) {
// stop_module_timer(); stop_module_timer();
// strike("Out of time"); strike("Out of time");
// return false; return false;
// } }
// if (get_switch_flipped(&switch_)) { // if (get_switch_flipped(&switch_)) {
// printf("%d\n", piece); // printf("%d\n", piece);
@@ -334,7 +340,8 @@ bool play_game(int time, int required_score) {
// game over // game over
ESP_LOGI(TAG, "Game Over. Score: %d", score); ESP_LOGI(TAG, "Game Over. Score: %d", score);
// stop_module_timer(); if (!play_modified)
stop_module_timer();
strike("Out of room"); strike("Out of room");
return false; return false;
} }
@@ -390,13 +397,16 @@ void p001_step4() {
do_star_codes(&star_code, 1); do_star_codes(&star_code, 1);
init_screen(); 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); play_clip_wav(MOUNT_POINT "/partdone.wav", true, false, 0, 0);
complete(); 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); play_clip_wav(MOUNT_POINT "/partdone.wav", true, false, 0, 0);
complete(); 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); play_clip_wav(MOUNT_POINT "/stepdone.wav", true, false, 1, 0);
complete(); complete();
+151
View File
@@ -7,6 +7,7 @@
#define TIME_BLINK 35'000 #define TIME_BLINK 35'000
#define TIME_UMMM 35'000 #define TIME_UMMM 35'000
#define TIME_BLANK 40'000 #define TIME_BLANK 40'000
#define TIME_WHAT 60'000
#define TIME_PLINK 40'000 #define TIME_PLINK 40'000
__attribute__((unused)) __attribute__((unused))
@@ -650,6 +651,8 @@ void p001_step5(void) {
break; break;
} }
case 7: { case 7: {
if (play_modified) {
// do PLINK
lcd_print("Plink"); lcd_print("Plink");
set_module_time(TIME_PLINK); set_module_time(TIME_PLINK);
start_module_timer(); start_module_timer();
@@ -744,6 +747,154 @@ void p001_step5(void) {
if (!failed) { if (!failed) {
solved_correctly = true; 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 < 4; i++) {
set_unique_leds(led_options, modifier_indicators[i], COLORS[i]);
}
leds_flush();
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_keypad_pressed(&key)) {
if (key == KeypadKey::star) {
// clear
entered_string = "";
} else if (key == KeypadKey::pound) {
// submit
if (entered_string != answer_string) {
strike("Incorrect answer!");
} else {
solved_correctly = true;
}
break;
} else {
entered_string += char_of_keypad_key(key);
}
lcd_clear();
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; break;
} }
default: { default: {
+13 -1
View File
@@ -47,6 +47,12 @@ static void replay_last() {
} }
static void do_p001() { static void do_p001() {
play_modified = false;
puzzle = 1;
}
static void do_p001_modified() {
play_modified = true;
puzzle = 1; puzzle = 1;
} }
@@ -62,10 +68,16 @@ void step0() {
StarCodeHandler star_codes[] = { StarCodeHandler star_codes[] = {
{ {
.code = "*9819", .code = "*9819",
.display_text = "Start P001", .display_text = "Start P001DH",
.should_exit = true, .should_exit = true,
.callback = do_p001, .callback = do_p001,
}, },
{
.code = "*9818",
.display_text = "Start P001DM",
.should_exit = true,
.callback = do_p001_modified,
},
{ {
.code = "*3141", .code = "*3141",
.display_text = "Start P002", .display_text = "Start P002",
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.