css
复制代码
#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;
}