From 2d3a51877ba45ed5a64d2c9acee3d3300f55c5fa Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Sat, 13 Apr 2019 17:12:12 -0400 Subject: general cleanup and add ghost piece for preview --- "core/\\" | 277 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 "core/\\" (limited to 'core/\') diff --git "a/core/\\" "b/core/\\" new file mode 100644 index 0000000..80e819a --- /dev/null +++ "b/core/\\" @@ -0,0 +1,277 @@ +#include + +#include "matrix.h" +#include "types.h" +#include "cetris.h" + +/* SRS WALL KICK VALUES */ + +// https://tetris.wiki/SRS +static const vec2 srs_wall_kicks[8][5] = { + { {0, 0}, {-1, 0}, {-1,1}, {0,-2}, {-1,-2} }, // 0->R + { {0, 0}, {1, 0}, {1,-1}, {0,2}, {1,2} }, // R->0 + { {0, 0}, {1, 0}, {1,-1}, {0,2}, {1,2} }, // R->2 + { {0, 0}, {-1, 0}, {-1,1}, {0,-2}, {-1,-2} }, // 2->R + { {0, 0}, {1, 0}, {1,1}, {0,-2}, {1,-2} }, // 2->L + { {0, 0}, {-1, 0}, {-1,-1}, {0,2}, {-1,2} }, // L->2 + { {0, 0}, {-1, 0}, {-1,-1}, {0,2}, {-1,2} }, // L->0 + { {0, 0}, {1, 0}, {1,1}, {0,-2}, {1,-2} } // 0->L +}; + +static const vec2 srs_wall_kicks_i[8][5] = { + { {0, 0}, {-2, 0}, {1, 0}, {-2,-1}, {1,2} }, // 0->R + { {0, 0}, {2, 0}, {-1, 0}, {2,1}, {-1,-2} }, // R->0 + { {0, 0}, {-1, 0}, {2, 0}, {-1,2}, {2,-1} }, // R->2 + { {0, 0}, {1, 0}, {-2, 0}, {1,-2}, {-2,1} }, // 2->R + { {0, 0}, {2, 0}, {-1, 0}, {2,1}, {-1,-2} }, // 2->L + { {0, 0}, {-2, 0}, {1, 0}, {-2,-1}, {1,2} }, // L->2 + { {0, 0}, {1, 0}, {-2, 0}, {1,-2}, {-2,1} }, // L->0 + { {0, 0}, {-1, 0}, {2, 0}, {-1,2}, {2,-1} } // 0->L +}; + +/* DEFAULT MATRIX FOR EACH POSSIBLE TETRIMINO */ + +const piece_matrix default_matrices[7] = { + { + { 0, 0, 0, 0 }, + { 0, 1, 1, 0 }, + { 0, 1, 1, 0 }, + { 0, 0, 0, 0 } + }, + + { + { 0, 0, 0, 0 }, + { 1, 1, 1, 1 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 } + }, + + { + { 0, 0, 0, 0 }, + { 0, 1, 1, 0 }, + { 1, 1, 0, 0 }, + { 0, 0, 0, 0 } + }, + + { + { 0, 0, 0, 0 }, + { 1, 1, 0, 0 }, + { 0, 1, 1, 0 }, + { 0, 0, 0, 0 } + }, + + { + { 0, 0, 0, 0 }, + { 0, 0, 1, 0 }, + { 1, 1, 1, 0 }, + { 0, 0, 0, 0 } + }, + + { + { 0, 0, 0, 0 }, + { 1, 0, 0, 0 }, + { 1, 1, 1, 0 }, + { 0, 0, 0, 0 } + }, + + { + { 0, 0, 0, 0 }, + { 0, 1, 0, 0 }, + { 1, 1, 1, 0 }, + { 0, 0, 0, 0 } + } +}; + +/* MATRIX MODIFICATION */ + +const vec2 basic_movements[4] = { + {0, 0}, {0, 1}, {1, 0}, {-1, 0} // NONE, DOWN, RIGHT, LEFT +}; + +void move_current(struct cetris_game* g, vec2 offset) { + if (g->game_over) return; +g->current.pos.y += offset.y; g->current.pos.x += offset.x; + + i8 check = check_new_matrix(g, g->current.m); + if (check <= 0) { + g->current.pos.y -= offset.y; + g->current.pos.x -= offset.x; + + if (check == -1 && g->current.lock_tick == 0) { + g->current.lock_tick = g->tick + 30; + } + } + + update_board(g); +} + +i8 overlay_matrix(struct cetris_game* g, piece_matrix m, bool set_board) { + for (i8 y = 0; y < 4; y++) { + for (i8 x = 0; x < 4; x++) { + vec2 r = (vec2){x + g->current.pos.x, y + g->current.pos.y}; + if (r.x > CETRIS_BOARD_X || r.x < 0 || r.y > CETRIS_BOARD_Y) + return 0; + if (m[y][x] && r.y >= 0) { + if (g->board[r.x][r.y].occupied) return -1; + if (set_board) { + g->board[r.x][r.y].occupied = 1; + g->board[r.x][r.y].c = g->current.c; + } + } + } + } + return 1; +} + +void hard_drop(struct cetris_game* g) { + if (g->game_over) return; + + bool drop = false; + u8 drop_count = 0; + while (!drop) { + g->current.pos.y++; + drop_count++; + i8 check = check_new_matrix(g, g->current.m); + if (check <= 0) { + g->current.pos.y--; + drop_count--; + drop = true; + } + } + + g->score += 2 * drop_count; // 2 score for each hard-drop'd cell + + update_board(g); + next_piece(g); +} + +void rotate_matrix(struct cetris_game* g, bool clockwise) { + if (g->game_over) return; + if (g->current.t == O) return; + + rstate next = 0; + u8 wall_kick = 0; + switch (g->current.r) { + case INIT: + if (clockwise) { + next = ONCE_RIGHT; + wall_kick = 0; + } else { + next = ONCE_LEFT; + wall_kick = 7; + } break; + case ONCE_RIGHT: + if (clockwise) { + next = TWICE; + wall_kick = 2; + } else { + next = INIT; + wall_kick = 1; + } break; + case ONCE_LEFT: + if (clockwise) { + next = INIT; + wall_kick = 6; + } else { + next = TWICE; + wall_kick = 5; + } break; + case TWICE: + if (clockwise) { + next = ONCE_LEFT; + wall_kick = 4; + } else { + next = ONCE_RIGHT; + wall_kick = 3; + } break; + } + + piece_matrix m; + memset(m, 0, sizeof(piece_matrix)); + + for (u8 x = 0; x < 4; x++) { + for (u8 y = 0; y < 4; y++) { + if (g->current.m[y][x]) { + u8 new_x = (clockwise) ? 1 - (y - 2) : 1 + (y - 2); + u8 new_y = (clockwise) ? 2 + (x - 1) : 2 - (x - 1); + + if (g->current.t == I) { + if (clockwise) new_y--; + else new_x++; + } + + m[new_y][new_x] = 1; + } + } + } + + vec2 kick; + bool set_current = false; + bool did_kick = false; + for (u8 i = 0; i < 5; i++) { + if (g->current.t == I) { + kick = srs_wall_kicks_i[wall_kick][i]; + } else { + kick = srs_wall_kicks[wall_kick][i]; + } + g->current.pos.x += kick.x; + g->current.pos.y += kick.y; + if (check_new_matrix(g, m) > 0) { + set_current = true; + if (i > 0) did_kick = true; + break; + } else { + g->current.pos.x -= kick.x; + g->current.pos.y -= kick.y; + } + } + + if (set_current) { + memcpy(g->current.m, m, sizeof(piece_matrix)); + + /* check for tspin */ + if (g->current.t == T) { + u8 did_tspin = 1; + for (int i = 0; i < 4; i++) { + g->current.pos.x += basic_movements[i].x; + g->current.pos.y += basic_movements[i].y; + + if (overlay_current_matrix(g, false) == 1) + did_tspin = 0; + + g->current.pos.x -= basic_movements[i].x; + g->current.pos.y -= basic_movements[i].y; + } + + if (did_tspin) { + if (did_kick) g->mini_tspin = 1; + else g->tspin = 1; + } + } + + g->current.r = next; + update_board(g); + } +} + + +/* +i8 check_new_matrix(struct cetris_game* g, piece_matrix m) { + for (u8 x = 0; x < 4; x++) { + for (u8 y = 0; y < 4; y++) { + vec2 r = (vec2){g->current.pos.x + x, g->current.pos.y + y}; + if (m[y][x]) { + if (r.x > CETRIS_BOARD_X - 1 || r.x < 0) + return 0; + + if (r.y > CETRIS_BOARD_Y - 1) + return -1; + + if (g->board[r.x][r.y].occupied && g->board[r.x][r.y].constant) + return -1; + } + } + } + return 1; +} +*/ -- cgit v1.2.3-101-g0448