Фигурки то рисуются!
This commit is contained in:
parent
e20765d252
commit
fef0d8cbe3
6 changed files with 176 additions and 22 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -50,3 +50,4 @@ modules.order
|
||||||
Module.symvers
|
Module.symvers
|
||||||
Mkfile.old
|
Mkfile.old
|
||||||
dkms.conf
|
dkms.conf
|
||||||
|
src/tetris
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# src/Makefile
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -std=c11 -Wall -Wextra -Werror -g
|
CFLAGS = -std=c11 -Wall -Wextra -Werror -g
|
||||||
LDFLAGS = -lncurses
|
LDFLAGS = -lncurses
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
// src/brick_game/tetris/tetris.c
|
||||||
|
#include "tetris.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
|
// src/brick_game/tetris/tetris.h
|
||||||
#ifndef TETRIS_H
|
#ifndef TETRIS_H
|
||||||
#define TETRIS_H
|
#define TETRIS_H
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
// Константы
|
// Константы
|
||||||
#define FIELD_WIDTH 10
|
#define FIELD_WIDTH 10
|
||||||
#define FIELD_HEIGHT 20
|
#define FIELD_HEIGHT 20
|
||||||
#define NEXT_SIZE 4
|
|
||||||
|
|
||||||
// Типы фигур
|
// Типы фигур
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
@ -21,16 +21,6 @@ typedef enum {
|
||||||
FIGURE_COUNT
|
FIGURE_COUNT
|
||||||
} FigureType;
|
} FigureType;
|
||||||
|
|
||||||
// Состояния конечного автомата
|
|
||||||
typedef enum {
|
|
||||||
START,
|
|
||||||
SPAWN,
|
|
||||||
MOVING,
|
|
||||||
SHIFTING,
|
|
||||||
ATTACHING,
|
|
||||||
GAME_OVER
|
|
||||||
} GameState;
|
|
||||||
|
|
||||||
// Структура фигуры
|
// Структура фигуры
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int x, y; // Позиция фигуры на поле
|
int x, y; // Позиция фигуры на поле
|
||||||
|
|
@ -42,30 +32,31 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int field[FIELD_HEIGHT][FIELD_WIDTH]; // Игровое поле
|
int field[FIELD_HEIGHT][FIELD_WIDTH]; // Игровое поле
|
||||||
Figure current_figure; // Текущая фигура
|
Figure current_figure; // Текущая фигура
|
||||||
Figure next_figure; // Следующая фигура
|
bool figure_active; // Есть активная фигура?
|
||||||
int score; // Текущие очки
|
|
||||||
int high_score; // Максимальные очки
|
|
||||||
int level; // Уровень
|
|
||||||
int lines_cleared; // Удалённые линии
|
|
||||||
GameState state; // Текущее состояние КА
|
|
||||||
bool paused; // Игра на паузе?
|
|
||||||
} GameStateData;
|
} GameStateData;
|
||||||
|
|
||||||
// Ввод пользователя
|
// Ввод пользователя
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
Undefined = -1,
|
||||||
Start,
|
Start,
|
||||||
Pause,
|
Pause,
|
||||||
Terminate,
|
Terminate,
|
||||||
Left,
|
Left,
|
||||||
Right,
|
Right,
|
||||||
Up, // не используется
|
Up,
|
||||||
Down,
|
Down,
|
||||||
Action // вращение
|
Action,
|
||||||
|
Figure1, // 1
|
||||||
|
Figure2, // 2
|
||||||
|
Figure3, // 3
|
||||||
|
Figure4, // 4
|
||||||
|
Figure5 // 5
|
||||||
} UserAction_t;
|
} UserAction_t;
|
||||||
|
|
||||||
// Основные функции библиотеки
|
// Основные функции библиотеки
|
||||||
void userInput(UserAction_t action, bool hold);
|
void userInput(UserAction_t action, bool hold);
|
||||||
GameStateData* getGameState(void);
|
GameStateData* getGameState(void);
|
||||||
void updateCurrentState(void);
|
|
||||||
|
const int (*get_figure_shape(FigureType type, int rotation))[4];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
// src/gui/cli/display.c
|
||||||
|
#include <ncurses.h>
|
||||||
|
#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();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
// src/gui/cli/main.c
|
||||||
|
#include <ncurses.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#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;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue