【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;
}
相关推荐
“AI国潮设计-小江”6 小时前
《【AIGC实战】Python+SDXL批量生成“猫咪英歌舞蛋挞”IP,附保持角色一致性的代码逻辑》
开发语言·人工智能·python·prompt·aigc
weixin_BYSJ19876 小时前
【计算机毕设】基于Spring_Boot_Vue的马拉松报名与选手成绩追踪系统05445
java·vue.js·spring boot·学习·spring·django·课程设计
艾莉丝努力练剑6 小时前
【AI大模型接入SDK】ChatServer HTTP接口模块实现总览
网络·c++·人工智能·网络协议·学习·http·架构
坤坤子吖6 小时前
Linux 线程概念与控制——线程创建、退出与等待
linux·开发语言·c++·笔记·学习
薛一半6 小时前
Redux实战:组件状态管理全解析
开发语言·前端·javascript·react.js
weixin_307779136 小时前
C++代码实现MATLAB中的fitnlm函数功能
开发语言·c++·算法·matlab
m4Rk_6 小时前
【论文阅读】Agent 记忆机制(103):Dynamic Coding Memory——记忆为何让 Agent 更可靠,却可能更平庸
论文阅读·人工智能·学习·开源·github
qq_284274056 小时前
间歇运动机构与机械设计概论:棘轮与槽轮机构运动系数、零件失效与强度刚度准则、结构工艺性清根及标准件(含考点)
笔记·学习·平面·自动化·制造
白帽攻防录14 小时前
SRC 挖洞:PostScript 打印机驱动双 RCE,打印服务器怎么变成内网跳板
开发语言·网络安全·php·内网安全