俄罗斯方块 应该会有些小bug 😅😅😅😅😅😅🥹

#include <iostream>
#include <vector>
#include <conio.h>   // 用于键盘输入检测
#include <windows.h> // 用于控制台控制和延时
#include <cstdlib>   // 随机数
#include <ctime>     // 随机数种子

using namespace std;

// 控制台光标位置控制
void gotoxy(int x, int y) {
    COORD pos = {x, y};
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

// 隐藏控制台光标
void hideCursor() {
    CONSOLE_CURSOR_INFO cursorInfo;
    GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
    cursorInfo.bVisible = false;
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
}

// 显示控制台光标(用于菜单选择)
void showCursor() {
    CONSOLE_CURSOR_INFO cursorInfo;
    GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
    cursorInfo.bVisible = true;
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
}

// 设置控制台文字颜色
void setColor(int color) {
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}

// 方块形状定义 (7种基础形状,每种包含旋转状态)
const int SHAPES[7][4][4] = {
    // I 型
    {{0,0,0,0},
     {1,1,1,1},
     {0,0,0,0},
     {0,0,0,0}},
    // O 型
    {{0,0,0,0},
     {0,1,1,0},
     {0,1,1,0},
     {0,0,0,0}},
    // T 型
    {{0,0,0,0},
     {0,1,0,0},
     {1,1,1,0},
     {0,0,0,0}},
    // L 型
    {{0,0,0,0},
     {0,0,1,0},
     {1,1,1,0},
     {0,0,0,0}},
    // J 型
    {{0,0,0,0},
     {1,0,0,0},
     {1,1,1,0},
     {0,0,0,0}},
    // S 型
    {{0,0,0,0},
     {0,1,1,0},
     {1,1,0,0},
     {0,0,0,0}},
    // Z 型
    {{0,0,0,0},
     {1,1,0,0},
     {0,1,1,0},
     {0,0,0,0}}
};

// 游戏常量
const int WIDTH = 10;    // 游戏区域宽度
const int HEIGHT = 20;   // 游戏区域高度
const int PREVIEW_X = 15; // 预览区域X坐标
const int PREVIEW_Y = 2;  // 预览区域Y坐标

// 游戏全局变量
int gameBoard[HEIGHT][WIDTH] = {0}; // 游戏棋盘
int currentShape;                  // 当前方块类型 (0-6)
int currentRotation;               // 当前旋转角度 (0-3)
int currentX, currentY;            // 当前方块位置
int nextShape;                     // 下一个方块类型
int score = 0;                     // 得分
bool gameOver = false;             // 游戏结束标志

// 生成随机方块
int randomShape() {
    return rand() % 7;
}

// 绘制单个方块
void drawBlock(int x, int y, int type) {
    gotoxy(x * 2, y);
    if (type == 0) {
        cout << "  "; // 空白
    } else {
        setColor(14); // 黄色方块
        cout << "■"; // 方块字符
        setColor(7);  // 恢复默认颜色
    }
}

// 绘制游戏边框
void drawBorder() {
    // 上边框
    gotoxy(0, 0);
    cout << "+";
    for (int i = 0; i < WIDTH; i++) cout << "--";
    cout << "+";
    
    // 侧边框
    for (int i = 0; i < HEIGHT; i++) {
        gotoxy(0, i + 1);
        cout << "|";
        gotoxy(WIDTH * 2 + 1, i + 1);
        cout << "|";
    }
    
    // 下边框
    gotoxy(0, HEIGHT + 1);
    cout << "+";
    for (int i = 0; i < WIDTH; i++) cout << "--";
    cout << "+";
    
    // 预览区域边框
    gotoxy(PREVIEW_X * 2, PREVIEW_Y);
    cout << "下一个:";
    gotoxy(PREVIEW_X * 2, PREVIEW_Y + 1);
    cout << "+------+";
    for (int i = 0; i < 4; i++) {
        gotoxy(PREVIEW_X * 2, PREVIEW_Y + 2 + i);
        cout << "|      |";
    }
    gotoxy(PREVIEW_X * 2, PREVIEW_Y + 6);
    cout << "+------+";
    
    // 得分显示
    gotoxy(PREVIEW_X * 2, PREVIEW_Y + 8);
    cout << "得分: " << score;
    
    // 操作提示
    gotoxy(PREVIEW_X * 2, PREVIEW_Y + 10);
    cout << "操作说明:";
    gotoxy(PREVIEW_X * 2, PREVIEW_Y + 11);
    cout << "← → : 移动";
    gotoxy(PREVIEW_X * 2, PREVIEW_Y + 12);
    cout << "↑   : 旋转";
    gotoxy(PREVIEW_X * 2, PREVIEW_Y + 13);
    cout << "↓   : 加速";
    gotoxy(PREVIEW_X * 2, PREVIEW_Y + 14);
    cout << "空格 : 速降";
    gotoxy(PREVIEW_X * 2, PREVIEW_Y + 15);
    cout << "Q   : 退出";
}

// 绘制游戏棋盘
void drawBoard() {
    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            drawBlock(x, y + 1, gameBoard[y][x]);
        }
    }
}

