From cc6f9bb2d133aaa30386bc0b2bc7abe916b23ddf Mon Sep 17 00:00:00 2001 From: Rorikstr | Rust Dev Date: Wed, 1 Oct 2025 00:01:44 +0300 Subject: [PATCH] Decomposed and fixed saves --- .gitignore | 1 + src/brick_game/tetris/01_automato.h | 3 +- src/brick_game/tetris/02_tetris.c | 2 +- src/brick_game/tetris/04_init.c | 21 ++++--- src/brick_game/tetris/05_spawn.c | 17 ++++-- src/brick_game/tetris/06_move.c | 14 ++++- src/brick_game/tetris/07_moving.c | 88 ++++++++++++++++++---------- src/brick_game/tetris/08_attaching.c | 36 ++++++------ src/brick_game/tetris/09_gameover.c | 2 +- 9 files changed, 112 insertions(+), 72 deletions(-) diff --git a/.gitignore b/.gitignore index 29297c0..9a1be82 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,4 @@ ginpee.toml src/ginpee.toml .vscode/launch.json src/tetris.log +src/high_score.txt diff --git a/src/brick_game/tetris/01_automato.h b/src/brick_game/tetris/01_automato.h index 0eb49a8..2ce371d 100644 --- a/src/brick_game/tetris/01_automato.h +++ b/src/brick_game/tetris/01_automato.h @@ -58,6 +58,7 @@ GameState_t* get_game_state(void); void do_init(void); int load_high_score(); void save_high_score(int score); +void generate_next_figure(void); // spawn void do_spawn(void); @@ -78,7 +79,6 @@ void clear_lines(); void do_gameover(void); int is_game_over(); - // Функции фигур const int (*get_figure_shape(Sprite_t sprite, int rotation))[4]; @@ -110,5 +110,4 @@ const int (*z_fig_down())[4]; const int (*z_fig_left())[4]; const int (*empty_fig())[4]; - #endif \ No newline at end of file diff --git a/src/brick_game/tetris/02_tetris.c b/src/brick_game/tetris/02_tetris.c index a114344..e37f674 100644 --- a/src/brick_game/tetris/02_tetris.c +++ b/src/brick_game/tetris/02_tetris.c @@ -12,7 +12,7 @@ void userInput(UserAction_t action, bool hold) { switch (action) { case Start: - if (state->info->score > state->info->high_score) { + if (state->info->score >= state->info->high_score) { state->info->high_score = state->info->score; save_high_score(state->info->high_score); } diff --git a/src/brick_game/tetris/04_init.c b/src/brick_game/tetris/04_init.c index 71d297f..64736b0 100644 --- a/src/brick_game/tetris/04_init.c +++ b/src/brick_game/tetris/04_init.c @@ -1,23 +1,22 @@ #include "01_automato.h" -void do_init(void) { +void clear_field(void) { GameState_t* state = get_game_state(); - - // Очищаем поле for (int i = 0; i < FIELD_HEIGHT; ++i) for (int j = 0; j < FIELD_WIDTH; ++j) state->field[i][j] = 0; +} +void reset_game_stats(void) { + GameState_t* state = get_game_state(); state->info->score = 0; state->info->level = 1; state->info->speed = 10; +} - state->next.sprite = rand() % FIGURE_COUNT; - state->next.rotation = 0; - const int (*shape)[4] = get_figure_shape(state->next.sprite, 0); - for (int i = 0; i < 4; ++i) - for (int j = 0; j < 4; ++j) - state->next.mtrx[i][j] = shape[i][j]; - - state->state = Spawn; // Переход в Spawn +void do_init(void) { + clear_field(); + reset_game_stats(); + generate_next_figure(); + get_game_state()->state = Spawn; // Переход в Spawn } \ No newline at end of file diff --git a/src/brick_game/tetris/05_spawn.c b/src/brick_game/tetris/05_spawn.c index f8ffa57..bd4b74f 100644 --- a/src/brick_game/tetris/05_spawn.c +++ b/src/brick_game/tetris/05_spawn.c @@ -1,24 +1,31 @@ #include "01_automato.h" -void do_spawn(void) { +void set_current_figure_from_next(void) { GameState_t* state = get_game_state(); - state->curr = state->next; state->curr.x = FIELD_WIDTH / 2 - 2; state->curr.y = 0; state->moving_type = DoNothing; +} +void generate_next_figure(void) { + GameState_t* state = get_game_state(); state->next.sprite = rand() % FIGURE_COUNT; state->next.rotation = 0; const int (*shape)[4] = get_figure_shape(state->next.sprite, 0); for (int i = 0; i < 4; ++i) for (int j = 0; j < 4; ++j) state->next.mtrx[i][j] = shape[i][j]; +} +void do_spawn(void) { + set_current_figure_from_next(); + generate_next_figure(); + if (check_collision()) { - state->state = GameOver; - return; + get_game_state()->state = GameOver; + return; // TODO } - state->state = Move; + get_game_state()->state = Move; } \ No newline at end of file diff --git a/src/brick_game/tetris/06_move.c b/src/brick_game/tetris/06_move.c index a795590..f3b6539 100644 --- a/src/brick_game/tetris/06_move.c +++ b/src/brick_game/tetris/06_move.c @@ -1,13 +1,21 @@ -// brick_game/tetris/06_move.c #include "01_automato.h" +int get_frames_to_wait(void) { + GameState_t* state = get_game_state(); + if (state->moving_type == ToDown) { + return 1; // TODO + } else { + return 1000 / state->info->speed; // TODO + } +} + void do_move(void) { GameState_t* state = get_game_state(); - int frames_to_wait = (state->moving_type == ToDown) ? 1 : (1000 / state->info->speed); + int frames_to_wait = get_frames_to_wait(); if (state->frame_count - state->last_move_frame < frames_to_wait) { - return; + return; // TODO } state->last_move_frame = state->frame_count; diff --git a/src/brick_game/tetris/07_moving.c b/src/brick_game/tetris/07_moving.c index af47c2f..ca6d25f 100644 --- a/src/brick_game/tetris/07_moving.c +++ b/src/brick_game/tetris/07_moving.c @@ -1,47 +1,73 @@ #include "01_automato.h" +void handle_move_direction(Moving_t direction) { + GameState_t* state = get_game_state(); + switch (direction) { + case LeftDown: + state->curr.x--; + break; + case RightDown: + state->curr.x++; + break; + default: + break; + } +} + +void handle_rotate(void) { + GameState_t* state = get_game_state(); + state->curr.rotation = (state->curr.rotation + 1) % 4; + const int (*shape)[4] = get_figure_shape(state->curr.sprite, state->curr.rotation); + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 4; ++j) + state->curr.mtrx[i][j] = shape[i][j]; +} + +void handle_horizontal_rotate_move(void) { + GameState_t* state = get_game_state(); + Figure_t old = state->curr; + + switch (state->moving_type) { + case LeftDown: + case RightDown: + handle_move_direction(state->moving_type); + break; + case Rotate: + handle_rotate(); + break; + default: + break; + } + + if (check_collision()) { + state->curr = old; + } + state->state = Move; +} + +void handle_to_down_move(void) { + GameState_t* state = get_game_state(); + while (!check_collision()) { + state->curr.y++; + } + state->curr.y--; + state->state = Attaching; +} + void do_moving(void) { GameState_t* state = get_game_state(); switch (state->moving_type) { case LeftDown: case RightDown: - case (Rotate): { - Figure_t old = state->curr; - switch (state->moving_type) { - case LeftDown: - state->curr.x--; - break; - case RightDown: - state->curr.x++; - break; - case Rotate: - state->curr.rotation = (state->curr.rotation + 1) % 4; - const int (*shape)[4] = get_figure_shape(state->curr.sprite, state->curr.rotation); - for (int i = 0; i < 4; ++i) - for (int j = 0; j < 4; ++j) - state->curr.mtrx[i][j] = shape[i][j]; - break; - default: - break; - } - if (check_collision()) { - state->curr = old; - } - state->state = Move; + case Rotate: + handle_horizontal_rotate_move(); break; - } case ToDown: - while (!check_collision()) { - state->curr.y++; - } - state->curr.y--; - state->state = Attaching; + handle_to_down_move(); break; - case DoNothing: state->state = Move; break; } - state->state = Move; } \ No newline at end of file diff --git a/src/brick_game/tetris/08_attaching.c b/src/brick_game/tetris/08_attaching.c index e0252e1..59396ff 100644 --- a/src/brick_game/tetris/08_attaching.c +++ b/src/brick_game/tetris/08_attaching.c @@ -22,10 +22,10 @@ int check_collision() { int y = fig->y + i; if (x < 0 || x >= FIELD_WIDTH || y >= FIELD_HEIGHT) { - return 1; + return 1; // TODO } if (y >= 0 && state->field[y][x]) { - return 1; + return 1; // TODO } } } @@ -34,7 +34,6 @@ int check_collision() { } void place_figure() { - GameState_t* state = get_game_state(); Figure_t* fig = &state->curr; @@ -51,10 +50,20 @@ void place_figure() { } } -void clear_lines() { - +void shift_lines_down(int from_row) { + GameState_t* state = get_game_state(); + for (int y = from_row; y > 0; --y) { + for (int x = 0; x < FIELD_WIDTH; ++x) { + state->field[y][x] = state->field[y - 1][x]; + } + } + for (int x = 0; x < FIELD_WIDTH; ++x) { + state->field[0][x] = 0; + } +} + +void clear_lines() { GameState_t* state = get_game_state(); - int lines_cleared = 0; for (int i = FIELD_HEIGHT - 1; i >= 0; --i) { @@ -62,20 +71,13 @@ void clear_lines() { for (int j = 0; j < FIELD_WIDTH; ++j) { if (state->field[i][j] != 2) { full = 0; - break; + break; // TODO } } if (full) { - for (int y = i; y > 0; --y) { - for (int x = 0; x < FIELD_WIDTH; ++x) { - state->field[y][x] = state->field[y - 1][x]; - } - } - for (int x = 0; x < FIELD_WIDTH; ++x) { - state->field[0][x] = 0; - } + shift_lines_down(i); lines_cleared++; - i++; + i++; // Check the same row again after shifting } } @@ -90,9 +92,7 @@ void clear_lines() { if (new_level > state->info->level) { state->info->level = new_level; - state->info->speed = new_level * 10; - return; } } } \ No newline at end of file diff --git a/src/brick_game/tetris/09_gameover.c b/src/brick_game/tetris/09_gameover.c index 4dbcf21..ba34b03 100644 --- a/src/brick_game/tetris/09_gameover.c +++ b/src/brick_game/tetris/09_gameover.c @@ -19,7 +19,7 @@ int is_game_over() { GameState_t* state = get_game_state(); for (int j = 0; j < FIELD_WIDTH; ++j) { if (state->field[0][j] || state->field[1][j]) { - return 1; + return 1; // TODO } }