扫雷的实现

目录

一、分块编程

二、扫雷的分析

三、扫雷的实现

test.c

game.h

game.c※

 Init_Board初始化棋盘

Display_Board展示棋盘

Set_Mine随机生成雷 

Get_Mine_Count得到周围雷的个数

Find_Mine排查雷

四、结语

五、代码总览

test.c

game.h

game.c


一、分块编程

将函数声明,函数定义,函数运行写在不同的game.h,game.c,test.c文件中,可以可读性,可移植性

二、扫雷的分析

1.打印菜单

2.初始化棋盘

3.随机布置雷

4.排查雷:不是雷,显示周围雷的个数

                 是雷,被炸死,游戏结束

                 如果雷全被找出来,赢了,游戏结束

三、扫雷的实现

test.c

#include "game.h"

   引用“game.h”

打印菜单-menu函数

void menu()
{
    printf("     扫雷游戏!\n");
    printf("##################\n");
    printf("######1.play######\n");
    printf("######0.exit######\n");
    printf("##################\n");
}

游戏的实现-game函数

void game()
{
    char mine[ROWS][COLS] = {0};
    char show[ROWS][COLS] = {0};
    Init_Board(mine,ROWS,COLS,'0');
    Init_Board(show,ROWS,COLS,'#');
    Display_Board(show,ROW,COL);
    Set_Mine(mine,ROW,COL);
    //Display_Board(mine,ROW,COL);//用来调试
    Find_Mine(mine,show,ROW,COL);
}

初始化雷的数组与展示的数组

Init_Board初始化棋盘 mine与show

Display_Board展示棋盘

Set_Mine随机生成雷

Find_Mine排查雷

main函数

int main()
{
    srand((unsigned int)time(NULL));
    int input;
    do
    {
        menu();
        scanf("%d", &input);
        switch(input)
        {
        case 1:
            game();
        case 0:
            break;
        default:
            printf("选择错误,重新选择!\n");
        }
    }while(input);
    return 0;
}  

srand((unsigned int)time(NULL))来初始化rand()的随机值,只需初始化一次所以放在主函数中

打印菜单,并使用do while循环(先执行,再判断下次循环)

     1->执行game函数

     0->退出

     else->重新选择

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 Init_Board(char board[ROWS][COLS], int rows, int cols, char set);
void Display_Board(char board[ROWS][COLS], int row, int col);
void Set_Mine(char board[ROWS][COLS], int row, int col);
void Find_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

引用所需头文件,在.h文件中引用,其他文件引用“game.h”,避免重复引用

#define定义全局变量,改变大小时方便,不用多处修改

先声明函数,之后在定义

game.c※

 Init_Board初始化棋盘

void Init_Board(char board[ROWS][COLS], int rows, int cols, char set)
{
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            board[i][j] = set;
        }
    }
}

可以传入初始化的字符

Display_Board展示棋盘

void Display_Board(char board[ROWS][COLS], int row, int col)
{
    for (int i = 0; i <= row; 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");
    }
}

Set_Mine随机生成雷 

void Set_Mine(char board[ROWS][COLS], int row, int col)
{
    for (int i = 0; i < Easy_Count; i++)
    {
        int x = rand() % row + 1;
        int y = rand() % col + 1;
        if (board[x][y] == '0')
            board[x][y] = '1';
        else
            i--;
    }
}

利用rand函数生成0-9的随即值,将雷布置为‘1’

如果已经布置为雷,就i--,再重新布置一次

Get_Mine_Count得到周围雷的个数

static int Get_Mine_Count(char board[ROWS][COLS], int x, int y)
{
    return board[x - 1][y] + board[x - 1][y + 1] +
           board[x - 1][y - 1] + board[x][y + 1] +
           board[x][y - 1] + board[x + 1][y + 1] +
           board[x + 1][y] + board[x + 1][y - 1] - 8 * '0';
}

static不想除了game.c的文件使用这个函数 

数字的ASCII码值减去‘0’,就是它原本的数字

Find_Mine排查雷