// 绘制当前方块
void drawCurrentShape() {
    for (int y = 0; y < 4; y++) {
        for (int x = 0; x < 4; x++) {
            if (SHAPES[currentShape][currentRotation][y * 4 + x] == 1) {
                drawBlock(currentX + x, currentY + y + 1, 1);
            }
        }
    }
}

// 清除当前方块(用于移动时重绘)
void clearCurrentShape() {
    for (int y = 0; y < 4; y++) {
        for (int x = 0; x < 4; x++) {
            if (SHAPES[currentShape][currentRotation][y * 4 + x] == 1) {
                drawBlock(currentX + x, currentY + y + 1, 0);
            }
        }
    }
}

// 绘制预览方块
void drawPreviewShape() {
    // 清空预览区域
    for (int y = 0; y < 4; y++) {
        for (int x = 0; x < 4; x++) {
            gotoxy(PREVIEW_X * 2 + x * 2 + 1, PREVIEW_Y + 2 + y);
            cout << "  ";
        }
    }
    
    // 绘制预览方块
    for (int y = 0; y < 4; y++) {
        for (int x = 0; x < 4; x++) {
            if (SHAPES[nextShape][0][y * 4 + x] == 1) {
                gotoxy(PREVIEW_X * 2 + x * 2 + 1, PREVIEW_Y + 2 + y);
                setColor(14);
                cout << "■";
                setColor(7);
            }
        }
    }
}

// 检查碰撞
bool checkCollision(int x, int y, int rotation) {
    for (int dy = 0; dy < 4; dy++) {
        for (int dx = 0; dx < 4; dx++) {
            if (SHAPES[currentShape][rotation][dy * 4 + dx] == 1) {
                int newX = x + dx;
                int newY = y + dy;
                
                // 边界检测
                if (newX < 0 || newX >= WIDTH || newY >= HEIGHT) {
                    return true;
                }
                
                // 棋盘碰撞检测
                if (newY >= 0 && gameBoard[newY][newX] == 1) {
                    return true;
                }
            }
        }
    }
    return false;
}

// 生成新方块
void newShape() {
    currentShape = nextShape;
    nextShape = randomShape();
    currentRotation = 0;
    currentX = WIDTH / 2 - 2;
    currentY = 0;
    
    // 检测游戏结束(新方块刚生成就碰撞)
    if (checkCollision(currentX, currentY, currentRotation)) {
        gameOver = true;
    }
    
    drawPreviewShape();
}

// 固定方块到棋盘
void lockShape() {
    for (int y = 0; y < 4; y++) {
        for (int x = 0; x < 4; x++) {
            if (SHAPES[currentShape][currentRotation][y * 4 + x] == 1) {
                int boardX = currentX + x;
                int boardY = currentY + y;
                if (boardY >= 0) {
                    gameBoard[boardY][boardX] = 1;
                }
            }
        }
    }
}

// 消除满行
void clearLines() {
    int linesCleared = 0;
    
    for (int y = HEIGHT - 1; y >= 0; y--) {
        bool fullLine = true;
        
        // 检查是否满行
        for (int x = 0; x < WIDTH; x++) {
            if (gameBoard[y][x] == 0) {
                fullLine = false;
                break;
            }
        }
        
        // 消除满行
        if (fullLine) {
            linesCleared++;
            
            // 上面的行向下移动
            for (int yy = y; yy > 0; yy--) {
                for (int x = 0; x < WIDTH; x++) {
                    gameBoard[yy][x] = gameBoard[yy - 1][x];
                }
            }
            
            // 清空第一行
            for (int x = 0; x < WIDTH; x++) {
                gameBoard[0][x] = 0;
            }
            
            // 重新检查当前行(因为上面的行掉下来了)
            y++;
        }
    }
    
    // 更新得分 (消行数越多得分越高)
    if (linesCleared > 0) {
        score += linesCleared * 100;
        gotoxy(PREVIEW_X * 2, PREVIEW_Y + 8);
        cout << "得分: " << score;
    }
}

// 旋转方块
void rotateShape() {
    int newRotation = (currentRotation + 1) % 4;
    if (!checkCollision(currentX, currentY, newRotation)) {
        clearCurrentShape();
        currentRotation = newRotation;
        drawCurrentShape();
    }
}

// 移动方块
void moveShape(int dx, int dy) {
    if (!checkCollision(currentX + dx, currentY + dy, currentRotation)) {
        clearCurrentShape();
        currentX += dx;
        currentY += dy;
        drawCurrentShape();
        return;
    }
    
    // 如果是向下移动且碰撞,说明方块落地
    if (dy > 0) {
        lockShape();
        clearLines();
        newShape();
    }
}

