05 C语言扫雷

C语言实现扫雷

这是一个经典的项目

思路及步骤

  1. 基本流程

游戏进入界面–>进入选项–>进入游戏

  1. 游戏内容及准备

游戏使用棋盘为9*9。

存有雷的棋盘(有雷是1) >>> 数组11*11(加一圈好计算)

展示周围雷数的棋盘 (因为有可能出现1所以需要新的)>>> 数组11*11(这个是为了和存有雷的棋盘相对应)

初始化棋盘
void InitBoard(char board[ROWS][COLS],int rows,int cols,char full){
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            board[i][j] = full;//填充传过来的要求字符。
        }
    }
}
展示棋盘
void DisplayBoard(char board[ROWS][COLS],int row,int col){
    printf("\n");
    //打印列号
    for (int i = 0; i <= col; ++i) {
        printf(" %d ",i);
    }
    printf("\n");
    for (int i = 1; i <= row; ++i) {
        printf(" %d ",i);
        for (int j = 1; j <= col; ++j) {
            printf(" %c ",board[i][j]);
        }
        printf("\n");
    }
}
布置雷
void SetMine(char board[ROWS][COLS],int row,int col){
    int count = EASY_COUNT;//雷的总个数
    while(count){
        int x = rand()%row+1;// 我们需要的是 1-9
        int y = rand()%col+1;//随机生成0-8,加一得
        if (board[x][y] == '0'){
            board[x][y] = '1';
            count--;
        }
    }
}
扫雷

扫雷的过程中需要知道周围的雷数。也是比较复杂的代码。独立成函数模块

// 获取周围的雷数
int get_mine_count(char mine[ROWS][COLS],int x,int y){
    //这里可以int count  然后遍历周围的八个。
    //但是这里使用的思路周围所有数字总和为雷数。但是这里是char类型利用ASCII码的性质与'0'求差。
    int count = mine[x-1][y-1]+mine[x-1][y]+mine[x-1][y+1]+
    mine[x][y-1]+mine[x][y+1]+mine[x+1][y-1]+
    mine[x+1][y]+mine[x+1][y+1] - 8*'0';
    return count;
}
// 扫雷
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col){
    int x;
    int y;
    int win =0;
    while (win<row*col-EASY_COUNT){
        printf("请输入排查的雷的坐标:\n");
        scanf("%d%d",&x,&y);
        if (x>=1 && x<=row && y>=1 && y<=col){
            //坐标合法
            //1.踩雷了
            if (mine[x][y]=='1'){
                printf("很遗憾,你被炸死了。\n");
                DisplayBoard(mine,row,col);
            } else{
                win++;
                //计算周围有几个雷
                int count = get_mine_count(mine,x,y);
                show[x][y] = count+'0';
                DisplayBoard(show,row,col);

            }

        } else{
            printf("您输入的坐标有误,请重新输入。\n");
        }
    }
    if (win==row*col-EASY_COUNT){
        printf("恭喜你,排雷成功");
        DisplayBoard(mine,row,col);
    }
}

一点打开一大片可以使用递归函数。

# 终止条件,周围有雷。
# 每次解决:
 1. 周围没有雷show数组在该位置改为' '。
 2. 周围的8个中有没有雷。--》提供思路。

代码展示

main.c
//
// Created by Tian_baby on 2021/12/30.
//

#include "game.h"
//打印初识目录界面
void menu(){
    printf("*****************************\n");
    printf("********   扫   雷   *********\n");
    printf("****  1. play   0. exit  ****\n");
    printf("*****************************\n");
}

//游戏的实现
void game(){
    // 1.布置好雷的棋盘
    char mine[ROWS][COLS] = {0};
    // 2.有每点周围雷的棋盘
    char show[ROWS][COLS] = {0};
    char res = 0;
    //初始化棋盘都是空格
    InitBoard(mine,ROWS,COLS,'0');
    InitBoard(show,ROWS,COLS,'*');

    //打印棋盘
    DisplayBoard(show,ROW,COL);
    //布置雷
    SetMine(mine,ROW,COL);
    // 查找雷
    FindMine(mine,show,ROW,COL);

}

