#include "step2.h" static const char *TAG = "step2"; static lv_obj_t* scr; 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 bool game = true; 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}, }; static lv_color_t piece_colors[] = { (lv_color_t { .full = 0xfee0 }), }; std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<> piece_dist(2, 7); static void generate_block(void); static void show_board(void); static void get_node_locations(void); static void line_clear(int height); static void check_line_clears(void); static void place_piece(void); static void move_left(void); static void move_right(void); static void drop(void); static void rotate_block(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 init_screen(void) { LV_IMG_DECLARE(tetris); // scr = lv_obj_create(screen); // img = lv_img_create(lv_scr_act()); // lv_img_set_src(img, &tetris); // lv_obj_align(img, LV_ALIGN_CENTER, 0, 0); img = lv_img_create(lv_scr_act()); lv_img_set_src(img, "A:/sdcard/db.bin"); lv_obj_align(img, LV_ALIGN_CENTER, 0, 0); // play_raw(MOUNT_POINT "/tetris.pcm"); } static void deinit_screen(void) { lv_obj_clean(scr); } void step2(void) { init_screen(); generate_block(); ButtonKey button; SwitchKey switch_; while(game) { if (get_pressed_button(&button)) { switch (button) { case ButtonKey::b1: move_left(); break; case ButtonKey::b2: move_right(); break; case ButtonKey::b3: drop(); break; case ButtonKey::b4: rotate_block(); break; } show_board(); } 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("PieceRotaition: %d\n", piece_rotation); } vTaskDelay(pdMS_TO_TICKS(10)); } // game over ESP_LOGI(TAG, "Game Over. Score: %d", score); 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"); } else { } } 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] = 20; 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; } } } } } static void rotate_block(void) { piece_rotation++; if (piece_rotation > 3) { piece_rotation = 0; } get_node_locations(); bool overlap = false; for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) { int* p = piece_nodes[i]; if (p[0] < 0) { overlap = true; break; } else if (board[p[0]][p[1]] != 0 && board[p[0]][p[1]] != 9) { overlap = true; break; } } if (overlap) { piece_location[0]++; get_node_locations(); bool overlap2 = false; for (int i = 0; i < sizeof(piece_nodes)/sizeof(piece_nodes[0]); i++) { int* p = piece_nodes[i]; if (p[0] < 0) { overlap2 = true; break; } else if (board[p[0]][p[1]] != 0 && board[p[0]][p[1]] != 9) { overlap2 = true; break; } } if (overlap2) { piece_rotation--; if (piece_rotation < 0) { piece_rotation += 4; } piece_location[0]--; get_node_locations(); } } } 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; } } } 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); } } else { break; } } } } static void line_clear(int height) { for (int h = height; h < height-1; h++) { for (int w = 0; w < width; w++) { board[h][w] = board[h+1][w]; } } score++; }