diff --git a/.gitignore b/.gitignore index c6127b3..0103826 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,4 @@ modules.order Module.symvers Mkfile.old dkms.conf +src/tetris diff --git a/src/Makefile b/src/Makefile index f565e1f..cb5f995 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,3 +1,4 @@ +# src/Makefile CC = gcc CFLAGS = -std=c11 -Wall -Wextra -Werror -g LDFLAGS = -lncurses diff --git a/src/brick_game/tetris/tetris.c b/src/brick_game/tetris/tetris.c index e69de29..ef6f995 100644 --- a/src/brick_game/tetris/tetris.c +++ b/src/brick_game/tetris/tetris.c @@ -0,0 +1,76 @@ +// src/brick_game/tetris/tetris.c +#include "tetris.h" +#include +#include +#include + +static GameStateData game_state = {0}; +static bool initialized = false; + +const int (*get_figure_shape(FigureType type, int rotation))[4] { + static const int shapes[FIGURE_COUNT][4][4][4] = { + // I + {{{0, 0, 0, 0}, {1, 1, 1, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}}, + {{0, 0, 1, 0}, {0, 0, 1, 0}, {0, 0, 1, 0}, {0, 0, 1, 0}}, + {{0, 0, 0, 0}, {0, 0, 0, 0}, {1, 1, 1, 1}, {0, 0, 0, 0}}, + {{0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}}}, + // O + {{{0, 1, 1, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, + {{0, 1, 1, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, + {{0, 1, 1, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, + {{0, 1, 1, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}}, + // T + {{{0, 1, 0, 0}, {1, 1, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, + {{0, 1, 0, 0}, {0, 1, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}}, + {{0, 0, 0, 0}, {1, 1, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}}, + {{0, 1, 0, 0}, {1, 1, 0, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}}}, + // L + {{{0, 0, 1, 0}, {1, 1, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, + {{1, 0, 0, 0}, {1, 0, 0, 0}, {1, 1, 0, 0}, {0, 0, 0, 0}}, + {{0, 0, 0, 0}, {1, 1, 1, 0}, {1, 0, 0, 0}, {0, 0, 0, 0}}, + {{1, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}}}, + // J + {{{1, 0, 0, 0}, {1, 1, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, + {{0, 1, 1, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}}, + {{0, 0, 0, 0}, {1, 1, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}}, + {{0, 1, 0, 0}, {0, 1, 0, 0}, {1, 1, 0, 0}, {0, 0, 0, 0}}}, + // S + {{{0, 1, 1, 0}, {1, 1, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, + {{0, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}}, + {{0, 1, 1, 0}, {1, 1, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, + {{0, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}}}, + // Z + {{{1, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, + {{0, 0, 1, 0}, {0, 1, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}}, + {{1, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, + {{0, 0, 1, 0}, {0, 1, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}}}}; + return shapes[type][rotation]; +} + +void userInput(UserAction_t action, bool hold) { + (void)hold; // Подавляем предупреждение + if (!initialized) { + memset(&game_state, 0, sizeof(game_state)); + initialized = true; + } + + if (action >= Figure1 && action <= Figure5) { + FigureType type = (FigureType)(action - Figure1); + game_state.current_figure.type = type; + game_state.current_figure.x = FIELD_WIDTH / 2 - 2; + game_state.current_figure.y = 0; + game_state.current_figure.rotation = 0; + game_state.figure_active = true; + } + + if (game_state.figure_active) { + if (action == Left) game_state.current_figure.x--; + if (action == Right) game_state.current_figure.x++; + if (action == Down) game_state.current_figure.y++; + if (action == Up) game_state.current_figure.y--; + } +} + +GameStateData* getGameState() { + return &game_state; +} \ No newline at end of file diff --git a/src/brick_game/tetris/tetris.h b/src/brick_game/tetris/tetris.h index 4980da2..bf4ccba 100644 --- a/src/brick_game/tetris/tetris.h +++ b/src/brick_game/tetris/tetris.h @@ -1,13 +1,13 @@ +// src/brick_game/tetris/tetris.h #ifndef TETRIS_H #define TETRIS_H -#include #include +#include // Константы #define FIELD_WIDTH 10 #define FIELD_HEIGHT 20 -#define NEXT_SIZE 4 // Типы фигур typedef enum { @@ -21,16 +21,6 @@ typedef enum { FIGURE_COUNT } FigureType; -// Состояния конечного автомата -typedef enum { - START, - SPAWN, - MOVING, - SHIFTING, - ATTACHING, - GAME_OVER -} GameState; - // Структура фигуры typedef struct { int x, y; // Позиция фигуры на поле @@ -42,30 +32,31 @@ typedef struct { typedef struct { int field[FIELD_HEIGHT][FIELD_WIDTH]; // Игровое поле Figure current_figure; // Текущая фигура - Figure next_figure; // Следующая фигура - int score; // Текущие очки - int high_score; // Максимальные очки - int level; // Уровень - int lines_cleared; // Удалённые линии - GameState state; // Текущее состояние КА - bool paused; // Игра на паузе? + bool figure_active; // Есть активная фигура? } GameStateData; // Ввод пользователя typedef enum { + Undefined = -1, Start, Pause, Terminate, Left, Right, - Up, // не используется + Up, Down, - Action // вращение + Action, + Figure1, // 1 + Figure2, // 2 + Figure3, // 3 + Figure4, // 4 + Figure5 // 5 } UserAction_t; // Основные функции библиотеки void userInput(UserAction_t action, bool hold); GameStateData* getGameState(void); -void updateCurrentState(void); + +const int (*get_figure_shape(FigureType type, int rotation))[4]; #endif \ No newline at end of file diff --git a/src/gui/cli/display.c b/src/gui/cli/display.c index e69de29..82412f1 100644 --- a/src/gui/cli/display.c +++ b/src/gui/cli/display.c @@ -0,0 +1,35 @@ +// src/gui/cli/display.c +#include +#include "../../brick_game/tetris/tetris.h" + +void display_game() { + clear(); + + GameStateData* state = getGameState(); + + // Очистка поля + for (int i = 0; i < FIELD_HEIGHT; i++) { + for (int j = 0; j < FIELD_WIDTH; j++) { + mvaddch(i + 1, j * 2 + 1, '.'); + } + } + + // Если фигура активна — отображаем её + if (state->figure_active) { + 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 (x >= 0 && x < FIELD_WIDTH && y >= 0 && y < FIELD_HEIGHT) { + mvaddch(y + 1, x * 2 + 1, '$'); + } + } + } + } + } + + refresh(); +} \ No newline at end of file diff --git a/src/gui/cli/main.c b/src/gui/cli/main.c index e69de29..42a9554 100644 --- a/src/gui/cli/main.c +++ b/src/gui/cli/main.c @@ -0,0 +1,50 @@ +// src/gui/cli/main.c +#include +#include +#include +#include "../../brick_game/tetris/tetris.h" + +void display_game(); + +int main() { + initscr(); + cbreak(); + noecho(); + keypad(stdscr, TRUE); + nodelay(stdscr, TRUE); + curs_set(0); + + timeout(100); // Таймаут для getch() + + int ch; + bool hold = false; + + while (1) { + ch = getch(); + UserAction_t action = Undefined; + + switch (ch) { + case 'q': action = Terminate; break; + case '1': action = Figure1; break; + case '2': action = Figure2; break; + case '3': action = Figure3; break; + case '4': action = Figure4; break; + case '5': action = Figure5; break; + case KEY_LEFT: action = Left; break; + case KEY_RIGHT: action = Right; break; + case KEY_DOWN: action = Down; break; + case KEY_UP: action = Up; break; + } + + if (action != Undefined) { + userInput(action, hold); + } + + display_game(); + + if (action == Terminate) break; + } + + endwin(); + return 0; +} \ No newline at end of file