【C语言编程】【小游戏】【俄罗斯方块】

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(&current, 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;
}
相关推荐
极客代码几秒前
【Python TensorFlow】入门到精通
开发语言·人工智能·python·深度学习·tensorflow
疯一样的码农7 分钟前
Python 正则表达式(RegEx)
开发语言·python·正则表达式
As977_10 分钟前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
ajsbxi13 分钟前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
Rattenking14 分钟前
React 源码学习01 ---- React.Children.map 的实现与应用
javascript·学习·react.js
&岁月不待人&29 分钟前
Kotlin by lazy和lateinit的使用及区别
android·开发语言·kotlin
StayInLove32 分钟前
G1垃圾回收器日志详解
java·开发语言
TeYiToKu34 分钟前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm
dsywws36 分钟前
Linux学习笔记之时间日期和查找和解压缩指令
linux·笔记·学习
道法自然040237 分钟前
Ethernet 系列(8)-- 基础学习::ARP
网络·学习·智能路由器