// 游戏流程
void test(){
    int input = 0;//功能选择输入项
    // 随机数
    srand((unsigned int)time(NULL));
    // 控制游戏的重复
    do {
        menu();
        printf("请选择: ");
        scanf( "%d",&input);
        switch (input) {
            case 1:
                game();//游戏内容
                break;
            case 0:
                printf("退出游戏\n");
                break;
            default:
                printf("输入错误,请重新输入\n");
                break;
        }
    } while (input);
}

// 主函数
int main() {
    test();
    return 0;
}

game.h
//
// Created by Tian baby on 2021/12/30.
//

#ifndef TEST_12_31_GAME_H
#define TEST_12_31_GAME_H

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 9       //显示的行
#define COL 9       //显示的列
#define ROWS ROW+2      //实际使用的行
#define COLS COL+2      //实际使用的列
#define EASY_COUNT 10   //简单难度雷的总数
//初始化棋盘
void InitBoard(char board[ROWS][COLS],int rows,int cols,char full);
//展示棋盘
void DisplayBoard(char board[ROWS][COLS],int row,int col);
//布置雷区
void SetMine(char board[ROWS][COLS],int row,int col);
//扫雷
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col);


#endif //TEST_12_31_GAME_H

game.c

//
// Created by Tian baby on 2021/12/30.
//

#include "game.h"
//初始化棋盘
void InitBoard(char board[ROWS][COLS],int rows,int cols,char full){
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            board[i][j] = full;//填充传过来的要求字符。
        }
    }
}
//展示棋盘
void DisplayBoard(char board[ROWS][COLS],int row,int col){
    printf("\n");
    //打印列号
    for (int i = 0; i <= col; ++i) {
        printf(" %d ",i);
    }
    printf("\n");
    for (int i = 1; i <= row; ++i) {
        printf(" %d ",i);
        for (int j = 1; j <= col; ++j) {
            printf(" %c ",board[i][j]);
        }
        printf("\n");
    }
}

//布置雷
void SetMine(char board[ROWS][COLS],int row,int col){
    int count = EASY_COUNT;//雷的总个数
    while(count){
        int x = rand()%row+1;// 我们需要的是 1-9
        int y = rand()%col+1;//随机生成0-8,加一得
        if (board[x][y] == '0'){
            board[x][y] = '1';
            count--;
        }
    }
}
// 获取周围的雷数
int get_mine_count(char mine[ROWS][COLS],int x,int y){
    //这里可以int count  然后遍历周围的八个。
    //但是这里使用的思路周围所有数字总和为雷数。但是这里是char类型利用ASCII码的性质与'0'求差。
    int count = mine[x-1][y-1]+mine[x-1][y]+mine[x-1][y+1]+
    mine[x][y-1]+mine[x][y+1]+mine[x+1][y-1]+
    mine[x+1][y]+mine[x+1][y+1] - 8*'0';
    return count;
}
// 扫雷
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col){
    int x;
    int y;
    int win =0;
    while (win<row*col-EASY_COUNT){
        printf("请输入排查的雷的坐标:\n");
        scanf("%d%d",&x,&y);
        if (x>=1 && x<=row && y>=1 && y<=col){
            //坐标合法
            //1.踩雷了
            if (mine[x][y]=='1'){
                printf("很遗憾,你被炸死了。\n");
                DisplayBoard(mine,row,col);
            } else{
                win++;
                //计算周围有几个雷
                int count = get_mine_count(mine,x,y);
                show[x][y] = count+'0';
                DisplayBoard(show,row,col);
            }

        } else{
            printf("您输入的坐标有误,请重新输入。\n");
        }
    }
    if (win==row*col-EASY_COUNT){
        printf("恭喜你,排雷成功");
        DisplayBoard(mine,row,col);
    }
}

运行结果

image-20211231012446853

image-20211231012722725

image-20211231012921590

因为没有实现一点空白出现一大片的功能所以就直接设置了80个雷,并且显示棋盘获胜,从而测试代码的正确性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黎丶辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值