step 6
This commit is contained in:
+39
-39
@@ -6,27 +6,46 @@
|
||||
#include "wires_puzzle.h"
|
||||
#include <esp_log.h>
|
||||
|
||||
void setup_wires(void) {
|
||||
clear_all_pressed_released();
|
||||
lcd_clear(&lcd);
|
||||
|
||||
WiresColor wires[NUM_WIRES];
|
||||
load_wires_from_sd_card(wires);
|
||||
uint8_t wires_state = 0;
|
||||
|
||||
void print_wires(WireColor* wires, int editing_idx) {
|
||||
bool cut[NUM_WIRES];
|
||||
solve_wires(wires, cut);
|
||||
|
||||
lcd_set_cursor(&lcd, 1, 1);
|
||||
char wires_string[NUM_WIRES+1] = {0};
|
||||
wires_to_string(wires, wires_string);
|
||||
lcd_print(&lcd, wires_string);
|
||||
char string_buf[NUM_WIRES+1] = {0};
|
||||
wires_to_string(wires, string_buf);
|
||||
lcd_print(&lcd, string_buf);
|
||||
|
||||
lcd_set_cursor(&lcd, 1, 2);
|
||||
cut_to_string(cut, wires_string);
|
||||
lcd_print(&lcd, wires_string);
|
||||
lcd_set_cursor(&lcd, 1, 1);
|
||||
cut_to_string(cut, string_buf);
|
||||
lcd_print(&lcd, string_buf);
|
||||
|
||||
lcd_set_cursor(&lcd, 1, 3);
|
||||
wires_state = get_wires();
|
||||
for (int i = 0; i < NUM_WIRES; i++) {
|
||||
if (wires_state & (1<<i)) {
|
||||
string_buf[i] = ' ';
|
||||
} else {
|
||||
string_buf[i] = '!';
|
||||
}
|
||||
}
|
||||
lcd_print(&lcd, string_buf);
|
||||
|
||||
lcd_set_cursor(&lcd, editing_idx+1, 1);
|
||||
}
|
||||
|
||||
void setup_wires(void) {
|
||||
clear_all_pressed_released();
|
||||
get_cut_wires();
|
||||
lcd_clear(&lcd);
|
||||
lcd_cursor(&lcd);
|
||||
|
||||
WireColor wires[NUM_WIRES];
|
||||
load_wires_from_sd_card(wires);
|
||||
|
||||
int editing_idx = 0;
|
||||
print_wires(wires, editing_idx);
|
||||
|
||||
KeypadKey key;
|
||||
ButtonKey button;
|
||||
@@ -36,18 +55,7 @@ void setup_wires(void) {
|
||||
if (key == KeypadKey::k1) {
|
||||
generate_new_wires(wires);
|
||||
save_wires_to_sd_card(wires);
|
||||
bool cut[NUM_WIRES];
|
||||
solve_wires(wires, cut);
|
||||
|
||||
lcd_set_cursor(&lcd, 1, 1);
|
||||
char wires_string[NUM_WIRES+1] = {0};
|
||||
wires_to_string(wires, wires_string);
|
||||
lcd_print(&lcd, wires_string);
|
||||
|
||||
lcd_set_cursor(&lcd, 1, 2);
|
||||
cut_to_string(cut, wires_string);
|
||||
lcd_print(&lcd, wires_string);
|
||||
lcd_set_cursor(&lcd, editing_idx+1, 1);
|
||||
print_wires(wires, editing_idx);
|
||||
} else if (key == KeypadKey::pound) {
|
||||
lcd_no_cursor(&lcd);
|
||||
return;
|
||||
@@ -55,7 +63,6 @@ void setup_wires(void) {
|
||||
}
|
||||
|
||||
while (get_pressed_button(&button)) {
|
||||
ESP_LOGI("setup_wires", "Button press: %d", (int)button);
|
||||
if (button == ButtonKey::b1) {
|
||||
// left
|
||||
editing_idx = editing_idx - 1;
|
||||
@@ -66,26 +73,19 @@ void setup_wires(void) {
|
||||
if (editing_idx >= NUM_WIRES) editing_idx = NUM_WIRES-1;
|
||||
} else if (button == ButtonKey::b2) {
|
||||
// down
|
||||
wires[editing_idx] = (WiresColor)(((int)(wires[editing_idx]) + (NUM_COLORS-1)) % NUM_COLORS);
|
||||
wires[editing_idx] = (WireColor)(((int)(wires[editing_idx]) + (NUM_COLORS-1)) % NUM_COLORS);
|
||||
} else if (button == ButtonKey::b3) {
|
||||
// up
|
||||
wires[editing_idx] = (WiresColor)(((int)(wires[editing_idx]) + 1) % NUM_COLORS);
|
||||
wires[editing_idx] = (WireColor)(((int)(wires[editing_idx]) + 1) % NUM_COLORS);
|
||||
}
|
||||
save_wires_to_sd_card(wires);
|
||||
lcd_set_cursor(&lcd, 1, 1);
|
||||
char wires_string[NUM_WIRES+1] = {0};
|
||||
wires_to_string(wires, wires_string);
|
||||
lcd_print(&lcd, wires_string);
|
||||
|
||||
bool cut[NUM_WIRES];
|
||||
solve_wires(wires, cut);
|
||||
lcd_set_cursor(&lcd, 1, 2);
|
||||
cut_to_string(cut, wires_string);
|
||||
lcd_print(&lcd, wires_string);
|
||||
|
||||
lcd_set_cursor(&lcd, editing_idx+1, 1);
|
||||
print_wires(wires, editing_idx);
|
||||
}
|
||||
|
||||
uint8_t new_wires_state = get_wires();
|
||||
if (new_wires_state != wires_state) {
|
||||
print_wires(wires, editing_idx);
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "../drivers/bottom_half.h"
|
||||
#include "../drivers/char_lcd.hpp"
|
||||
#include "../drivers/wires.hpp"
|
||||
#include "../drivers/wires.h"
|
||||
#include "setup_wires.hpp"
|
||||
|
||||
static const char *STEP0_TAG = "step0";
|
||||
|
||||
@@ -1,10 +1,64 @@
|
||||
#ifndef STEP_6_HPP
|
||||
#define STEP_6_HPP
|
||||
|
||||
#include "wires_puzzle.h"
|
||||
#include "drivers/wires.h"
|
||||
#include "drivers/bottom_half.h"
|
||||
|
||||
static const char *STEP6_TAG = "step6";
|
||||
|
||||
static uint8_t cut_wires = 0;
|
||||
|
||||
static void correct_wire_task(void *arg);
|
||||
|
||||
void step6(void) {
|
||||
get_cut_wires();
|
||||
clear_all_pressed_released();
|
||||
|
||||
WireColor wires[NUM_WIRES];
|
||||
load_wires_from_sd_card(wires);
|
||||
bool solution[NUM_WIRES] = {0};
|
||||
solve_wires(wires, solution);
|
||||
|
||||
while (1) {
|
||||
|
||||
uint8_t new_cut_wires = get_cut_wires();
|
||||
uint8_t just_cut_wires = new_cut_wires & ~cut_wires;
|
||||
cut_wires |= new_cut_wires;
|
||||
|
||||
for (int i = 0; i < NUM_WIRES; i++) {
|
||||
if (just_cut_wires & (1<<i)) {
|
||||
if (solution[i]) {
|
||||
xTaskCreate(correct_wire_task, "correct_wire", 4096, NULL, 5, NULL);
|
||||
} else {
|
||||
strike("Cut wrong wire");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (get_touch_pressed()) {
|
||||
bool correct = true;
|
||||
for (int i = 0; i < NUM_WIRES; i++) {
|
||||
bool wire_cut = (cut_wires & (1<<i)) != 0;
|
||||
if (solution[i] && !wire_cut) {
|
||||
correct = false;
|
||||
}
|
||||
}
|
||||
if (correct) {
|
||||
return;
|
||||
} else {
|
||||
strike("Not all wires are cut!");
|
||||
}
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
}
|
||||
|
||||
static void correct_wire_task(void *arg) {
|
||||
ESP_LOGI(STEP6_TAG, "Correct!");
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
#endif /* STEP_6_HPP */
|
||||
+43
-43
@@ -14,25 +14,25 @@ static int color_name_len[NUM_COLORS] = {
|
||||
|
||||
static int max(int n0, int n1, int n2, int n3, int n4, int n5);
|
||||
|
||||
void wires_to_string(WiresColor* wires, char* out_wires_string) {
|
||||
void wires_to_string(WireColor* wires, char* out_wires_string) {
|
||||
for (int i = 0; i < NUM_WIRES; i++) {
|
||||
switch (wires[i]) {
|
||||
case WiresColor::red:
|
||||
case WireColor::red:
|
||||
out_wires_string[i] = 'r';
|
||||
break;
|
||||
case WiresColor::yellow:
|
||||
case WireColor::yellow:
|
||||
out_wires_string[i] = 'y';
|
||||
break;
|
||||
case WiresColor::green:
|
||||
case WireColor::green:
|
||||
out_wires_string[i] = 'g';
|
||||
break;
|
||||
case WiresColor::blue:
|
||||
case WireColor::blue:
|
||||
out_wires_string[i] = 'u';
|
||||
break;
|
||||
case WiresColor::black:
|
||||
case WireColor::black:
|
||||
out_wires_string[i] = 'b';
|
||||
break;
|
||||
case WiresColor::white:
|
||||
case WireColor::white:
|
||||
out_wires_string[i] = 'w';
|
||||
break;
|
||||
}
|
||||
@@ -48,32 +48,32 @@ void cut_to_string(bool* cut, char* out_cut_string) {
|
||||
}
|
||||
}
|
||||
|
||||
void string_to_wires(char* wires_string, WiresColor* out_wires) {
|
||||
void string_to_wires(char* wires_string, WireColor* out_wires) {
|
||||
for (int i = 0; i < NUM_WIRES; i++) {
|
||||
switch (wires_string[i]) {
|
||||
case 'r':
|
||||
out_wires[i] = WiresColor::red;
|
||||
out_wires[i] = WireColor::red;
|
||||
break;
|
||||
case 'y':
|
||||
out_wires[i] = WiresColor::yellow;
|
||||
out_wires[i] = WireColor::yellow;
|
||||
break;
|
||||
case 'g':
|
||||
out_wires[i] = WiresColor::green;
|
||||
out_wires[i] = WireColor::green;
|
||||
break;
|
||||
case 'u':
|
||||
out_wires[i] = WiresColor::blue;
|
||||
out_wires[i] = WireColor::blue;
|
||||
break;
|
||||
case 'b':
|
||||
out_wires[i] = WiresColor::black;
|
||||
out_wires[i] = WireColor::black;
|
||||
break;
|
||||
case 'w':
|
||||
out_wires[i] = WiresColor::white;
|
||||
out_wires[i] = WireColor::white;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void save_wires_to_sd_card(WiresColor* wires) {
|
||||
void save_wires_to_sd_card(WireColor* wires) {
|
||||
FILE* f = fopen(WIRES_FILE_PATH, "w");
|
||||
if (f == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to open wires file to write");
|
||||
@@ -84,7 +84,7 @@ void save_wires_to_sd_card(WiresColor* wires) {
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void load_wires_from_sd_card(WiresColor* out_wires) {
|
||||
void load_wires_from_sd_card(WireColor* out_wires) {
|
||||
FILE* f = fopen(WIRES_FILE_PATH, "r");
|
||||
if (f == NULL) {
|
||||
ESP_LOGW(TAG, "Failed to read wires file. Generating new wires");
|
||||
@@ -101,11 +101,11 @@ void load_wires_from_sd_card(WiresColor* out_wires) {
|
||||
|
||||
/// @brief Fills the array with 6 random WiresColors.
|
||||
/// @param wires and array of len >= 6 to be populated with random colors
|
||||
void generate_new_wires(WiresColor* wires) {
|
||||
void generate_new_wires(WireColor* wires) {
|
||||
for (int w = 0; w < NUM_WIRES; w++) {
|
||||
// roughly evenly distributed
|
||||
uint32_t rand = esp_random() % NUM_COLORS;
|
||||
wires[w] = (WiresColor)(rand);
|
||||
wires[w] = (WireColor)(rand);
|
||||
}
|
||||
|
||||
bool cuts[NUM_WIRES] = {0};
|
||||
@@ -121,7 +121,7 @@ void generate_new_wires(WiresColor* wires) {
|
||||
}
|
||||
}
|
||||
|
||||
void solve_wires(WiresColor* wires, bool* out_cut) {
|
||||
void solve_wires(WireColor* wires, bool* out_cut) {
|
||||
// by default, don't cut any wires
|
||||
for (int i = 0; i < NUM_WIRES; i++) {
|
||||
out_cut[i] = false;
|
||||
@@ -142,17 +142,17 @@ void solve_wires(WiresColor* wires, bool* out_cut) {
|
||||
int white_pos_len = 0;
|
||||
|
||||
for (int i = 0; i < NUM_WIRES; i++) {
|
||||
if (wires[i] == WiresColor::red) {
|
||||
if (wires[i] == WireColor::red) {
|
||||
red_pos[red_pos_len++] = i;
|
||||
} else if (wires[i] == WiresColor::yellow) {
|
||||
} else if (wires[i] == WireColor::yellow) {
|
||||
yellow_pos[yellow_pos_len++] = i;
|
||||
} else if (wires[i] == WiresColor::green) {
|
||||
} else if (wires[i] == WireColor::green) {
|
||||
green_pos[green_pos_len++] = i;
|
||||
} else if (wires[i] == WiresColor::blue) {
|
||||
} else if (wires[i] == WireColor::blue) {
|
||||
blue_pos[blue_pos_len++] = i;
|
||||
} else if (wires[i] == WiresColor::black) {
|
||||
} else if (wires[i] == WireColor::black) {
|
||||
black_pos[black_pos_len++] = i;
|
||||
} else if (wires[i] == WiresColor::white) {
|
||||
} else if (wires[i] == WireColor::white) {
|
||||
white_pos[white_pos_len++] = i;
|
||||
}
|
||||
}
|
||||
@@ -188,18 +188,18 @@ void solve_wires(WiresColor* wires, bool* out_cut) {
|
||||
}
|
||||
|
||||
// cut the first wire if it is green or white
|
||||
if (wires[0] == WiresColor::green || wires[0] == WiresColor::white) out_cut[0] = true;
|
||||
if (wires[0] == WireColor::green || wires[0] == WireColor::white) out_cut[0] = true;
|
||||
|
||||
// cut blue wires in even positions (odd indexes)
|
||||
for (int i = 1; i < NUM_WIRES; i += 2) {
|
||||
if (wires[i] == WiresColor::blue) out_cut[i] = true;
|
||||
if (wires[i] == WireColor::blue) out_cut[i] = true;
|
||||
}
|
||||
|
||||
// cut black and yellow wires next to black and yellow wires
|
||||
for (int i = 0; i < NUM_WIRES-1; i++) {
|
||||
if (
|
||||
(wires[i] == WiresColor::yellow || wires[i] == WiresColor::black) &&
|
||||
(wires[i+1] == WiresColor::yellow || wires[i+1] == WiresColor::black)
|
||||
(wires[i] == WireColor::yellow || wires[i] == WireColor::black) &&
|
||||
(wires[i+1] == WireColor::yellow || wires[i+1] == WireColor::black)
|
||||
) {
|
||||
out_cut[i] = true;
|
||||
out_cut[1] = true;
|
||||
@@ -210,10 +210,10 @@ void solve_wires(WiresColor* wires, bool* out_cut) {
|
||||
for (int green_idx = green_pos_len-1; green_idx >= 0; green_idx--) {
|
||||
int pos = green_pos[green_idx];
|
||||
if (
|
||||
wires[pos-1] == WiresColor::yellow ||
|
||||
wires[pos-1] == WiresColor::white ||
|
||||
wires[pos+1] == WiresColor::yellow ||
|
||||
wires[pos+1] == WiresColor::white
|
||||
wires[pos-1] == WireColor::yellow ||
|
||||
wires[pos-1] == WireColor::white ||
|
||||
wires[pos+1] == WireColor::yellow ||
|
||||
wires[pos+1] == WireColor::white
|
||||
) {
|
||||
out_cut[pos] = true;
|
||||
break;
|
||||
@@ -221,7 +221,7 @@ void solve_wires(WiresColor* wires, bool* out_cut) {
|
||||
}
|
||||
|
||||
// cut all white wires if there is a red wire in the 5th position
|
||||
if (wires[4] == WiresColor::red) {
|
||||
if (wires[4] == WireColor::red) {
|
||||
for (int white_idx = 0; white_idx < white_pos_len; white_idx++) {
|
||||
out_cut[white_pos[white_idx]] = true;
|
||||
}
|
||||
@@ -268,8 +268,8 @@ void solve_wires(WiresColor* wires, bool* out_cut) {
|
||||
// cut any wire adjacent to both a yellow and blue wire
|
||||
for (int i = 0; i < NUM_WIRES-2; i++) {
|
||||
if (
|
||||
(wires[i] == WiresColor::yellow && wires[i+2] == WiresColor::blue) ||
|
||||
(wires[i] == WiresColor::blue && wires[i+2] == WiresColor::white)
|
||||
(wires[i] == WireColor::yellow && wires[i+2] == WireColor::blue) ||
|
||||
(wires[i] == WireColor::blue && wires[i+2] == WireColor::white)
|
||||
) {
|
||||
out_cut[i+1] = true;
|
||||
}
|
||||
@@ -281,10 +281,10 @@ void solve_wires(WiresColor* wires, bool* out_cut) {
|
||||
for (int i = 0; i < blue_pos_len; i++) {
|
||||
int pos = blue_pos[i];
|
||||
if (
|
||||
wires[pos-1] == WiresColor::red ||
|
||||
wires[pos-1] == WiresColor::green ||
|
||||
wires[pos+1] == WiresColor::red ||
|
||||
wires[pos+1] == WiresColor::green
|
||||
wires[pos-1] == WireColor::red ||
|
||||
wires[pos-1] == WireColor::green ||
|
||||
wires[pos+1] == WireColor::red ||
|
||||
wires[pos+1] == WireColor::green
|
||||
) {
|
||||
out_cut[pos] = false;
|
||||
}
|
||||
@@ -298,10 +298,10 @@ void solve_wires(WiresColor* wires, bool* out_cut) {
|
||||
}
|
||||
|
||||
// never cut red or black wires in the 4th or 7th positions
|
||||
if (wires[3] == WiresColor::red || wires[3] == WiresColor::black) {
|
||||
if (wires[3] == WireColor::red || wires[3] == WireColor::black) {
|
||||
out_cut[3] = false;
|
||||
}
|
||||
if (wires[6] == WiresColor::red || wires[6] == WiresColor::black) {
|
||||
if (wires[6] == WireColor::red || wires[6] == WireColor::black) {
|
||||
out_cut[6] = false;
|
||||
}
|
||||
|
||||
@@ -324,7 +324,7 @@ void solve_wires(WiresColor* wires, bool* out_cut) {
|
||||
}
|
||||
|
||||
// never cut a blue or green wire in the 8th postion
|
||||
if (wires[7] == WiresColor::blue || wires[7] == WiresColor::green) {
|
||||
if (wires[7] == WireColor::blue || wires[7] == WireColor::green) {
|
||||
out_cut[7] = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,25 +16,25 @@ typedef enum {
|
||||
blue = 3,
|
||||
black = 4,
|
||||
white = 5,
|
||||
} WiresColor;
|
||||
} WireColor;
|
||||
|
||||
void solve_wires(WiresColor* wires, bool* out_cut);
|
||||
void generate_new_wires(WiresColor* wires);
|
||||
void solve_wires(WireColor* wires, bool* out_cut);
|
||||
void generate_new_wires(WireColor* wires);
|
||||
|
||||
void cut_to_string(bool* cut, char* out_cut_string);
|
||||
void wires_to_string(WiresColor* wires, char* out_wires_string);
|
||||
void string_to_wires(char* wires_string, WiresColor* out_wires);
|
||||
void wires_to_string(WireColor* wires, char* out_wires_string);
|
||||
void string_to_wires(char* wires_string, WireColor* out_wires);
|
||||
|
||||
void save_wires_to_sd_card(WiresColor* wires);
|
||||
void load_wires_from_sd_card(WiresColor* out_wires);
|
||||
void save_wires_to_sd_card(WireColor* wires);
|
||||
void load_wires_from_sd_card(WireColor* out_wires);
|
||||
|
||||
/// @brief Fills the array with 6 random WiresColors.
|
||||
/// @param wires the array of len >= 6 to be populated with random colors
|
||||
void generate_new_wires(WiresColor* wires);
|
||||
void generate_new_wires(WireColor* wires);
|
||||
|
||||
/// @brief Solves the wires puzzle, setting `out_cut` according to which wires are cut.
|
||||
/// @param wires the array of len >= 6 as input to the solver
|
||||
/// @param out_cut the output array of len >= 6 for which wires to cut
|
||||
void solve_wires(WiresColor* wires, bool* out_cut);
|
||||
void solve_wires(WireColor* wires, bool* out_cut);
|
||||
|
||||
#endif /* WIRES_PUZZLE_H */
|
||||
Reference in New Issue
Block a user