void Find_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
    int x, y, count = 0;
    while (1)
    {
        printf("请输入坐标:");
        scanf("%d %d", &x, &y);;
        if (x >= 1 && x <= row && y >= 1 && y <= col)
        {
            if (mine[x][y] == '0')
            {
                count++;
                show[x][y] = Get_Mine_Count(mine, x, y) + '0';
                Display_Board(show, ROW, COL);
            }
            else
            {
                printf("砰,你被炸死了!\n");
                Display_Board(mine, ROW, COL);
                break;
            }
            if (count == ROW * COL - Easy_Count)
            {
                printf("你赢了!\n");
                break;
            }
        }
        else
            printf("坐标非法,重新输入!\n");
    }
}

先要排查坐标是否合法,再排查

不是雷,显示周围雷的个数,count++,展示棋盘,继续循环

是雷,被炸死,打印雷的棋盘,游戏结束

赢时,count 等于 格子数减去雷数,游戏结束

四、结语

本人也是刚刚入门c语言,扫雷是一个适合学习完数组和函数及其之前内容的同学,挑战自己,加强自己对所学内容掌握能力的很好的程序,如果在写完程序之后,发现有bug,要善于运用调试,在扫雷这个程序中可以将Display_Board这个函数放在不同位置,打印count,改变雷的数量等方法进行调试,验证程序是否有bug,不要害怕出差,我也是经过多次调试,与修改才完成的

本篇文章如有错误,或者值得优化的地方,还请各位大佬多多指出,感谢大家的阅读

下篇文章,将是扫雷的进阶,扩展发现雷函数,感兴趣的朋友点个关注

五、代码总览

test.c

#include "game.h"

void menu()
{
    printf("     扫雷游戏!\n");
    printf("##################\n");
    printf("######1.play######\n");
    printf("######0.exit######\n");
    printf("##################\n");
}

void game()
{
    char mine[ROWS][COLS] = {0};
    char show[ROWS][COLS] = {0};
    Init_Board(mine,ROWS,COLS,'0');
    Init_Board(show,ROWS,COLS,'#');
    Display_Board(show,ROW,COL);
    Set_Mine(mine,ROW,COL);
    //Display_Board(mine,ROW,COL);//用来调试
    Find_Mine(mine,show,ROW,COL);
}

int main()
{
    srand((unsigned int)time(NULL));
    int input;
    do
    {
        menu();
        scanf("%d", &input);
        switch(input)
        {
        case 1:
            game();
        case 0:
            break;
        default:
            printf("选择错误,重新选择!\n");
        }
    }while(input);
    return 0;
}

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 Init_Board(char board[ROWS][COLS], int rows, int cols, char set);
void Display_Board(char board[ROWS][COLS], int row, int col);
void Set_Mine(char board[ROWS][COLS], int row, int col);
void Find_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

game.c

void Expand_Find(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y, int *count);

void Init_Board(char board[ROWS][COLS], int rows, int cols, char set)
{
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            board[i][j] = set;
        }
    }
}

void Display_Board(char board[ROWS][COLS], int row, int col)
{
    for (int i = 0; i <= row; 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 Set_Mine(char board[ROWS][COLS], int row, int col)
{
    for (int i = 0; i < Easy_Count; i++)
    {
        int x = rand() % row + 1;
        int y = rand() % col + 1;
        if (board[x][y] == '0')
            board[x][y] = '1';
        else
            i--;
    }
}

static int Get_Mine_Count(char board[ROWS][COLS], int x, int y)
{
    return board[x - 1][y] + board[x - 1][y + 1] +
           board[x - 1][y - 1] + board[x][y + 1] +
           board[x][y - 1] + board[x + 1][y + 1] +
           board[x + 1][y] + board[x + 1][y - 1] - 8 * '0';
}

void Find_Mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
    int x, y, count = 0;
    while (1)
    {
        printf("请输入坐标:");
        scanf("%d %d", &x, &y);;
        if (x >= 1 && x <= row && y >= 1 && y <= col)
        {
            if (mine[x][y] == '0')
            {
                count++;
                show[x][y] = Get_Mine_Count(mine, x, y) + '0';
                Display_Board(show, ROW, COL);
            }
            else
            {
                printf("砰,你被炸死了!\n");
                Display_Board(mine, ROW, COL);
                break;
            }
            if (count == ROW * COL - Easy_Count)
            {
                printf("你赢了!\n");
                break;
            }
        }
        else
            printf("坐标非法,重新输入!\n");
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值