// 快速下落
void dropShape() {
    while (!checkCollision(currentX, currentY + 1, currentRotation)) {
        moveShape(0, 1);
    }
}

// 初始化游戏
void initGame() {
    // 重置游戏数据
    memset(gameBoard, 0, sizeof(gameBoard));
    score = 0;
    gameOver = false;
    
    srand(time(0));          // 设置随机数种子
    hideCursor();            // 隐藏光标
    system("cls");           // 清屏
    drawBorder();            // 绘制边框
    drawBoard();             // 绘制棋盘
    
    // 初始化第一个和下一个方块
    currentShape = randomShape();
    nextShape = randomShape();
    currentRotation = 0;
    currentX = WIDTH / 2 - 2;
    currentY = 0;
    
    drawPreviewShape();
    drawCurrentShape();
}

// 游戏主循环
void gameLoop() {
    int fallTime = 0;
    const int fallSpeed = 30; // 下落速度(数值越小越快)
    
    while (!gameOver) {
        // 键盘控制
        if (_kbhit()) {
            switch (_getch()) {
                case 75: // 左方向键
                    moveShape(-1, 0);
                    break;
                case 77: // 右方向键
                    moveShape(1, 0);
                    break;
                case 72: // 上方向键 (旋转)
                    rotateShape();
                    break;
                case 80: // 下方向键
                    moveShape(0, 1);
                    break;
                case ' ': // 空格键 (快速下落)
                    dropShape();
                    break;
                case 'q': // Q键退出
                    gameOver = true;
                    break;
            }
        }
        
        // 自动下落
        if (fallTime >= fallSpeed) {
            moveShape(0, 1);
            fallTime = 0;
        }
        fallTime++;
        
        Sleep(10); // 控制游戏帧率
    }
    
    // 游戏结束显示
    gotoxy(WIDTH - 3, HEIGHT / 2);
    setColor(12); // 红色
    cout << "游戏结束!";
    setColor(7);  // 恢复默认颜色
    gotoxy(WIDTH - 4, HEIGHT / 2 + 1);
    cout << "最终得分: " << score;
    gotoxy(WIDTH - 6, HEIGHT / 2 + 2);
    cout << "按任意键返回菜单";
    _getch();
}

// 绘制开始界面
void drawStartMenu(int selectedOption) {
    system("cls");
    hideCursor();
    
    // 游戏标题
    int titleX = 15;
    int titleY = 5;
    
    gotoxy(titleX, titleY);
    setColor(11); // 淡蓝色
    cout << "╔════════════════════════════════════╗";
    gotoxy(titleX, titleY + 1);
    cout << "║            俄罗斯方块游戏           ║";
    gotoxy(titleX, titleY + 2);
    cout << "╚════════════════════════════════════╝";
    setColor(7);
    
    // 菜单选项
    int menuX = 25;
    int menuY = 10;
    
    gotoxy(menuX, menuY);
    if (selectedOption == 0) {
        setColor(14); // 黄色高亮
        cout << "● 开始游戏";
    } else {
        cout << "  开始游戏";
    }
    setColor(7);
    
    gotoxy(menuX, menuY + 1);
    if (selectedOption == 1) {
        setColor(14);
        cout << "● 退出游戏";
    } else {
        cout << "  退出游戏";
    }
    setColor(7);
    
    // 版权信息
    gotoxy(20, 18);
    setColor(8); // 灰色
    cout << "按 ↑↓ 选择,按 Enter 确认";
    setColor(7);
    
    // 移动光标到选中项
    gotoxy(menuX - 2, menuY + selectedOption);
    showCursor();
}

// 开始界面菜单逻辑
int startMenu() {
    int selectedOption = 0;
    const int totalOptions = 2;
    
    drawStartMenu(selectedOption);
    
    while (true) {
        if (_kbhit()) {
            int key = _getch();
            switch (key) {
                case 72: // 上方向键
                    selectedOption = (selectedOption - 1 + totalOptions) % totalOptions;
                    drawStartMenu(selectedOption);
                    break;
                case 80: // 下方向键
                    selectedOption = (selectedOption + 1) % totalOptions;
                    drawStartMenu(selectedOption);
                    break;
                case 13: // 回车键
                    return selectedOption;
                    break;
            }
        }
        Sleep(10);
    }
}

int main() {
    // 设置控制台编码(解决中文乱码)
    SetConsoleOutputCP(CP_UTF8);
    
    while (true) {
        int choice = startMenu();
        if (choice == 0) {
            // 开始游戏
            initGame();
            gameLoop();
        } else if (choice == 1) {
            // 退出游戏
            system("cls");
            gotoxy(25, 10);
            cout << "感谢游玩!";
            Sleep(1000);
            break;
        }
    }
    
    return 0;
}