#include #include #include #include "world.h" #define EMPTY ' ' #define BLOCK '#' #define WIDTH 10 #define HEIGHT 20 typedef struct { int x, y; } Point; typedef struct { Point blocks[4]; Point position; } Tetromino; typedef struct { char grid[HEIGHT][WIDTH]; Tetromino current; } GameState; Tetromino tetrominoes[] = { {{{0,0}, {1,0}, {0,1}, {1,1}}, {0,0}}, // Square {{{0,0}, {1,0}, {2,0}, {3,0}}, {0,0}}, // Line {{{0,0}, {1,0}, {1,1}, {2,1}}, {0,0}}, // Z shape {{{1,0}, {2,0}, {0,1}, {1,1}}, {0,0}}, // S shape {{{0,0}, {1,0}, {2,0}, {1,1}}, {0,0}}, // T shape {{{0,0}, {0,1}, {1,1}, {2,1}}, {0,0}}, // L shape {{{2,0}, {0,1}, {1,1}, {2,1}}, {0,0}} // J shape }; void draw_grid(GameState* game) { clear_world(); for (int y = 0; y < HEIGHT; ++y) { for (int x = 0; x < WIDTH; ++x) { draw_character(game->grid[y][x], x, y); } } for (int i = 0; i < 4; ++i) { draw_character(BLOCK, game->current.position.x + game->current.blocks[i].x, game->current.position.y + game->current.blocks[i].y); } refresh_world(); } int is_valid_position(GameState* game, Point new_position) { for (int i = 0; i < 4; ++i) { int new_x = new_position.x + game->current.blocks[i].x; int new_y = new_position.y + game->current.blocks[i].y; if (new_x < 0 || new_x >= WIDTH || new_y < 0 || new_y >= HEIGHT || game->grid[new_y][new_x] != EMPTY) { return 0; } } return 1; } void place_tetromino(GameState* game) { for (int i = 0; i < 4; ++i) { int x = game->current.position.x + game->current.blocks[i].x; int y = game->current.position.y + game->current.blocks[i].y; game->grid[y][x] = BLOCK; } } void clear_lines(GameState* game) { for (int y = HEIGHT - 1; y >= 0; --y) { int full = 1; for (int x = 0; x < WIDTH; ++x) { if (game->grid[y][x] == EMPTY) { full = 0; break; } } if (full) { for (int row = y; row > 0; --row) { memcpy(game->grid[row], game->grid[row - 1], WIDTH); } memset(game->grid[0], EMPTY, WIDTH); y++; } } } void* init_game() { srand(time(NULL)); GameState* game = malloc(sizeof(GameState)); memset(game->grid, EMPTY, sizeof(game->grid)); game->current = tetrominoes[rand() % 7]; game->current.position.x = WIDTH / 2 - 1; game->current.position.y = 0; return game; } int game_event(struct event* event, void* state) { GameState* game = (GameState*)state; Point new_position = game->current.position; if (event->key) { switch (event->key) { case 'a': new_position.x -= 1; break; case 'd': new_position.x += 1; break; case 's': new_position.y += 1; break; case 'w': // TODO: Implement rotation break; case 27: return 1; // Escape key } if (is_valid_position(game, new_position)) { game->current.position = new_position; } } new_position.y += 1; if (!is_valid_position(game, new_position)) { place_tetromino(game); clear_lines(game); game->current = tetrominoes[rand() % 7]; game->current.position.x = WIDTH / 2 - 1; game->current.position.y = 0; if (!is_valid_position(game, game->current.position)) { return 1; // Game over } } else { game->current.position = new_position; } draw_grid(game); return 0; }