【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;
}
相关推荐
Logintern0913 分钟前
[Matlab] 遗传算法求解TSP入门
开发语言·matlab
云半S一14 分钟前
Python学习总结
python·学习·学习分享
练习时长两年半的RL练习生1 小时前
与AI对话后对 Actor-Critic 中 TD Target 的 a‘ 来源总结
开发语言·人工智能·php
科信集团1 小时前
政策科普|广东省绿色制造体系全解读
学习·制造·绿色
十五年专注C++开发1 小时前
100w条数据丝滑滚动!Qt Model/View 架构实战(二)
开发语言·c++·qt
迪丽热爱2 小时前
多媒体应用9-823
学习
萧瑟余晖2 小时前
Java深入解析篇三十九之集成测试
java·开发语言·集成测试
skr爱码士2 小时前
06_Qt 常用数据类型与容器:QString、QList、QVector、QMap 的性能与实现分析
开发语言·c++·qt
m4Rk_2 小时前
【论文阅读】Agent 记忆机制(48):Fine-Mem——用细粒度奖励解决长期记忆管理中的奖励稀疏与信用分配
论文阅读·人工智能·学习·开源·github
总有刁民想爱朕ha2 小时前
零基础Python开发「图片批量转MP4视频」工具,本地离线、免费无水印
开发语言·python·音视频