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

View file

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

View file

@ -3,10 +3,11 @@
static GameState_t g_state = {0};
GameState_t* get_game_state(void) {
static int initialized = 0;
if (!initialized) {
static GameInfo_t instance = {0};
static int is_init = 0;
if (!is_init) {
g_state.state = GameOver;
initialized = 1;
is_init = 1;
}
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->next.type = rand() % FIGURE_COUNT;
state->next.sprite = rand() % FIGURE_COUNT;
state->next.rotation = 0;
const int (*shape)[4] = get_figure_shape(state->next.type, 0);
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
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];
// Проверка на GameOver

View file

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

View file

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

View file

@ -1,9 +1,9 @@
#include "01_automato.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;
switch (type) {
switch (sprite) {
case I:
switch (rotation % 4) {
case 0: result = i_fig_up(); break;

View file

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

View file

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