
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <windows.h>
#include <string.h>#define WIDTH 12
#define HEIGHT 18
#define BUFFER_WIDTH (WIDTH * 2 + 20)
#define BUFFER_HEIGHT (HEIGHT + 2)char field[HEIGHT][WIDTH] = {0};
int score = 0;
char buffer[BUFFER_HEIGHT][BUFFER_WIDTH];typedef struct {char **array;int width, row, col;
} Shape;Shape current;const char *shapes[] = {"..X...X...X...X.","..X..XX...X.....",".....XX..XX.....","..X..XX..X......",".X...XX...X.....",
};// 函数声明
void setupConsole();
void clearBuffer();
void drawToBuffer();
void flushBuffer();
int createShape(Shape *shape, int index);
int isValidMove(Shape shape, int row, int col);
void mergePiece(Shape shape);
void clearLines();
void rotateShape(Shape *shape);// 函数定义
void setupConsole() {HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);SMALL_RECT windowSize = {0, 0, BUFFER_WIDTH - 1, BUFFER_HEIGHT - 1};SetConsoleWindowInfo(hConsole, TRUE, &windowSize);SetConsoleScreenBufferSize(hConsole, (COORD){BUFFER_WIDTH, BUFFER_HEIGHT});CONSOLE_CURSOR_INFO cursorInfo;cursorInfo.dwSize = 1;cursorInfo.bVisible = FALSE;SetConsoleCursorInfo(hConsole, &cursorInfo);system("cls");
}void clearBuffer() {for (int i = 0; i < BUFFER_HEIGHT; i++) {for (int j = 0; j < BUFFER_WIDTH; j++) {buffer[i][j] = ' ';}buffer[i][BUFFER_WIDTH - 1] = '\0';}
}void drawToBuffer() {clearBuffer();// 绘制游戏区域for (int i = 0; i < HEIGHT; i++) {for (int j = 0; j < WIDTH; j++) {buffer[i][j * 2] = field[i][j] ? '[' : ' ';buffer[i][j * 2 + 1] = field[i][j] ? ']' : ' ';}}// 绘制当前方块for (int i = 0; i < current.width; i++) {for (int j = 0; j < current.width; j++) {if (current.array[i][j]) {int row = current.row + i;int col = current.col + j;if (row >= 0 && row < HEIGHT && col >= 0 && col < WIDTH) {buffer[row][col * 2] = '[';buffer[row][col * 2 + 1] = ']';}}}}// 绘制分数sprintf(&buffer[0][WIDTH * 2 + 2], "Score: %d", score);
}void flushBuffer() {HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);COORD coordScreen = {0, 0};DWORD cCharsWritten;CONSOLE_SCREEN_BUFFER_INFO csbi;GetConsoleScreenBufferInfo(hConsole, &csbi);for (int i = 0; i < BUFFER_HEIGHT; i++) {WriteConsoleOutputCharacter(hConsole, buffer[i], BUFFER_WIDTH - 1, coordScreen, &cCharsWritten);coordScreen.Y++;}SetConsoleCursorPosition(hConsole, (COORD){0, 0});
}int createShape(Shape *shape, int index) {int i, j;int size = 4;shape->array = (char**)malloc(size * sizeof(char*));for (i = 0; i < size; i++) {shape->array[i] = (char*)malloc(size * sizeof(char));for (j = 0; j < size; j++) {shape->array[i][j] = shapes[index][i * size + j] == 'X';}}shape->width = size;shape->row = 0;shape->col = WIDTH / 2 - size / 2;return 1;
}int isValidMove(Shape shape, int row, int col) {for (int i = 0; i < shape.width; i++) {for (int j = 0; j < shape.width; j++) {if (shape.array[i][j]) {int newRow = row + i;int newCol = col + j;if (newRow >= HEIGHT || newCol < 0 || newCol >= WIDTH || field[newRow][newCol]) {return 0;}}}}return 1;
}void mergePiece(Shape shape) {for (int i = 0; i < shape.width; i++) {for (int j = 0; j < shape.width; j++) {if (shape.array[i][j]) {field[shape.row + i][shape.col + j] = 1;}}}
}void clearLines() {int linesCleared = 0;for (int i = HEIGHT - 1; i >= 0; i--) {int line = 1;for (int j = 0; j < WIDTH; j++) {if (!field[i][j]) {line = 0;break;}}if (line) {linesCleared++;for (int k = i; k > 0; k--) {for (int j = 0; j < WIDTH; j++) {field[k][j] = field[k-1][j];}}i++;}}score += linesCleared * 100;
}void rotateShape(Shape *shape) {int n = shape->width;char **temp = (char**)malloc(n * sizeof(char*));for (int i = 0; i < n; i++) {temp[i] = (char*)malloc(n * sizeof(char));}// 复制并旋转for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {temp[j][n-1-i] = shape->array[i][j];}}// 复制回原数组for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {shape->array[i][j] = temp[i][j];}}// 释放临时数组for (int i = 0; i < n; i++) {free(temp[i]);}free(temp);
}int main() {srand(time(0));setupConsole();while (1) {if (!current.array) {createShape(¤t, rand() % 5);if (!isValidMove(current, current.row, current.col)) {break;}}drawToBuffer();flushBuffer();if (_kbhit()) {char key = _getch();Shape temp = current;switch(key) {case ',': temp.col--; break; // 左移case '.': temp.col++; break; // 右移case 's': temp.row++; break; // 加速下落case '1': // 旋转rotateShape(&temp);break;}if (isValidMove(temp, temp.row, temp.col)) {current = temp;}}Sleep(300); // 将 100 改为 300,降低下降速度Shape temp = current;temp.row++;if (!isValidMove(temp, temp.row, temp.col)) {mergePiece(current);clearLines();free(current.array);current.array = NULL;} else {current = temp;}}drawToBuffer();sprintf(&buffer[HEIGHT / 2][WIDTH + 1], "Game Over! Score: %d", score);flushBuffer();_getch();return 0;
}