【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;
}
相关推荐
学步_技术6 分钟前
Python编码系列—Python桥接模式:连接抽象与实现的桥梁
开发语言·python·桥接模式
柴华松9 分钟前
GPU训练代码
开发语言·python
好兄弟给我起把狙15 分钟前
[Golang] Select
开发语言·后端·golang
Echo_Lee017 分钟前
C#与Python脚本使用共享内存通信
开发语言·python·c#
python之行27 分钟前
python 环境问题
开发语言·python
小林熬夜学编程29 分钟前
C++第五十一弹---IO流实战:高效文件读写与格式化输出
c语言·开发语言·c++·算法
月夕花晨37431 分钟前
C++学习笔记(30)
c++·笔记·学习