no segs and correct points
This commit is contained in:
parent
6b80483129
commit
3c7e55dd6f
5 changed files with 76 additions and 40 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -56,3 +56,4 @@ src/.gpskip
|
|||
.gpskip
|
||||
ginpee.toml
|
||||
src/ginpee.toml
|
||||
.vscode/launch.json
|
||||
|
|
|
|||
|
|
@ -46,12 +46,11 @@ void init_game() {
|
|||
state->next_figure.rotation = 0;
|
||||
|
||||
state->score = 0;
|
||||
state->high_score = 0;
|
||||
state->level = 1;
|
||||
state->drop_time = time(NULL) * 1000;
|
||||
state->game_over = false;
|
||||
state->paused = false;
|
||||
state->state = FSM_Start;
|
||||
state->state = FSM_Start; // Начинаем в состоянии Start
|
||||
}
|
||||
|
||||
void place_figure() {
|
||||
|
|
@ -65,7 +64,7 @@ void place_figure() {
|
|||
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;
|
||||
state->game_field[y][x] = 1; // Фиксируем блок
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -74,12 +73,26 @@ void place_figure() {
|
|||
// Проверяем и удаляем заполненные строки
|
||||
clear_completed_lines();
|
||||
|
||||
// Меняем состояние на Spawn для генерации новой фигуры
|
||||
state->state = FSM_Spawn;
|
||||
// Спавним новую фигуру
|
||||
state->current_figure = state->next_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.rotation = 0;
|
||||
|
||||
// Проверяем, возможно ли размещение новой фигуры
|
||||
if (check_collision()) {
|
||||
state->state = FSM_GameOver;
|
||||
} else {
|
||||
state->state = FSM_Moving;
|
||||
}
|
||||
}
|
||||
|
||||
void clear_completed_lines() {
|
||||
GameStateData* state = get_instance();
|
||||
GameStateData* state = get_game_state();
|
||||
int lines_cleared = 0;
|
||||
int write_row = FIELD_HEIGHT - 1;
|
||||
|
||||
|
|
@ -122,7 +135,7 @@ void clear_completed_lines() {
|
|||
} else {
|
||||
score_points = points[4]; // для > 4 линий
|
||||
}
|
||||
state->score += score_points * state->level;
|
||||
state->score += score_points; // УБРАЛ УМНОЖЕНИЕ НА УРОВЕНЬ
|
||||
|
||||
if (state->score > state->high_score) {
|
||||
state->high_score = state->score;
|
||||
|
|
@ -164,11 +177,11 @@ bool check_collision() {
|
|||
}
|
||||
|
||||
void fsm_transition() {
|
||||
GameStateData* state = get_instance();
|
||||
GameStateData* state = get_game_state();
|
||||
|
||||
switch (state->state) {
|
||||
case FSM_Start:
|
||||
state->state = FSM_Spawn;
|
||||
// Ожидание начала игры - не делаем ничего, пока не будет нажата Start
|
||||
break;
|
||||
|
||||
case FSM_Spawn:
|
||||
|
|
@ -202,7 +215,8 @@ void fsm_transition() {
|
|||
|
||||
case FSM_Attaching:
|
||||
place_figure();
|
||||
state->state = FSM_Spawn;
|
||||
// После place_figure проверяем, не произошел ли Game Over
|
||||
// В place_figure уже устанавливается FSM_Spawn, но нужно проверить столкновение
|
||||
break;
|
||||
|
||||
case FSM_GameOver:
|
||||
|
|
|
|||
|
|
@ -44,27 +44,14 @@ void userInput(UserAction_t action, bool hold) {
|
|||
GameInfo_t* game_info = get_game_info_instance();
|
||||
|
||||
switch (action) {
|
||||
case Start:
|
||||
if (state->state == FSM_GameOver) {
|
||||
// Перезапуск игры
|
||||
int saved_high_score = state->high_score;
|
||||
init_game();
|
||||
state->high_score = saved_high_score;
|
||||
state->state = FSM_Spawn;
|
||||
} else {
|
||||
state->paused = !state->paused;
|
||||
}
|
||||
break;
|
||||
|
||||
case Pause:
|
||||
state->paused = !state->paused;
|
||||
break;
|
||||
|
||||
case Terminate:
|
||||
// Освобождаем память при завершении
|
||||
if (game_info->field != NULL) {
|
||||
for (int i = 0; i < FIELD_HEIGHT; i++) {
|
||||
free(game_info->field[i]);
|
||||
if (game_info->field[i] != NULL) {
|
||||
free(game_info->field[i]);
|
||||
game_info->field[i] = NULL;
|
||||
}
|
||||
}
|
||||
free(game_info->field);
|
||||
game_info->field = NULL;
|
||||
|
|
@ -72,15 +59,38 @@ void userInput(UserAction_t action, bool hold) {
|
|||
|
||||
if (game_info->next != NULL) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
free(game_info->next[i]);
|
||||
if (game_info->next[i] != NULL) {
|
||||
free(game_info->next[i]);
|
||||
game_info->next[i] = NULL;
|
||||
}
|
||||
}
|
||||
free(game_info->next);
|
||||
game_info->next = NULL;
|
||||
}
|
||||
return; // ВАЖНО: выходим из функции, не делаем ничего после Terminate
|
||||
|
||||
case Start:
|
||||
if (state->state == FSM_GameOver) {
|
||||
// Перезапуск игры после Game Over
|
||||
int saved_high_score = state->high_score;
|
||||
init_game();
|
||||
state->high_score = saved_high_score;
|
||||
// Не меняем состояние, пусть остается в Start до следующего нажатия
|
||||
} else if (state->state == FSM_Start) {
|
||||
// Начинаем игру из состояния Start
|
||||
state->state = FSM_Spawn;
|
||||
} else {
|
||||
// Для всех других состояний (Moving, Move) - ставим на паузу
|
||||
state->paused = !state->paused;
|
||||
}
|
||||
break;
|
||||
|
||||
case Pause:
|
||||
state->paused = !state->paused;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (state->state == FSM_GameOver || state->paused) {
|
||||
if (state->state == FSM_GameOver || state->paused || state->state == FSM_Start) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -136,7 +146,7 @@ GameInfo_t updateCurrentState() {
|
|||
GameStateData* state = get_game_state();
|
||||
GameInfo_t* game_info = get_game_info_instance();
|
||||
|
||||
if (!state->game_over && !state->paused) {
|
||||
if (state->state != FSM_Start && !state->game_over && !state->paused) {
|
||||
long long current_time = time(NULL) * 1000;
|
||||
|
||||
// Определяем интервал падения в зависимости от уровня
|
||||
|
|
@ -149,8 +159,10 @@ GameInfo_t updateCurrentState() {
|
|||
}
|
||||
}
|
||||
|
||||
// Выполняем переходы FSM
|
||||
fsm_transition();
|
||||
// Выполняем переходы FSM (но не в состоянии Start)
|
||||
if (state->state != FSM_Start) {
|
||||
fsm_transition();
|
||||
}
|
||||
|
||||
// Обновляем game_info.field из state->game_field
|
||||
for (int i = 0; i < FIELD_HEIGHT; i++) {
|
||||
|
|
@ -159,7 +171,7 @@ GameInfo_t updateCurrentState() {
|
|||
}
|
||||
}
|
||||
|
||||
// Добавляем активную фигуру на поле для отображения (если не game_over)
|
||||
// Добавляем активную фигуру на поле для отображения (если не в Start или GameOver)
|
||||
if ((state->state == FSM_Moving || state->state == FSM_Move) && !state->game_over) {
|
||||
Figure* f = &state->current_figure;
|
||||
const int (*shape)[4] = get_figure_shape(f->type, f->rotation);
|
||||
|
|
@ -168,8 +180,12 @@ GameInfo_t updateCurrentState() {
|
|||
if (shape[i][j]) {
|
||||
int x = f->x + j;
|
||||
int y = f->y + i;
|
||||
// Проверяем границы перед записью
|
||||
if (x >= 0 && x < FIELD_WIDTH && y >= 0 && y < FIELD_HEIGHT) {
|
||||
game_info->field[y][x] = 1;
|
||||
// Не перезаписываем уже зафиксированные блоки
|
||||
if (state->game_field[y][x] == 0) {
|
||||
game_info->field[y][x] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -178,8 +194,8 @@ GameInfo_t updateCurrentState() {
|
|||
|
||||
// Обновляем next
|
||||
const int (*next_shape)[4];
|
||||
if (state->state == FSM_GameOver) {
|
||||
// При game_over показываем пустую фигуру
|
||||
if (state->state == FSM_GameOver || state->state == FSM_Start) {
|
||||
// При game_over или в начальном состоянии показываем пустую фигуру
|
||||
next_shape = empty_fig();
|
||||
} else {
|
||||
next_shape = get_figure_shape(state->next_figure.type, state->next_figure.rotation);
|
||||
|
|
|
|||
|
|
@ -3,9 +3,13 @@
|
|||
#include "../../brick_game/tetris/tetris.h"
|
||||
|
||||
void display_game() {
|
||||
printf("DEBUG: display_game called\n");
|
||||
clear();
|
||||
|
||||
GameInfo_t game_state = updateCurrentState();
|
||||
|
||||
printf("DEBUG: Got game state, field: %p, next: %p\n",
|
||||
game_state.field, game_state.next);
|
||||
|
||||
// Отображение игрового поля
|
||||
for (int i = 0; i < FIELD_HEIGHT; i++) {
|
||||
|
|
@ -43,4 +47,5 @@ void display_game() {
|
|||
}
|
||||
|
||||
refresh();
|
||||
printf("DEBUG: display_game completed\n");
|
||||
}
|
||||
|
|
@ -64,12 +64,12 @@ int main() {
|
|||
userInput(current_action, false);
|
||||
}
|
||||
|
||||
updateCurrentState();
|
||||
display_game();
|
||||
if (running) { // Обновляем состояние только если не завершаемся
|
||||
updateCurrentState();
|
||||
display_game();
|
||||
}
|
||||
}
|
||||
|
||||
// Вызов userInput с Terminate для освобождения памяти
|
||||
userInput(Terminate, false);
|
||||
endwin();
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue