编辑代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// 方块结构体
struct Block {
    char c;
    int isFlagged;  // 是否标记为地雷
    int isQuestion; // 是否标记为问号
    int isClicked;  // 是否被点击
    int value;      // 方块的数字提示
};

// 游戏配置参数
struct GameConfig {
    int rows;        // 雷区行数
    int cols;        // 雷区列数
    int mineCount;   // 雷数
    int level;       // 游戏级别
};

int T=0;
int mine=0;
int con=0;
// 玩家操作类型
enum ActionType {
    LEFT_CLICK = 1,        // 左键单击
    RIGHT_CLICK_FLAG = 2,  // 右键单击标记地雷
    RIGHT_CLICK_QUESTION = 3,  // 右键单击标记问题
    RIGHT_CLICK_UNFLAG = 4,  // 右键单击取消地雷标记
    DOUBLE_CLICK = 9       // 双击
};



// 初始化雷区
void initializeBoard(struct Block** board, int rows, int cols) {
    int i, j;
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            board[i][j].c='.';
            board[i][j].isFlagged = 0;
            board[i][j].isQuestion = 0;
            board[i][j].isClicked = 0;
            board[i][j].value = 0;
        }
    }
}

// 设置地雷
void setMines(struct Block** board, int rows, int cols) {
    for(int i=0;i<rows;i++){
        char array[100];
        scanf("%s",&array);
        for(int j=0;j<cols;j++){
            board[i][j].c=array[j];
        }
    }
    
}

// 打印雷区
void printBoard(struct Block** board, int rows, int cols) {
    int i, j;

    int ttt=0;
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            if(board[i][j].c!='*'&&!board[i][j].isClicked){
                ttt++;
            }
        }
    }
    if(ttt==0)T=2;

    con++;
    if(T==0){
        printf("Game in progress\n");
    }
    else if(T==1){
        printf("Hit mine, you lose\n");
    }
    else {
        printf("Game over, you win\n");
    }
    printf("%d %d %d\n",con,mine,T);
    printf("\n");
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            if(board[i][j].isClicked){
                printf("%d",board[i][j].value);
            }
            else if(board[i][j].isFlagged){
                printf("!");
            }
            else if(board[i][j].isQuestion){
                printf("?");
            }
            else{
                if(T==0)printf(".");
                else printf("%c",board[i][j].c);
            }

            
            //printf("%c",board[i][j].c);

            /*
            if (board[i][j].isClicked) {
                if (board[i][j].isMine) {
                    printf("*  ");
                } else {
                    printf("%d  ", board[i][j].value);
                }
            } else if (board[i][j].isFlagged) {
                printf("F  ");
            } else if (board[i][j].isQuestion) {
               
                printf("?  ");
            } else {
                printf(".  ");
            }
            */
        }
        printf("\n");
    }
}


// 处理玩家操作
void handleAction(struct Block** board, int rows, int cols, int actionType, int row, int col) {
    // 检查方块坐标是否越界
    if (row < 0 || row >=rows || col < 0 || col >=cols&&board[row][col].isClicked) {
        //printf("无效的方块坐标。\n");
        return;
    }
    
    // 获取操作的方块
    //struct Block* block = &board[row - 1][col - 1];

    // 根据操作类型处理方块
    switch (actionType) {
        case LEFT_CLICK:
        {
            if(board[row][col].isFlagged||board[row][col].isQuestion||board[row][col].isClicked){
                return ;
            }
            int x=row,y=col;
            int i,j;

            if(board[x][y].c=='*'){
                T=1;return ;
            }

            
            //printf("%d %d\n",row,col);
            for(i=x-1;i<=x+1;i++)
            {
                for(j=y-1;j<=y+1;j++){
                    //printf("%d %d \n",i,j);
                    if(i>=0&&i<rows && j>=0 &&j<cols && board[i][j].c=='*'){
                        board[row][col].value++;
                    }
                }
            }
            board[row][col].isClicked=1;

            if(board[row][col].value==0){
                for(i=x-1;i<=x+1;i++)
                {
                    for(j=y-1;j<=y+1;j++){
                        //printf("%d %d \n",i,j);
                        handleAction(board,rows,cols,1,i,j);

                    }
                }
            }
            break;
        }
        case RIGHT_CLICK_FLAG:
            if (board[row][col].isClicked) {
                return ;
            } 
            else if(board[row][col].isFlagged){
                ;
            }
            else{
                mine--;
                board[row][col].isFlagged=1;
                board[row][col].isQuestion=0;
            }
            break;
        case RIGHT_CLICK_QUESTION:
            if (board[row][col].isClicked) {
                return ;
            } 
            else if(board[row][col].isQuestion){
                ;
            }
            else{
                mine++;
                board[row][col].isFlagged=0;
                board[row][col].isQuestion=1;
            }
            break;
        case RIGHT_CLICK_UNFLAG:
            if (board[row][col].isClicked) {
                return ;
            } 
            else if(board[row][col].isFlagged){
                board[row][col].isFlagged=0;mine++;
            }
            else if(board[row][col].isQuestion){
                board[row][col].isQuestion=0;
            }
            break;
        case DOUBLE_CLICK:
        {
            if(!board[row][col].isClicked){
                return ;
            }
            int x=row,y=col;
            int i,j;

            
            int sum=0;
            for(i=x-1;i<=x+1;i++)
            {
                for(j=y-1;j<=y+1;j++){
                    //printf("%d %d \n",i,j);
                    if(i>=0&&i<rows && j>=0 &&j<cols&&board[i][j].isFlagged){
                        sum++;
                    }
                }
            }
            if(board[row][col].value==sum){
                for(i=x-1;i<=x+1;i++)
                {
                    for(j=y-1;j<=y+1;j++){
                        //printf("%d %d \n",i,j);
                        if(i>=0&&i<rows && j>=0 &&j<cols&&!board[i][j].isClicked){
                            handleAction(board,rows,cols,1,i,j);
                        }
                    }
                }
            }
            break;
        }
    }
}










// 主函数
int main() {
    struct GameConfig config;
    //printf("请输入游戏级别(1-初级,2-中级,3-高级,4-自定义):");
    scanf("%d", &(config.level));
    
    if (config.level == 4) {
        scanf("%d %d %d", &(config.rows), &(config.cols), &(config.mineCount));
    } else {
        
        switch (config.level) {
            case 1:
                config.rows = 9;
                config.cols = 9;
                config.mineCount = 10;
                break;
            case 2:
                config.rows = 16;
                config.cols = 16;
                config.mineCount = 40;
                break;
            case 3:
                config.rows = 16;
                config.cols = 30;
                config.mineCount = 99;
                break;
        }
    }
    mine=config.mineCount;
    
    // 动态分配雷区内存并初始化
    struct Block** board = (struct Block**)malloc(config.rows * sizeof(struct Block*));
    for (int i = 0; i < config.rows; i++) {
        board[i] = (struct Block*)malloc(config.cols * sizeof(struct Block));
    }
    initializeBoard(board, config.rows, config.cols);
    
    // 设置地雷
    setMines(board, config.rows, config.cols);
    


    

    while(1){
        int actionType,row,col;
        scanf("%d %d %d",&actionType,&row,&col);
        row--;col--;
        handleAction(board,config.rows, config.cols,actionType,row,col);
       
        
        printBoard(board, config.rows, config.cols);

        if(T!=0)break;
    }

    // 释放内存
    for (int i = 0; i < config.rows; i++) {
        free(board[i]);
    }
    free(board);
    
    return 0;
}