Фигурки то рисуются!
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
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
src/tetris
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
# src/Makefile
|
||||
CC = gcc
|
||||
CFLAGS = -std=c11 -Wall -Wextra -Werror -g
|
||||
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
|
||||
#define TETRIS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Константы
|
||||
#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
|
||||
|
|
@ -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