This commit is contained in:
Rorikstr | Rust Dev 2025-09-29 15:20:21 +03:00
parent f8e1e664a7
commit 5fd528e22a
11 changed files with 78 additions and 67 deletions

View file

@ -13,6 +13,13 @@ typedef enum {
GameOver GameOver
} Automato_t; } Automato_t;
typedef enum {
RightDown,
LeftDown,
Rotate,
DoNothing
} Moving_t;
typedef enum { typedef enum {
I = 0, I = 0,
J, J,
@ -22,31 +29,32 @@ typedef enum {
T, T,
Z, Z,
FIGURE_COUNT FIGURE_COUNT
} FigureType; } Sprite_t;
typedef struct { typedef struct {
int x, y; // Позиция фигуры на поле int x, y; // Позиция фигуры на поле
int mtrx[4][4]; // сама матрица int mtrx[4][4]; // сама матрица
FigureType type; // Тип фигуры Sprite_t sprite; // Тип фигуры
int rotation; // Поворот (03) int rotation; // Поворот (03)
} Figure; } Figure_t;
typedef struct { typedef struct {
Figure curr; Figure_t curr;
Figure next; Figure_t next;
Automato_t state; Automato_t state;
Moving_t moving_type;
int field[FIELD_HEIGHT][FIELD_WIDTH]; int field[FIELD_HEIGHT][FIELD_WIDTH];
int score; // int score; // НЕ НУЖЕН, это уже есть в GameInfo_t
int high_score; // int high_score; // НЕ НУЖЕН, это уже есть в GameInfo_t
int level; // int level; // НЕ НУЖЕН, это уже есть в GameInfo_t
int speed; // int speed; // НЕ НУЖЕН, это уже есть в GameInfo_t
long long last_time; long long last_time; // нужно пояснение для чего это
} GameState_t; } GameState_t;
GameState_t* get_game_state(void); GameState_t* get_game_state(void);
// Функции состояний // Функции состояний
void do_start(void); void do_init(void);
void do_spawn(void); void do_spawn(void);
void do_move(void); void do_move(void);
void do_moving(void); void do_moving(void);
@ -54,13 +62,13 @@ void do_attaching(void);
void do_gameover(void); void do_gameover(void);
// Вспомогательные // Вспомогательные
void place_figure_on_field(); void place_figure();
int check_collision(); int check_collision();
void clear_lines(); void clear_lines();
int is_game_over(); int is_game_over();
// Функции фигур // Функции фигур
const int (*get_figure_shape(FigureType type, int rotation))[4]; const int (*get_figure_shape(Sprite_t sprite, int rotation))[4];
// Остальные фигуры... // Остальные фигуры...
const int (*i_fig_up())[4]; const int (*i_fig_up())[4];

View file

@ -2,37 +2,43 @@
#include <stdlib.h> #include <stdlib.h>
void userInput(UserAction_t action, bool hold) { void userInput(UserAction_t action, bool hold) {
GameState_t* state = get_game_state(); GameState_t* g_state = get_game_state();
GameInfo_t* g_info = get_info_state();
switch (action) { switch (action) {
case Start: case Start:
state->state = Start; g_state->state = Init;
break; break;
case Terminate: case Terminate:
if (state->score > state->high_score) { if (g_info->score > g_info->high_score) {
state->high_score = state->score; g_info->high_score = g_info->score;
} }
exit(0);
break; break;
case Left: case Left:
g_state->state = Moving;
g_state->moving_type = LeftDown;
break;
case Right: case Right:
g_state->state = Moving;
g_state->moving_type = RightDown;
break;
case Action: case Action:
state->state = Moving; g_state->state = Moving;
g_state->moving_type = Rotate;
break; break;
case Down: case Down:
// Ускорение падения — будет обрабатываться в do_move // Ускорение падения — будет обрабатываться в do_move
break; break;
case Pause: default:
// Обработка на UI break; // pause и down - не нужны в backend логике.
break;
} }
} }
GameInfo_t updateCurrentState() { GameInfo_t updateCurrentState() {
GameState_t* state = get_game_state(); GameState_t* g_state = get_game_state();
switch (state->state) { switch (g_state->state) {
case Start: case Start:
do_start(); do_init();
break; break;
case Spawn: case Spawn:
do_spawn(); do_spawn();
@ -52,12 +58,8 @@ GameInfo_t updateCurrentState() {
} }
GameInfo_t info = {0}; GameInfo_t info = {0};
info.field = (int**)state->field; info.field = (int**)g_state->field;
info.next = (int**)state->next.mtrx; // теперь next.mtrx info.next = (int**)g_state->next.mtrx; // теперь next.mtrx
info.score = state->score;
info.high_score = state->high_score;
info.level = state->level;
info.speed = state->speed;
info.pause = 0; info.pause = 0;
return info; return info;
} }

View file

@ -3,10 +3,11 @@
static GameState_t g_state = {0}; static GameState_t g_state = {0};
GameState_t* get_game_state(void) { GameState_t* get_game_state(void) {
static int initialized = 0; static GameInfo_t instance = {0};
if (!initialized) { static int is_init = 0;
if (!is_init) {
g_state.state = GameOver; g_state.state = GameOver;
initialized = 1; is_init = 1;
} }
return &g_state; return &g_state;
} }

View file

@ -0,0 +1,15 @@
#include "01_automato.h"
void do_init(void) {
GameState_t* g_state = get_game_state();
GameInfo_t* g_info = get_game_info();
// Очистка поля
for (int i = 0; i < FIELD_HEIGHT; ++i)
for (int j = 0; j < FIELD_WIDTH; ++j)
g_state->field[i][j] = 0;
g_info->score = 0;
g_info->level = 1;
g_info->speed = 1;
g_state->state = Spawn;
}

View file

@ -1,14 +0,0 @@
#include "01_automato.h"
void do_start(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;
state->score = 0;
state->level = 1;
state->speed = 1;
state->state = Spawn;
}

View file

@ -9,11 +9,11 @@ void do_spawn(void) {
state->curr.y = 0; state->curr.y = 0;
// Генерим следующую фигуру // Генерим следующую фигуру
state->next.type = rand() % FIGURE_COUNT; state->next.sprite = rand() % FIGURE_COUNT;
state->next.rotation = 0; state->next.rotation = 0;
const int (*shape)[4] = get_figure_shape(state->next.type, 0); const int (*shape)[4] = get_figure_shape(state->next.sprite, 0);
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; j++) for (int j = 0; j < 4; ++j)
state->next.mtrx[i][j] = shape[i][j]; state->next.mtrx[i][j] = shape[i][j];
// Проверка на GameOver // Проверка на GameOver

View file

@ -3,17 +3,16 @@
void do_attaching(void) { void do_attaching(void) {
GameState_t* state = get_game_state(); GameState_t* state = get_game_state();
// Закрепляем фигуру на поле // Закрепляем фигуру на поле
place_figure_on_field(); place_figure();
// Удаляем линии // Удаляем линии
clear_lines(); clear_lines();
// Проверяем GameOver // Проверяем GameOver
int is_gameov = 0;
if (is_game_over()) { if (is_game_over()) {
state->state = GameOver; state->state = GameOver;
return; } else {
state->state = Spawn;
} }
// Переход в Spawn
state->state = Spawn;
} }

View file

@ -3,7 +3,7 @@
void do_gameover(void) { void do_gameover(void) {
GameState_t* state = get_game_state(); GameState_t* state = get_game_state();
// Сброс next в пустую фигуру // Сброс next в пустую фигуру
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; j++) for (int j = 0; j < 4; ++j)
state->next.mtrx[i][j] = 0; state->next.mtrx[i][j] = 0;
} }

View file

@ -1,9 +1,9 @@
#include "01_automato.h" #include "01_automato.h"
#include <string.h> #include <string.h>
const int (*get_figure_shape(FigureType type, int rotation))[4] { const int (*get_figure_shape(Sprite_t sprite, int rotation))[4] {
const int (*result)[4] = NULL; const int (*result)[4] = NULL;
switch (type) { switch (sprite) {
case I: case I:
switch (rotation % 4) { switch (rotation % 4) {
case 0: result = i_fig_up(); break; case 0: result = i_fig_up(); break;

View file

@ -1,6 +1,6 @@
// src/gui/cli/display.c // src/gui/cli/display.c
#include <ncurses.h> #include <ncurses.h>
#include "../../brick_game/tetris/tetris.h" #include "../../brick_game/tetris/00_tetris.h"
void display_game() { void display_game() {
printf("DEBUG: display_game called\n"); printf("DEBUG: display_game called\n");
@ -12,8 +12,8 @@ void display_game() {
game_state.field, game_state.next); game_state.field, game_state.next);
// Отображение игрового поля // Отображение игрового поля
for (int i = 0; i < FIELD_HEIGHT; i++) { for (int i = 0; i < FIELD_HEIGHT; ++i) {
for (int j = 0; j < FIELD_WIDTH; j++) { for (int j = 0; j < FIELD_WIDTH; ++j) {
if (game_state.field[i][j] == 2) { if (game_state.field[i][j] == 2) {
mvaddch(i + 1, j * 2 + 1, '#'); // Закрепленные блоки mvaddch(i + 1, j * 2 + 1, '#'); // Закрепленные блоки
} else if (game_state.field[i][j] == 1) { } else if (game_state.field[i][j] == 1) {
@ -27,8 +27,8 @@ void display_game() {
// Отображение следующей фигуры // Отображение следующей фигуры
mvaddstr(1, FIELD_WIDTH * 2 + 5, "Next figure:"); mvaddstr(1, FIELD_WIDTH * 2 + 5, "Next figure:");
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; ++j) {
if (game_state.next[i][j]) { if (game_state.next[i][j]) {
mvaddch(i + 3, (FIELD_WIDTH * 2 + 5) + j * 2, '@'); mvaddch(i + 3, (FIELD_WIDTH * 2 + 5) + j * 2, '@');
} else { } else {

View file

@ -2,7 +2,7 @@
#include <ncurses.h> #include <ncurses.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include "../../brick_game/tetris/tetris.h" #include "../../brick_game/tetris/00_tetris.h"
void display_game(); void display_game();