works but with leaks
This commit is contained in:
parent
eaafb06836
commit
6b80483129
4 changed files with 231 additions and 225 deletions
25
src/Makefile
25
src/Makefile
|
|
@ -24,23 +24,30 @@ CLIDIR = gui/cli
|
||||||
|
|
||||||
# Файлы
|
# Файлы
|
||||||
TETRIS_SRC = $(shell find $(TETRISDIR) -name "*.c")
|
TETRIS_SRC = $(shell find $(TETRISDIR) -name "*.c")
|
||||||
|
TETRIS_OBJ = $(TETRIS_SRC:.c=.o)
|
||||||
CLI_SRC = $(shell find $(CLIDIR) -name "*.c")
|
CLI_SRC = $(shell find $(CLIDIR) -name "*.c")
|
||||||
ALL_SRC = $(TETRIS_SRC) $(CLI_SRC)
|
CLI_OBJ = $(CLI_SRC:.c=.o)
|
||||||
OBJ = $(ALL_SRC:.c=.o)
|
|
||||||
|
|
||||||
# Имя исполняемого файла
|
LIB_TETRIS = $(BUILDDIR)/libtetris.a
|
||||||
TARGET = tetris_bin
|
TARGET = $(BUILDDIR)/tetris_bin.out
|
||||||
|
|
||||||
# Установка
|
# Установка
|
||||||
PREFIX ?= /usr/local
|
PREFIX ?= /usr/local
|
||||||
BINDIR = $(PREFIX)/bin
|
BINDIR = $(PREFIX)/bin
|
||||||
|
|
||||||
all: $(TARGET)
|
all: clean $(TARGET)
|
||||||
|
|
||||||
$(TARGET): $(OBJ)
|
$(LIB_TETRIS): $(TETRIS_OBJ)
|
||||||
$(CC) $(OBJ) -o $@ $(LDFLAGS)
|
mkdir -p $(BUILDDIR)
|
||||||
|
ar rcs $@ $^
|
||||||
|
|
||||||
%.o: %.c
|
$(TARGET): $(LIB_TETRIS) $(CLI_OBJ)
|
||||||
|
$(CC) $(CLI_OBJ) -L$(BUILDDIR) -ltetris -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
|
brick_game/tetris/%.o: brick_game/tetris/%.c
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
gui/cli/%.o: gui/cli/%.c
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
install: $(TARGET)
|
install: $(TARGET)
|
||||||
|
|
@ -50,7 +57,7 @@ uninstall:
|
||||||
rm -f $(BINDIR)/$(TARGET)
|
rm -f $(BINDIR)/$(TARGET)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJ) $(TARGET) *.gcda *.gcno *.gcov
|
rm -f $(CLI_OBJ) $(TETRIS_OBJ) $(TARGET) *.gcda *.gcno *.gcov
|
||||||
|
|
||||||
test:
|
test:
|
||||||
@echo "Running tests..."
|
@echo "Running tests..."
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
// static bool initialized = false;
|
|
||||||
|
|
||||||
static GameStateData* get_instance() {
|
static GameStateData* get_instance() {
|
||||||
static GameStateData instance = {0};
|
static GameStateData instance = {0};
|
||||||
static bool initialized_local = false;
|
static bool initialized_local = false;
|
||||||
|
|
@ -21,8 +19,7 @@ static GameStateData* get_instance() {
|
||||||
instance.score = 0;
|
instance.score = 0;
|
||||||
instance.high_score = 0;
|
instance.high_score = 0;
|
||||||
instance.level = 1;
|
instance.level = 1;
|
||||||
instance.speed = 1000;
|
instance.state = FSM_Start;
|
||||||
instance.figure_active = false;
|
|
||||||
instance.game_over = false;
|
instance.game_over = false;
|
||||||
instance.paused = false;
|
instance.paused = false;
|
||||||
initialized_local = true;
|
initialized_local = true;
|
||||||
|
|
@ -43,27 +40,45 @@ void init_game() {
|
||||||
|
|
||||||
srand((unsigned int)time(NULL));
|
srand((unsigned int)time(NULL));
|
||||||
|
|
||||||
state->current_figure.type = get_random_figure();
|
|
||||||
state->current_figure.x = FIELD_WIDTH / 2 - 2;
|
|
||||||
state->current_figure.y = 0;
|
|
||||||
state->current_figure.rotation = 0;
|
|
||||||
|
|
||||||
state->next_figure.type = get_random_figure();
|
state->next_figure.type = get_random_figure();
|
||||||
state->next_figure.x = 0;
|
state->next_figure.x = 0;
|
||||||
state->next_figure.y = 0;
|
state->next_figure.y = 0;
|
||||||
state->next_figure.rotation = 0;
|
state->next_figure.rotation = 0;
|
||||||
|
|
||||||
state->figure_active = true;
|
|
||||||
state->score = 0;
|
state->score = 0;
|
||||||
state->high_score = 0; // Позже можно загружать из файла
|
state->high_score = 0;
|
||||||
state->level = 1;
|
state->level = 1;
|
||||||
state->speed = 1000;
|
|
||||||
state->drop_time = time(NULL) * 1000;
|
state->drop_time = time(NULL) * 1000;
|
||||||
state->game_over = false;
|
state->game_over = false;
|
||||||
state->paused = false;
|
state->paused = false;
|
||||||
|
state->state = FSM_Start;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_completed_lines() {
|
void place_figure() {
|
||||||
|
GameStateData* state = get_instance();
|
||||||
|
Figure* f = &state->current_figure;
|
||||||
|
const int (*shape)[4] = get_figure_shape(f->type, f->rotation);
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
if (shape[i][j]) {
|
||||||
|
int x = f->x + j;
|
||||||
|
int y = f->y + i;
|
||||||
|
if (y >= 0 && y < FIELD_HEIGHT && x >= 0 && x < FIELD_WIDTH) {
|
||||||
|
state->game_field[y][x] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверяем и удаляем заполненные строки
|
||||||
|
clear_completed_lines();
|
||||||
|
|
||||||
|
// Меняем состояние на Spawn для генерации новой фигуры
|
||||||
|
state->state = FSM_Spawn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_completed_lines() {
|
||||||
GameStateData* state = get_instance();
|
GameStateData* state = get_instance();
|
||||||
int lines_cleared = 0;
|
int lines_cleared = 0;
|
||||||
int write_row = FIELD_HEIGHT - 1;
|
int write_row = FIELD_HEIGHT - 1;
|
||||||
|
|
@ -118,9 +133,6 @@ static void clear_completed_lines() {
|
||||||
if (new_level > 10) new_level = 10;
|
if (new_level > 10) new_level = 10;
|
||||||
if (new_level != state->level) {
|
if (new_level != state->level) {
|
||||||
state->level = new_level;
|
state->level = new_level;
|
||||||
// Увеличиваем скорость (уменьшаем время падения)
|
|
||||||
state->speed = 1000 - (state->level - 1) * 50;
|
|
||||||
if (state->speed < 100) state->speed = 100;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -151,63 +163,50 @@ bool check_collision() {
|
||||||
return collision;
|
return collision;
|
||||||
}
|
}
|
||||||
|
|
||||||
void place_figure() {
|
void fsm_transition() {
|
||||||
GameStateData* state = get_instance();
|
GameStateData* state = get_instance();
|
||||||
Figure* f = &state->current_figure;
|
|
||||||
const int (*shape)[4] = get_figure_shape(f->type, f->rotation);
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
switch (state->state) {
|
||||||
for (int j = 0; j < 4; j++) {
|
case FSM_Start:
|
||||||
if (shape[i][j]) {
|
state->state = FSM_Spawn;
|
||||||
int x = f->x + j;
|
break;
|
||||||
int y = f->y + i;
|
|
||||||
if (y >= 0 && y < FIELD_HEIGHT && x >= 0 && x < FIELD_WIDTH) {
|
|
||||||
state->game_field[y][x] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Проверяем и удаляем заполненные строки
|
case FSM_Spawn:
|
||||||
clear_completed_lines();
|
|
||||||
|
|
||||||
// Сгенерировать новую текущую фигуру из следующей
|
|
||||||
state->current_figure = state->next_figure;
|
state->current_figure = state->next_figure;
|
||||||
state->current_figure.x = FIELD_WIDTH / 2 - 2;
|
state->current_figure.x = FIELD_WIDTH / 2 - 2;
|
||||||
state->current_figure.y = 0;
|
state->current_figure.y = 0;
|
||||||
state->current_figure.rotation = 0;
|
state->current_figure.rotation = 0;
|
||||||
|
|
||||||
// Сгенерировать новую следующую фигуру
|
|
||||||
state->next_figure.type = get_random_figure();
|
state->next_figure.type = get_random_figure();
|
||||||
state->next_figure.rotation = 0;
|
state->next_figure.rotation = 0;
|
||||||
|
|
||||||
// Проверить, возможно ли размещение новой фигуры
|
|
||||||
if (check_collision()) {
|
if (check_collision()) {
|
||||||
state->game_over = true;
|
state->state = FSM_GameOver;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void update_game_state() {
|
|
||||||
GameStateData* state = get_instance();
|
|
||||||
|
|
||||||
if (state->game_over) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Проверка времени для автоматического падения
|
|
||||||
long long current_time = time(NULL) * 1000; // в миллисекундах
|
|
||||||
if (current_time - state->drop_time >= state->speed) {
|
|
||||||
// Попробовать сдвинуть фигуру вниз
|
|
||||||
int old_y = state->current_figure.y;
|
|
||||||
state->current_figure.y++;
|
|
||||||
|
|
||||||
if (check_collision()) {
|
|
||||||
// Если столкновение, вернуть позицию и зафиксировать фигуру
|
|
||||||
state->current_figure.y = old_y;
|
|
||||||
place_figure();
|
|
||||||
} else {
|
} else {
|
||||||
state->drop_time = current_time;
|
state->state = FSM_Moving;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FSM_Moving:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FSM_Move:
|
||||||
|
state->current_figure.y++;
|
||||||
|
if (check_collision()) {
|
||||||
|
state->current_figure.y--;
|
||||||
|
state->state = FSM_Attaching;
|
||||||
|
} else {
|
||||||
|
state->state = FSM_Moving;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FSM_Attaching:
|
||||||
|
place_figure();
|
||||||
|
state->state = FSM_Spawn;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FSM_GameOver:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,16 @@ typedef enum {
|
||||||
FIGURE_COUNT
|
FIGURE_COUNT
|
||||||
} FigureType;
|
} FigureType;
|
||||||
|
|
||||||
|
// FSM состояния
|
||||||
|
typedef enum {
|
||||||
|
FSM_Start,
|
||||||
|
FSM_Spawn,
|
||||||
|
FSM_Moving,
|
||||||
|
FSM_Move,
|
||||||
|
FSM_Attaching,
|
||||||
|
FSM_GameOver
|
||||||
|
} FSMState_t;
|
||||||
|
|
||||||
// Структура фигуры
|
// Структура фигуры
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int x, y; // Позиция фигуры на поле
|
int x, y; // Позиция фигуры на поле
|
||||||
|
|
@ -27,11 +37,10 @@ typedef struct {
|
||||||
int game_field[FIELD_HEIGHT][FIELD_WIDTH];
|
int game_field[FIELD_HEIGHT][FIELD_WIDTH];
|
||||||
Figure current_figure;
|
Figure current_figure;
|
||||||
Figure next_figure;
|
Figure next_figure;
|
||||||
bool figure_active;
|
FSMState_t state;
|
||||||
int score;
|
int score;
|
||||||
int high_score;
|
int high_score;
|
||||||
int level;
|
int level;
|
||||||
int speed;
|
|
||||||
long long drop_time;
|
long long drop_time;
|
||||||
bool game_over;
|
bool game_over;
|
||||||
bool paused;
|
bool paused;
|
||||||
|
|
@ -40,11 +49,12 @@ typedef struct {
|
||||||
// Внутренние функции
|
// Внутренние функции
|
||||||
bool check_collision(void);
|
bool check_collision(void);
|
||||||
void init_game(void);
|
void init_game(void);
|
||||||
void update_game_state(void);
|
void fsm_transition(void);
|
||||||
int get_random_figure(void);
|
int get_random_figure(void);
|
||||||
const int (*get_figure_shape(FigureType type, int rotation))[4];
|
const int (*get_figure_shape(FigureType type, int rotation))[4];
|
||||||
GameStateData* get_game_state(void);
|
GameStateData* get_game_state(void);
|
||||||
void place_figure(void);
|
void place_figure(void);
|
||||||
|
void clear_completed_lines(void);
|
||||||
|
|
||||||
// Фигуры
|
// Фигуры
|
||||||
const int (*i_fig_up())[4];
|
const int (*i_fig_up())[4];
|
||||||
|
|
|
||||||
|
|
@ -5,95 +5,86 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
static GameInfo_t game_info = {0};
|
static GameInfo_t* get_game_info_instance() {
|
||||||
|
static GameInfo_t instance = {0};
|
||||||
|
static bool initialized = false;
|
||||||
|
|
||||||
void init_game_info() {
|
if (!initialized) {
|
||||||
if (game_info.field == NULL) {
|
instance.field = malloc(FIELD_HEIGHT * sizeof(int*));
|
||||||
game_info.field = malloc(FIELD_HEIGHT * sizeof(int*));
|
|
||||||
for (int i = 0; i < FIELD_HEIGHT; i++) {
|
for (int i = 0; i < FIELD_HEIGHT; i++) {
|
||||||
game_info.field[i] = malloc(FIELD_WIDTH * sizeof(int));
|
instance.field[i] = malloc(FIELD_WIDTH * sizeof(int));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (game_info.next == NULL) {
|
instance.next = malloc(4 * sizeof(int*));
|
||||||
game_info.next = malloc(4 * sizeof(int*));
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
game_info.next[i] = malloc(4 * sizeof(int));
|
instance.next[i] = malloc(4 * sizeof(int));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Инициализация полей
|
// Инициализация полей
|
||||||
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++) {
|
||||||
game_info.field[i][j] = 0;
|
instance.field[i][j] = 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++) {
|
||||||
game_info.next[i][j] = 0;
|
instance.next[i][j] = 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_game_info_initialized() {
|
initialized = true;
|
||||||
// Проверяем, инициализирован ли game_info
|
}
|
||||||
if (game_info.field == NULL) return false;
|
|
||||||
if (game_info.next == NULL) return false;
|
return &instance;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void userInput(UserAction_t action, bool hold) {
|
void userInput(UserAction_t action, bool hold) {
|
||||||
if (!is_game_info_initialized()) {
|
|
||||||
init_game_info();
|
|
||||||
init_game();
|
|
||||||
}
|
|
||||||
|
|
||||||
GameStateData* state = get_game_state();
|
GameStateData* state = get_game_state();
|
||||||
|
GameInfo_t* game_info = get_game_info_instance();
|
||||||
|
|
||||||
if (action == Start) {
|
switch (action) {
|
||||||
if (state->game_over) {
|
case Start:
|
||||||
int saved_high_score = state->high_score; // Сохраняем high_score
|
if (state->state == FSM_GameOver) {
|
||||||
init_game(); // Перезапуск игры
|
// Перезапуск игры
|
||||||
state->high_score = saved_high_score; // Восстанавливаем high_score
|
int saved_high_score = state->high_score;
|
||||||
} else if (!state->paused) {
|
init_game();
|
||||||
state->paused = true;
|
state->high_score = saved_high_score;
|
||||||
|
state->state = FSM_Spawn;
|
||||||
} else {
|
} else {
|
||||||
state->paused = false;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action == Pause) {
|
|
||||||
state->paused = !state->paused;
|
state->paused = !state->paused;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
if (action == Terminate) {
|
case Pause:
|
||||||
|
state->paused = !state->paused;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Terminate:
|
||||||
// Освобождаем память при завершении
|
// Освобождаем память при завершении
|
||||||
if (game_info.field != NULL) {
|
if (game_info->field != NULL) {
|
||||||
for (int i = 0; i < FIELD_HEIGHT; i++) {
|
for (int i = 0; i < FIELD_HEIGHT; i++) {
|
||||||
free(game_info.field[i]);
|
free(game_info->field[i]);
|
||||||
}
|
}
|
||||||
free(game_info.field);
|
free(game_info->field);
|
||||||
game_info.field = NULL;
|
game_info->field = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (game_info.next != NULL) {
|
if (game_info->next != NULL) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
free(game_info.next[i]);
|
free(game_info->next[i]);
|
||||||
}
|
}
|
||||||
free(game_info.next);
|
free(game_info->next);
|
||||||
game_info.next = NULL;
|
game_info->next = NULL;
|
||||||
}
|
}
|
||||||
return;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (state->state == FSM_GameOver || state->paused) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->game_over || state->paused) {
|
if ((state->state == FSM_Moving || state->state == FSM_Move) && !state->game_over) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->figure_active && !state->game_over) {
|
|
||||||
int old_x = state->current_figure.x;
|
int old_x = state->current_figure.x;
|
||||||
int old_y = state->current_figure.y;
|
int old_y = state->current_figure.y;
|
||||||
int old_rot = state->current_figure.rotation;
|
int old_rot = state->current_figure.rotation;
|
||||||
|
|
@ -111,14 +102,14 @@ void userInput(UserAction_t action, bool hold) {
|
||||||
case Up:
|
case Up:
|
||||||
state->current_figure.rotation = (state->current_figure.rotation + 1) % 4;
|
state->current_figure.rotation = (state->current_figure.rotation + 1) % 4;
|
||||||
break;
|
break;
|
||||||
case Action: // Это может быть вращение или сброс
|
case Action:
|
||||||
if (hold) {
|
if (hold) {
|
||||||
// Быстрый сброс вниз
|
// Быстрый сброс вниз
|
||||||
while (!check_collision()) {
|
while (!check_collision()) {
|
||||||
state->current_figure.y++;
|
state->current_figure.y++;
|
||||||
}
|
}
|
||||||
state->current_figure.y--; // Вернуть на место перед столкновением
|
state->current_figure.y--; // Вернуть на место перед столкновением
|
||||||
place_figure();
|
state->state = FSM_Attaching;
|
||||||
} else {
|
} else {
|
||||||
state->current_figure.rotation = (state->current_figure.rotation + 1) % 4;
|
state->current_figure.rotation = (state->current_figure.rotation + 1) % 4;
|
||||||
}
|
}
|
||||||
|
|
@ -137,40 +128,39 @@ void userInput(UserAction_t action, bool hold) {
|
||||||
state->drop_time = time(NULL) * 1000;
|
state->drop_time = time(NULL) * 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GameInfo_t updateCurrentState() {
|
GameInfo_t updateCurrentState() {
|
||||||
if (!is_game_info_initialized()) {
|
|
||||||
init_game_info();
|
|
||||||
init_game();
|
|
||||||
}
|
|
||||||
|
|
||||||
GameStateData* state = get_game_state();
|
GameStateData* state = get_game_state();
|
||||||
|
GameInfo_t* game_info = get_game_info_instance();
|
||||||
|
|
||||||
if (!state->game_over && !state->paused) {
|
if (!state->game_over && !state->paused) {
|
||||||
long long current_time = time(NULL) * 1000;
|
long long current_time = time(NULL) * 1000;
|
||||||
if (current_time - state->drop_time >= state->speed) {
|
|
||||||
int old_y = state->current_figure.y;
|
|
||||||
state->current_figure.y++;
|
|
||||||
|
|
||||||
if (check_collision()) {
|
// Определяем интервал падения в зависимости от уровня
|
||||||
state->current_figure.y = old_y;
|
int drop_interval = 1000 - (state->level - 1) * 50;
|
||||||
place_figure();
|
if (drop_interval < 100) drop_interval = 100; // Минимальный интервал
|
||||||
} else {
|
|
||||||
|
if (current_time - state->drop_time >= drop_interval) {
|
||||||
|
state->state = FSM_Move; // Переходим к автоматическому движению
|
||||||
state->drop_time = current_time;
|
state->drop_time = current_time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Выполняем переходы FSM
|
||||||
|
fsm_transition();
|
||||||
|
|
||||||
// Обновляем game_info.field из state->game_field
|
// Обновляем game_info.field из state->game_field
|
||||||
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++) {
|
||||||
game_info.field[i][j] = state->game_field[i][j];
|
game_info->field[i][j] = state->game_field[i][j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Добавляем активную фигуру на поле для отображения (если не game_over)
|
// Добавляем активную фигуру на поле для отображения (если не game_over)
|
||||||
if (state->figure_active && !state->game_over) {
|
if ((state->state == FSM_Moving || state->state == FSM_Move) && !state->game_over) {
|
||||||
Figure* f = &state->current_figure;
|
Figure* f = &state->current_figure;
|
||||||
const int (*shape)[4] = get_figure_shape(f->type, f->rotation);
|
const int (*shape)[4] = get_figure_shape(f->type, f->rotation);
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
|
|
@ -179,7 +169,7 @@ GameInfo_t updateCurrentState() {
|
||||||
int x = f->x + j;
|
int x = f->x + j;
|
||||||
int y = f->y + i;
|
int y = f->y + i;
|
||||||
if (x >= 0 && x < FIELD_WIDTH && y >= 0 && y < FIELD_HEIGHT) {
|
if (x >= 0 && x < FIELD_WIDTH && y >= 0 && y < FIELD_HEIGHT) {
|
||||||
game_info.field[y][x] = 1;
|
game_info->field[y][x] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -188,7 +178,7 @@ GameInfo_t updateCurrentState() {
|
||||||
|
|
||||||
// Обновляем next
|
// Обновляем next
|
||||||
const int (*next_shape)[4];
|
const int (*next_shape)[4];
|
||||||
if (state->game_over) {
|
if (state->state == FSM_GameOver) {
|
||||||
// При game_over показываем пустую фигуру
|
// При game_over показываем пустую фигуру
|
||||||
next_shape = empty_fig();
|
next_shape = empty_fig();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -197,16 +187,16 @@ GameInfo_t updateCurrentState() {
|
||||||
|
|
||||||
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++) {
|
||||||
game_info.next[i][j] = next_shape[i][j];
|
game_info->next[i][j] = next_shape[i][j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Обновляем остальные поля
|
// Обновляем остальные поля
|
||||||
game_info.score = state->score;
|
game_info->score = state->score;
|
||||||
game_info.high_score = state->high_score;
|
game_info->high_score = state->high_score;
|
||||||
game_info.level = state->level;
|
game_info->level = state->level;
|
||||||
game_info.speed = state->speed;
|
game_info->speed = 0; // Заглушка
|
||||||
game_info.pause = state->paused ? 1 : 0;
|
game_info->pause = state->paused ? 1 : 0;
|
||||||
|
|
||||||
return game_info;
|
return *game_info;
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue