rearrange steps
This commit is contained in:
parent
99a5402e76
commit
2f6796f57f
@ -2,690 +2,123 @@
|
||||
|
||||
static const char *TAG = "step2";
|
||||
|
||||
static lv_obj_t* scr;
|
||||
static lv_style_t scr_style;
|
||||
static lv_obj_t* img;
|
||||
|
||||
static bool invisible_blocks = false;
|
||||
static bool text_output = false;
|
||||
|
||||
static const int height = 22;
|
||||
static const int width = 10;
|
||||
|
||||
static int board[height][width] = {0};
|
||||
static lv_obj_t* visual_board[height][width] = {0};
|
||||
|
||||
static lv_obj_t* line_clear_img;
|
||||
static lv_style_t game_over_style;
|
||||
static lv_obj_t* game_over_label;
|
||||
|
||||
static const void* LINE_CLEAR_SRC = (void*)"A:/sdcard/clear.bin";
|
||||
static const void* BACKGROUND_SRC = (void*)"A:/sdcard/bg.bin";
|
||||
// LV_IMG_DECLARE(background);
|
||||
// static const void* BACKGROUND_SRC = (void*)&background;
|
||||
|
||||
static const char* PIECE_IMG_SRC[] = {
|
||||
NULL,
|
||||
"A:/sdcard/lb.bin",
|
||||
"A:/sdcard/db.bin",
|
||||
"A:/sdcard/orange.bin",
|
||||
"A:/sdcard/yellow.bin",
|
||||
"A:/sdcard/green.bin",
|
||||
"A:/sdcard/purple.bin",
|
||||
"A:/sdcard/red.bin",
|
||||
// one: 0b00000110
|
||||
// seven: 0b00000111
|
||||
static const uint8_t SSEG_NUMS[8] = {0b00111111, 0b01011011, 0b01001111, 0b01100110, 0b01101101, 0b01111101, 0b01111111, 0b01101111};
|
||||
static 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}
|
||||
};
|
||||
|
||||
static bool game = true;
|
||||
|
||||
static int target_score = 0;
|
||||
static int score = 0;
|
||||
|
||||
static int piece = 0;
|
||||
static int piece_rotation = 0;
|
||||
static int piece_location[] = {0, 0};
|
||||
static int piece_nodes[4][2] = {
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
lv_obj_t* piece_imgs[4] = {};
|
||||
|
||||
TaskHandle_t music_handle;
|
||||
static const int INDICATOR_RED[5] = {15, 0, 0, 10, 5};
|
||||
static const int INDICATOR_GREEN[5] = {0, 0, 10, 5, 5};
|
||||
static const int INDICATOR_BLUE[5] = {0, 10, 0, 0, 5};
|
||||
|
||||
// random number generators
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
static std::uniform_int_distribution<> piece_dist(2, 7);
|
||||
static std::uniform_int_distribution<> answer_dist(0, 7);
|
||||
static std::uniform_int_distribution<> map_dist(0, 4);
|
||||
static std::uniform_int_distribution<> display_dist(0, 3);
|
||||
static std::uniform_int_distribution<> random_segment_dist(0, 127);
|
||||
|
||||
static void generate_block(void);
|
||||
static void show_board(void);
|
||||
static void get_node_locations(void);
|
||||
static bool check_overlap(void);
|
||||
static int answer = 0;
|
||||
static uint8_t answer_sseg = SSEG_NUMS[0];
|
||||
static char answer_char = '0';
|
||||
static uint8_t display_map[4] = {0b00000000, 0b00000000, 0b00000000, 0b00000000};
|
||||
static int chosen_map = 0;
|
||||
|
||||
static void line_clear(int hi);
|
||||
static void check_line_clears(void);
|
||||
static void place_piece(void);
|
||||
std::map<int, int> number_map = {
|
||||
{0, 0},
|
||||
{1, 2},
|
||||
{2, 3},
|
||||
{3, 4},
|
||||
{4, 5},
|
||||
{5, 6},
|
||||
{6, 8},
|
||||
{7, 9},
|
||||
};
|
||||
|
||||
static void move_left(void);
|
||||
static void move_right(void);
|
||||
static void drop(void);
|
||||
static void rotate_block(void);
|
||||
static void update_score(void);
|
||||
static void clear_board(void);
|
||||
|
||||
|
||||
static int bbcc(int i) { // [0,1,2,3] -> [ 0, 0,+1,+1]
|
||||
const int map[] = {0, 0, 1, 1};
|
||||
return map[i];
|
||||
}
|
||||
static int bccb(int i) { // [0,1,2,3] -> [ 0,+1,+1, 0]
|
||||
const int map[] = {0, 1, 1, 0};
|
||||
return map[i];
|
||||
}
|
||||
static int cbbc(int i) { // [0,1,2,3] -> [+1, 0, 0,+1]
|
||||
const int map[] = {1, 0, 0, 1};
|
||||
return map[i];
|
||||
}
|
||||
static int ccbb(int i) { // [0,1,2,3] -> [+1,+1, 0, 0]
|
||||
const int map[] = {1, 1, 0, 0};
|
||||
return map[i];
|
||||
}
|
||||
|
||||
static int acca(int i) { // [0,1,2,3] -> [-1,+1,+1,-1]
|
||||
const int map[] = {-1, 1, 1, -1};
|
||||
return map[i];
|
||||
}
|
||||
static int aacc(int i) { // [0,1,2,3] -> [-1,-1,+1,+1]
|
||||
const int map[] = {-1, -1, 1, 1};
|
||||
return map[i];
|
||||
}
|
||||
static int babc(int i) { // [0,1,2,3] -> [ 0,-1, 0,+1]
|
||||
const int map[] = {0, -1, 0, 1};
|
||||
return map[i];
|
||||
}
|
||||
static int abcb(int i) { // [0,1,2,3] -> [-1, 0,+1, 0]
|
||||
const int map[] = {-1, 0, 1, 0};
|
||||
return map[i];
|
||||
}
|
||||
|
||||
static int acdb(int i) { // [0,1,2,3] -> [-1,+1,+2, 0]
|
||||
const int map[] = {-1, +1, 2, 0};
|
||||
return map[i];
|
||||
}
|
||||
static int bacd(int i) { // [0,1,2,3] -> [ 0,-1,+1,+2]
|
||||
const int map[] = {0, -1, 1, 2};
|
||||
return map[i];
|
||||
}
|
||||
static int dcab(int i) { // [0,1,2,3] -> [+2,+1,-1, 0]
|
||||
const int map[] = {2, 1, -1, 0};
|
||||
return map[i];
|
||||
}
|
||||
static int bdca(int i) { // [0,1,2,3] -> [ 0,+2,+1,-1]
|
||||
const int map[] = {0, 2, 1, -1};
|
||||
return map[i];
|
||||
}
|
||||
|
||||
static void music_task(void* arg) {
|
||||
while (1) {
|
||||
play_raw(MOUNT_POINT "/tetris.pcm");
|
||||
}
|
||||
}
|
||||
|
||||
static void init_screen(void) {
|
||||
while (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdFALSE) vTaskDelay(pdMS_TO_TICKS(10));
|
||||
|
||||
img = lv_img_create(lv_scr_act());
|
||||
lv_img_set_src(img, BACKGROUND_SRC);
|
||||
lv_obj_align(img, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
line_clear_img = lv_img_create(lv_scr_act());
|
||||
lv_obj_add_flag(line_clear_img, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_img_set_src(line_clear_img, LINE_CLEAR_SRC);
|
||||
lv_obj_align(line_clear_img, LV_ALIGN_BOTTOM_LEFT, 159, -(height*16));
|
||||
|
||||
lv_style_init(&game_over_style);
|
||||
lv_style_set_text_color(&game_over_style, lv_color_white());
|
||||
lv_style_set_bg_color(&game_over_style, lv_color_black());
|
||||
lv_style_set_bg_opa(&game_over_style, LV_OPA_100);
|
||||
lv_style_set_text_align(&game_over_style, LV_TEXT_ALIGN_CENTER);
|
||||
|
||||
game_over_label = lv_label_create(lv_scr_act());
|
||||
lv_obj_add_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_align(game_over_label, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_add_style(game_over_label, &game_over_style, LV_STATE_DEFAULT);
|
||||
|
||||
// for (int h = 0; h < height; h++) {
|
||||
// for (int w = 0; w < width; w++) {
|
||||
// visual_board[h][w] = lv_img_create(lv_scr_act());
|
||||
// lv_obj_align(visual_board[h][w], LV_ALIGN_BOTTOM_LEFT, 159 + w*16, -(h*16));
|
||||
// lv_img_set_src(visual_board[h][w], PIECE_IMG_SRC[((w+h)%7)+1]);
|
||||
// }
|
||||
// }
|
||||
static void new_puzzle(void) {
|
||||
// scramble lights
|
||||
for (int i = 0; i < 5; i++) {
|
||||
led_strip_set_pixel(leds, 9, 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++) {
|
||||
piece_imgs[i] = lv_img_create(lv_scr_act());
|
||||
lv_obj_align(piece_imgs[i], LV_ALIGN_BOTTOM_LEFT, 159, -320);
|
||||
random_segments[i] = random_segment_dist(gen);
|
||||
}
|
||||
set_module_sseg_raw(random_segments);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
|
||||
xSemaphoreGive(xGuiSemaphore);
|
||||
answer = answer_dist(gen);
|
||||
answer_sseg = SSEG_NUMS[answer];
|
||||
// convert answer to number value to account for missing 1 and 7
|
||||
answer = number_map[answer];
|
||||
answer_char = '0' + answer;
|
||||
// ESP_LOGI(TAG, "Answer: %i", answer);
|
||||
|
||||
xTaskCreate(music_task, "music", 4096, NULL, 5, &music_handle);
|
||||
chosen_map = map_dist(gen);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
display_map[i] = SSEG_MAPS[chosen_map][i];
|
||||
}
|
||||
// ESP_LOGI(TAG, "Chosen Map: %i", chosen_map);
|
||||
|
||||
static void deinit_screen(void) {
|
||||
while (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdFALSE) vTaskDelay(pdMS_TO_TICKS(10));
|
||||
ESP_ERROR_CHECK(led_strip_set_pixel(leds, 9, INDICATOR_RED[chosen_map], INDICATOR_GREEN[chosen_map], INDICATOR_BLUE[chosen_map]));
|
||||
ESP_ERROR_CHECK(led_strip_refresh(leds));
|
||||
|
||||
lv_obj_clean(lv_scr_act());
|
||||
xSemaphoreGive(xGuiSemaphore);
|
||||
|
||||
vTaskDelete(music_handle);
|
||||
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(TAG, "Flipping bit %i on display %i", i, display);
|
||||
}
|
||||
|
||||
bool play_game(int time, int required_score) {
|
||||
game = true;
|
||||
target_score = required_score;
|
||||
score = 0;
|
||||
update_score();
|
||||
set_module_time(time);
|
||||
start_module_timer();
|
||||
|
||||
clear_board();
|
||||
|
||||
generate_block();
|
||||
show_board();
|
||||
|
||||
ButtonKey button;
|
||||
while (get_pressed_button(&button));
|
||||
// SwitchKey switch_;
|
||||
|
||||
const TickType_t first_repeat_time = pdMS_TO_TICKS(700);
|
||||
const TickType_t repeat_time = pdMS_TO_TICKS(100);
|
||||
TickType_t down_held = 0;
|
||||
TickType_t last_repeat = 0;
|
||||
|
||||
while(game) {
|
||||
if (get_pressed_button(&button)) {
|
||||
switch (button) {
|
||||
case ButtonKey::b1:
|
||||
move_left();
|
||||
break;
|
||||
case ButtonKey::b2:
|
||||
move_right();
|
||||
break;
|
||||
case ButtonKey::b3:
|
||||
down_held = xTaskGetTickCount();
|
||||
last_repeat = 0;
|
||||
drop();
|
||||
break;
|
||||
case ButtonKey::b4:
|
||||
rotate_block();
|
||||
break;
|
||||
}
|
||||
|
||||
show_board();
|
||||
|
||||
if (score >= required_score) {
|
||||
stop_module_timer();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (get_released_button(&button)) {
|
||||
if (button == ButtonKey::b3) {
|
||||
down_held = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (down_held != 0) {
|
||||
// check repeat
|
||||
TickType_t now = xTaskGetTickCount();
|
||||
if (now - down_held > first_repeat_time) {
|
||||
// repeat!
|
||||
if (now - last_repeat > repeat_time) {
|
||||
last_repeat = now;
|
||||
drop();
|
||||
show_board();
|
||||
|
||||
if (score >= required_score) {
|
||||
stop_module_timer();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (get_module_time() <= 0) {
|
||||
stop_module_timer();
|
||||
strike("Out of time");
|
||||
return false;
|
||||
}
|
||||
// if (get_flipped_switch(&switch_)) {
|
||||
// printf("%d\n", piece);
|
||||
// for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
||||
// int* p = piece_nodes[i];
|
||||
// printf("PieceLocation: %d, %d\n", p[0], p[1]);
|
||||
// }
|
||||
// printf("PieceRotation: %d\n", piece_rotation);
|
||||
// }
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
|
||||
// game over
|
||||
ESP_LOGI(TAG, "Game Over. Score: %d", score);
|
||||
stop_module_timer();
|
||||
strike("Out of room");
|
||||
return false;
|
||||
}
|
||||
|
||||
static void complete(void) {
|
||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||
lv_label_set_text(game_over_label, "Winner!\nPress any button to continue");
|
||||
lv_obj_clear_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
|
||||
xSemaphoreGive(xGuiSemaphore);
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
while (get_pressed_button(nullptr));
|
||||
while (1) {
|
||||
if (get_pressed_button(nullptr)) break;
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||
lv_obj_add_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
|
||||
xSemaphoreGive(xGuiSemaphore);
|
||||
}
|
||||
}
|
||||
|
||||
static void fail(void) {
|
||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||
lv_label_set_text(game_over_label, "Game Over\nPress any button to continue");
|
||||
lv_obj_clear_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
|
||||
xSemaphoreGive(xGuiSemaphore);
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
while (get_pressed_button(nullptr));
|
||||
while (1) {
|
||||
if (get_pressed_button(nullptr)) break;
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||
lv_obj_add_flag(game_over_label, LV_OBJ_FLAG_HIDDEN);
|
||||
xSemaphoreGive(xGuiSemaphore);
|
||||
}
|
||||
}
|
||||
|
||||
void step2(void) {
|
||||
StarCodeHandler star_code = {
|
||||
.code = "*3850",
|
||||
.display_text = "Starting...",
|
||||
.should_exit = true,
|
||||
.callback = nullptr,
|
||||
};
|
||||
do_star_codes(&star_code, 1);
|
||||
init_screen();
|
||||
KeypadKey key;
|
||||
int solved_times = 0;
|
||||
|
||||
while (!play_game(4*60*1000, 2)) fail();
|
||||
complete();
|
||||
while (!play_game(4*60*1000, 4)) fail();
|
||||
complete();
|
||||
while (!play_game(6*60*1000, 8)) fail();
|
||||
complete();
|
||||
|
||||
deinit_screen();
|
||||
}
|
||||
|
||||
static void show_board(void) {
|
||||
for (int h = 0; h < height; h++) {
|
||||
for (int w = 0; w < width; w++) {
|
||||
if (board[h][w] == 9) {
|
||||
board[h][w] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
||||
int* p = piece_nodes[i];
|
||||
board[p[0]][p[1]] = 9;
|
||||
}
|
||||
|
||||
if (text_output) {
|
||||
for (int h = height-1; h >= 0; h--) {
|
||||
for (int w = 0; w < width; w++) {
|
||||
printf("|%c", board[h][w] == 9 ? 'X' : (invisible_blocks ? '0' : ('0' + board[h][w])));
|
||||
}
|
||||
printf("|\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
||||
int* p = piece_nodes[i];
|
||||
lv_obj_t* piece_img = piece_imgs[i];
|
||||
lv_obj_align(piece_img, LV_ALIGN_BOTTOM_LEFT, 159 + p[1]*16, -(p[0]*16));
|
||||
}
|
||||
xSemaphoreGive(xGuiSemaphore);
|
||||
}
|
||||
}
|
||||
|
||||
static void generate_block(void) {
|
||||
int new_piece = piece_dist(gen);
|
||||
if (new_piece == piece) {
|
||||
new_piece = 1;
|
||||
}
|
||||
|
||||
piece = new_piece;
|
||||
piece_rotation = 0;
|
||||
|
||||
piece_location[0] = 18;
|
||||
piece_location[1] = 4;
|
||||
|
||||
get_node_locations();
|
||||
|
||||
for (int h = 0; h < height; h++) {
|
||||
for (int w = 0; w < width; w++) {
|
||||
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
||||
int* p = piece_nodes[i];
|
||||
if (board[p[0]][p[1]] != 0) {
|
||||
game = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
lv_obj_t* piece_img = piece_imgs[i];
|
||||
lv_img_set_src(piece_img, PIECE_IMG_SRC[piece]);
|
||||
}
|
||||
xSemaphoreGive(xGuiSemaphore);
|
||||
}
|
||||
}
|
||||
|
||||
static void rotate_block(void) {
|
||||
piece_rotation++;
|
||||
if (piece_rotation > 3) {
|
||||
piece_rotation = 0;
|
||||
}
|
||||
get_node_locations();
|
||||
|
||||
// Check overlap without moving
|
||||
if (check_overlap()) {
|
||||
|
||||
// Check overlap after moving up 1
|
||||
piece_location[0]--;
|
||||
get_node_locations();
|
||||
if (check_overlap()) {
|
||||
|
||||
// Check overlap after moving down 1
|
||||
piece_location[0]++;
|
||||
piece_location[0]++;
|
||||
get_node_locations();
|
||||
if (check_overlap()) {
|
||||
|
||||
// Check overlap after moving left 1
|
||||
piece_location[0]--;
|
||||
piece_location[1]--;
|
||||
get_node_locations();
|
||||
if (check_overlap()) {
|
||||
|
||||
// Check overlap after moving right 1
|
||||
piece_location[1]++;
|
||||
piece_location[1]++;
|
||||
get_node_locations();
|
||||
if (check_overlap()) {
|
||||
piece_location[1]--;
|
||||
// This is Original Position
|
||||
|
||||
// If Line Piece, check 2 left, 2 right, 2 up and 2 down
|
||||
|
||||
// Check 2 left
|
||||
if (piece == 1 && piece_rotation == 0) {
|
||||
piece_location[1]-=2;
|
||||
get_node_locations();
|
||||
if (check_overlap()) {
|
||||
piece_location[1]+=2;
|
||||
get_node_locations();
|
||||
}
|
||||
// Check 2 up
|
||||
} else if (piece == 1 && piece_rotation == 1) {
|
||||
piece_location[0]+=2;
|
||||
get_node_locations();
|
||||
if (check_overlap()) {
|
||||
piece_location[0]-=2;
|
||||
get_node_locations();
|
||||
}
|
||||
// Check 2 right
|
||||
} else if (piece == 1 && piece_rotation == 2) {
|
||||
piece_location[1]+=2;
|
||||
get_node_locations();
|
||||
if (check_overlap()) {
|
||||
piece_location[1]-=2;
|
||||
get_node_locations();
|
||||
}
|
||||
// Check 2 down
|
||||
} else if (piece == 1 && piece_rotation == 3) {
|
||||
piece_location[0]-=2;
|
||||
get_node_locations();
|
||||
if (check_overlap()) {
|
||||
piece_location[0]+=2;
|
||||
get_node_locations();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if nodes are outside of map or interposed onto placed nodes
|
||||
static bool check_overlap(void) {
|
||||
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
||||
int* p = piece_nodes[i];
|
||||
if (p[0] < 0 || p[1] < 0 || p[1] >= width) {
|
||||
return true;
|
||||
} else if (board[p[0]][p[1]] != 0 && board[p[0]][p[1]] != 9) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void move_left(void) {
|
||||
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
||||
int* p = piece_nodes[i];
|
||||
if (p[1] == 0) {
|
||||
return;
|
||||
} else if (board[p[0]][p[1]-1] != 0 && board[p[0]][p[1]-1] != 9) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
piece_location[1]--;
|
||||
get_node_locations();
|
||||
}
|
||||
|
||||
static void move_right(void) {
|
||||
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
||||
int* p = piece_nodes[i];
|
||||
if (p[1] == width-1) {
|
||||
return;
|
||||
} else if (board[p[0]][p[1]+1] != 0 && board[p[0]][p[1]+1] != 9) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
piece_location[1]++;
|
||||
get_node_locations();
|
||||
}
|
||||
|
||||
static void drop(void) {
|
||||
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
||||
int* p = piece_nodes[i];
|
||||
if (p[0] == 0) {
|
||||
place_piece();
|
||||
check_line_clears();
|
||||
generate_block();
|
||||
return;
|
||||
} else if (board[p[0]-1][p[1]] != 0 && board[p[0]-1][p[1]] != 9) {
|
||||
place_piece();
|
||||
check_line_clears();
|
||||
generate_block();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
piece_location[0]--;
|
||||
get_node_locations();
|
||||
}
|
||||
|
||||
static void place_piece(void) {
|
||||
for (int h = 0; h < height; h++) {
|
||||
for (int w = 0; w < width; w++) {
|
||||
if (board[h][w] == 9) {
|
||||
board[h][w] = piece;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||
for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) {
|
||||
int* p = piece_nodes[i];
|
||||
lv_obj_align(piece_imgs[i], LV_ALIGN_BOTTOM_LEFT, 159, -(height*16));
|
||||
}
|
||||
xSemaphoreGive(xGuiSemaphore);
|
||||
}
|
||||
ESP_LOGI(TAG, "Placed Piece: %d", piece);
|
||||
}
|
||||
|
||||
static void get_node_locations() {
|
||||
piece_nodes[0][0] = piece_location[0];
|
||||
piece_nodes[0][1] = piece_location[1];
|
||||
if (piece == 1) {
|
||||
piece_nodes[0][0] = piece_location[0]-bacd(piece_rotation);
|
||||
piece_nodes[0][1] = piece_location[1]+acdb(piece_rotation);
|
||||
|
||||
piece_nodes[1][0] = piece_location[0]-bbcc(piece_rotation);
|
||||
piece_nodes[1][1] = piece_location[1]+bccb(piece_rotation);
|
||||
|
||||
piece_nodes[2][0] = piece_location[0]-bccb(piece_rotation);
|
||||
piece_nodes[2][1] = piece_location[1]+ccbb(piece_rotation);
|
||||
|
||||
piece_nodes[3][0] = piece_location[0]-bdca(piece_rotation);
|
||||
piece_nodes[3][1] = piece_location[1]+dcab(piece_rotation);
|
||||
} else if (piece == 2) {
|
||||
piece_nodes[1][0] = piece_location[0]-babc(piece_rotation);
|
||||
piece_nodes[1][1] = piece_location[1]+abcb(piece_rotation);
|
||||
|
||||
piece_nodes[2][0] = piece_location[0]+babc(piece_rotation);
|
||||
piece_nodes[2][1] = piece_location[1]-abcb(piece_rotation);
|
||||
|
||||
piece_nodes[3][0] = piece_location[0]-aacc(piece_rotation);
|
||||
piece_nodes[3][1] = piece_location[1]+acca(piece_rotation);
|
||||
} else if (piece == 3) {
|
||||
piece_nodes[1][0] = piece_location[0]-babc(piece_rotation);
|
||||
piece_nodes[1][1] = piece_location[1]+abcb(piece_rotation);
|
||||
|
||||
piece_nodes[2][0] = piece_location[0]+babc(piece_rotation);
|
||||
piece_nodes[2][1] = piece_location[1]-abcb(piece_rotation);
|
||||
|
||||
piece_nodes[3][0] = piece_location[0]-acca(piece_rotation);
|
||||
piece_nodes[3][1] = piece_location[1]-aacc(piece_rotation);
|
||||
} else if (piece == 4) {
|
||||
piece_nodes[1][0] = piece_location[0]+1;
|
||||
piece_nodes[1][1] = piece_location[1];
|
||||
|
||||
piece_nodes[2][0] = piece_location[0];
|
||||
piece_nodes[2][1] = piece_location[1]+1;
|
||||
|
||||
piece_nodes[3][0] = piece_location[0]+1;
|
||||
piece_nodes[3][1] = piece_location[1]+1;
|
||||
} else if (piece == 5) {
|
||||
piece_nodes[1][0] = piece_location[0]-babc(piece_rotation);
|
||||
piece_nodes[1][1] = piece_location[1]+abcb(piece_rotation);
|
||||
|
||||
piece_nodes[2][0] = piece_location[0]-abcb(piece_rotation);
|
||||
piece_nodes[2][1] = piece_location[1]-babc(piece_rotation);
|
||||
|
||||
piece_nodes[3][0] = piece_location[0]-acca(piece_rotation);
|
||||
piece_nodes[3][1] = piece_location[1]-aacc(piece_rotation);
|
||||
} else if (piece == 6) {
|
||||
piece_nodes[1][0] = piece_location[0]-babc(piece_rotation);
|
||||
piece_nodes[1][1] = piece_location[1]+abcb(piece_rotation);
|
||||
|
||||
piece_nodes[2][0] = piece_location[0]-abcb(piece_rotation);
|
||||
piece_nodes[2][1] = piece_location[1]-babc(piece_rotation);
|
||||
|
||||
piece_nodes[3][0] = piece_location[0]+babc(piece_rotation);
|
||||
piece_nodes[3][1] = piece_location[1]-abcb(piece_rotation);
|
||||
} else if (piece == 7) {
|
||||
piece_nodes[1][0] = piece_location[0]+babc(piece_rotation);
|
||||
piece_nodes[1][1] = piece_location[1]-abcb(piece_rotation);
|
||||
|
||||
piece_nodes[2][0] = piece_location[0]-abcb(piece_rotation);
|
||||
piece_nodes[2][1] = piece_location[1]-babc(piece_rotation);
|
||||
|
||||
piece_nodes[3][0] = piece_location[0]-aacc(piece_rotation);
|
||||
piece_nodes[3][1] = piece_location[1]+acca(piece_rotation);
|
||||
}
|
||||
}
|
||||
|
||||
static void check_line_clears(void) {
|
||||
for (int h = height-2; h >= 0; h--) {
|
||||
for (int w = 0; w < width; w++) {
|
||||
if (board[h][w] != 0 && board[h][w] != 9) {
|
||||
if (w == width-1) {
|
||||
line_clear(h);
|
||||
new_puzzle();
|
||||
int strike_time = xTaskGetTickCount();
|
||||
bool striked = false;
|
||||
while(solved_times < 4) {
|
||||
// for every bit in the answer-
|
||||
set_module_sseg_raw(display_map);
|
||||
if (get_pressed_keypad(&key)) {
|
||||
lcd_clear(&lcd);
|
||||
char c = char_of_keypad_key(key);
|
||||
// ESP_LOGI(TAG, "Pressed: %c", c);
|
||||
if (c == answer_char) {
|
||||
play_raw(MOUNT_POINT "/correct.pcm");
|
||||
solved_times++;
|
||||
if (solved_times < 3) {
|
||||
clean_bomb();
|
||||
new_puzzle();
|
||||
} else {
|
||||
uint8_t display_tmp[4] = {0b00000000, 0b00000000, 0b00000000, 0b00000000};
|
||||
set_module_sseg_raw(display_tmp);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
strike_time = xTaskGetTickCount();
|
||||
striked = true;
|
||||
strike("Incorrect Character!");
|
||||
}
|
||||
}
|
||||
|
||||
static void update_score(void) {
|
||||
char buff[16] = {};
|
||||
sprintf(buff, "%d/%d", score, target_score);
|
||||
if (xTaskGetTickCount() - strike_time > pdMS_TO_TICKS(5000)) {
|
||||
striked = false;
|
||||
lcd_clear(&lcd);
|
||||
lcd_set_cursor(&lcd, 1, 1);
|
||||
lcd_print(&lcd, buff);
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
|
||||
static void line_clear(int hi) {
|
||||
for (int h = hi; h < height; h++) {
|
||||
for (int w = 0; w < width; w++) {
|
||||
board[h][w] = board[h+1][w];
|
||||
}
|
||||
}
|
||||
for (int w = 0; w < width; w++) {
|
||||
board[height-1][w] = 0;
|
||||
}
|
||||
score++;
|
||||
update_score();
|
||||
|
||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||
lv_obj_align(line_clear_img, LV_ALIGN_BOTTOM_LEFT, 159, -(hi*16));
|
||||
xSemaphoreGive(xGuiSemaphore);
|
||||
}
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||
lv_obj_clear_flag(line_clear_img, LV_OBJ_FLAG_HIDDEN);
|
||||
xSemaphoreGive(xGuiSemaphore);
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(300));
|
||||
if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||
lv_obj_add_flag(line_clear_img, LV_OBJ_FLAG_HIDDEN);
|
||||
xSemaphoreGive(xGuiSemaphore);
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(300));
|
||||
}
|
||||
}
|
||||
|
||||
void clear_board(void) {
|
||||
for (int h = 0; h < height; h++) {
|
||||
for (int w = 0; w < width; w++) {
|
||||
board[h][w] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,22 +1,15 @@
|
||||
#ifndef STEP_2_H
|
||||
#define STEP_2_H
|
||||
|
||||
#include <random>
|
||||
#include "../drivers/tft.h"
|
||||
#include "../drivers/speaker.h"
|
||||
#include "../drivers/bottom_half.h"
|
||||
#include "../drivers/game_timer.h"
|
||||
#include "../drivers/wires.h"
|
||||
#include "../drivers/char_lcd.h"
|
||||
#include "../drivers/game_timer.h"
|
||||
#include "../drivers/leds.h"
|
||||
#include "../drivers/speaker.h"
|
||||
#include "../helper.h"
|
||||
|
||||
// TODO:
|
||||
// - [ ] set up real game loop
|
||||
// - [ ] stop music
|
||||
// - [ ] set up strike on falure
|
||||
// - [ ] set up module timer
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <map>
|
||||
|
||||
void step2(void);
|
||||
|
||||
|
||||
1300
main/steps/step3.cpp
1300
main/steps/step3.cpp
File diff suppressed because it is too large
Load Diff
@ -1,21 +1,14 @@
|
||||
#ifndef STEP_3_H
|
||||
#define STEP_3_H
|
||||
|
||||
#include "../drivers/bottom_half.h"
|
||||
#include "../drivers/game_timer.h"
|
||||
#include "../drivers/char_lcd.h"
|
||||
#include "../drivers/leds.h"
|
||||
#include "../drivers/wires.h"
|
||||
#include "../helper.h"
|
||||
#include <random>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <array>
|
||||
|
||||
static const char *STEP3_TAG = "step3";
|
||||
#include "../drivers/bottom_half.h"
|
||||
#include "../drivers/wires.h"
|
||||
#include "../drivers/speaker.h"
|
||||
#include "../drivers/leds.h"
|
||||
#include "../drivers/char_lcd.h"
|
||||
#include "../drivers/game_timer.h"
|
||||
#include "../helper.h"
|
||||
|
||||
void step3(void);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -2,14 +2,22 @@
|
||||
#define STEP_4_H
|
||||
|
||||
#include <random>
|
||||
#include "../drivers/bottom_half.h"
|
||||
#include "../drivers/wires.h"
|
||||
#include "../drivers/tft.h"
|
||||
#include "../drivers/speaker.h"
|
||||
#include "../drivers/leds.h"
|
||||
#include "../drivers/char_lcd.h"
|
||||
#include "../drivers/bottom_half.h"
|
||||
#include "../drivers/game_timer.h"
|
||||
#include "../drivers/wires.h"
|
||||
#include "../drivers/char_lcd.h"
|
||||
#include "../helper.h"
|
||||
|
||||
// TODO:
|
||||
// - [ ] set up real game loop
|
||||
// - [ ] stop music
|
||||
// - [ ] set up strike on falure
|
||||
// - [ ] set up module timer
|
||||
|
||||
|
||||
|
||||
void step4(void);
|
||||
|
||||
#endif /* STEP_4_H */
|
||||
1039
main/steps/step5.cpp
1039
main/steps/step5.cpp
File diff suppressed because it is too large
Load Diff
@ -2,14 +2,18 @@
|
||||
#define STEP_5_H
|
||||
|
||||
#include "../drivers/bottom_half.h"
|
||||
#include "../drivers/wires.h"
|
||||
#include "../drivers/game_timer.h"
|
||||
#include "../drivers/char_lcd.h"
|
||||
#include "../drivers/leds.h"
|
||||
#include "../drivers/speaker.h"
|
||||
#include "../drivers/wires.h"
|
||||
#include "../helper.h"
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <array>
|
||||
|
||||
void step5(void);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user