零基础带你学会扫雷的制作-C语言(附有完整代码)

简介: 首先我们得了解扫雷的规则,扫雷的规则我们随便点一个格子,方格即被打开并显示出方格中的数字,方格中数字则表示其周围的8个方格隐藏了几颗雷,点开的数字是几,则说明该数字旁边的8个位置中有几个雷,如果挖开的是地则会输掉游戏,重新开始,所以扫雷也有一定的运气成分。

首先我们得了解扫雷的规则,扫雷的规则我们随便点一个格子,方格即被打开并显示出方格中的数字,方格中数字则表示其周围的8个方格隐藏了几颗雷,点开的数字是几,则说明该数字旁边的8个位置中有几个雷,如果挖开的是地则会输掉游戏,重新开始,所以扫雷也有一定的运气成分。

一.算法的基本逻辑

首先,需要一个二维数组mine去存储雷的分布情况。创建另一个二维数组show存储排雷的信息,在玩游戏期间呈现给玩家。程序所要实现的几个主要功能是:(1).初始化数组 (2).打印数组 (3).设置雷 (4).玩家排雷 (5).返回玩家输入坐标周围雷的个数 。

注:扫雷的基础棋盘是9x9的,计算一个坐标周围雷的个数时,会计算周围八个坐标中雷的个数之和。所以,为了防止当输入坐标在边缘时,计算周围雷的个数时发生数组越界的情况,最终,我创建的二维数组mine和show是11x11的,即棋盘为11x11的,棋盘不是固定的,玩家可以改变棋盘大小,改变游戏难度。

二. 算法的详细步骤

(1).创建数组

创建mine和show,mine[ROWS][COLS],show[ROWS][COLS]

ROWS的值为11,COLS的值为11,以后改变ROWS,COLS的值,可以改变游戏的难度。

(2).初始化数组和打印数组

将mine数组中的元素均初始化为‘0’,将show数组中的元素均初始化为‘*’。打印可以借助双重循环去遍历数组

Initboard(mine,ROWS,COLS,'0');
Initboard(show,ROWS,COLS,'*');

(3).随机布置雷

雷的个数可以控制

#define EASY 1  其中 EASY就是雷的个数

为了使雷分布的比较随机,我们可以使用库函数rand(),需要引用头文件#include<stdlib.h>

在使用rand()之前需要调用srand()生成时间戳,这样可以保证雷的分布更加随机。

但是一定要注意,srand()不能写在随机数生成的循环中,因将srand()放在主函数。

x=rand()%row+1;//范围为1~row,row的值为9
y=rand()%col+1;//范围为1~col,col的值为9

(4).排雷

玩家开始游戏时,则进入循环,游戏结束可以跳出循环。跳出循环时,要么是玩家已经展开除雷外的所有区域,游戏成功;要么是玩家踩到了雷,游戏结束。

玩家输入坐标,若坐标的周围有雷,则坐标会显示周围雷的个数

(5).函数计算周围雷的个数

一个坐标周围的坐标由八个坐标组成。因此,若该坐标周围有雷,排查该坐标后,该坐标应该显示周围八个坐标中雷的个数之和。

int JG(char mine[ROWS][COLS],int x,int y)
{
    return 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';
}

三.源码

由于代码很多,为了让代码更加易读、逻辑性更强,将代码分为main.c,game.c,game.h三个文件编写。

main.c

#include"game.h"
void menu()
{
    printf("******************************\n");
    printf("*            1.play          *\n");
    printf("*            0.exit          *\n");
    printf("******************************\n");
}
void game()
{
    char show[ROWS][COLS];
    char mine[ROWS][COLS];
    Initboard(mine,ROWS,COLS,'0');
    Initboard(show,ROWS,COLS,'*');
    Displayboard(show,ROW,COL);
    Setboard(mine,ROW,COL);
    //Displayboard(mine,ROW,COL);
    Findboard(mine,show,ROW,COL);
}
int main()
{
    int input=0;
    srand((unsigned int)time(NULL));
    do
    {
        menu();
        printf("请选择\n");
        scanf("%d",&input);
        switch(input)
        {
            case 1:
                game();
                break;
            case 0:
                printf("退出游戏\n");
                break;
            default:
                printf("选择错误,重新选择\n");
                break;
        }
    }while(input);
    return 0;
}

game.c

#include "game.h"
void Initboard(char board[ROWS][COLS],int rows,int cols,char set)
{
    int i=0,j=0;
    for(i=0;i<rows;i++)
    {
        for(j=0;j<cols;j++)
        {
            board[i][j]=set;
        }
    }
}
void Displayboard(char board[ROWS][COLS],int row,int col)
{
    printf("———————————————————\n");
    int i=0,j=0;
    for(i=0;i<=row;i++)
    {
        printf("%d ",i);
    }
    printf("\n");
    for(i=1;i<=row;i++)
    {
        printf("%d ",i);
        for(j=1;j<=col;j++)
        {
            printf("%c ",board[i][j]);
        }
        printf("\n");
    }
    printf("———————————————————\n");
}
void Setboard(char mine[ROWS][COLS],int row,int col)
{
    int x=0,y=0;
    int count=0;
    while(count<EASY)
    {
        x=rand()%row+1;
        y=rand()%col+1;
        if(mine[x][y]=='0')
        {
            mine[x][y]='1';
            count++;
        }
    }
}
int JG(char mine[ROWS][COLS],int x,int y)
{
    return 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';
}
void Findboard(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col)
{
    int x=0,y=0;
    int count=0;
    while(count<row*col-EASY)
    {
        printf("请输入排雷坐标\n");
        scanf("%d %d",&x,&y);
        if(x>=1&&x<=row&&y>=1&&y<=col)
        {
            if(show[x][y]=='*')
            {
                if(mine[x][y]=='1')
                {
                    printf("排雷失败,游戏结束\n");
                    Displayboard(mine,ROW,COL);
                    break;
                }
                else
                {
                    int ret=JG(mine,x,y);
                    show[x][y]=ret+'0';
                    Displayboard(show,ROW,COL);
                    count++;
                }
            }
            else
            {
                printf("该坐标被占用,重新输入\n");
            }
        }
        else
        {
            printf("输入坐标非法,重新输入坐标\n");
        }
    }
    if(count==row*col-EASY)
    {
        Displayboard(mine,ROW,COL);
        printf("恭喜排雷成功\n");
    }
}

game.h

#ifndef game_h
#define game_h
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#endif /* game_h */
#define ROWS ROW+2
#define COLS COL+2
#define ROW 3
#define COL 3
#define EASY 1
void Initboard(char board[ROWS][COLS],int rows,int cols,char set);
void Displayboard(char board[ROWS][COLS],int row,int col);
void Setboard(char mine[ROWS][COLS],int row,int col);
void Findboard(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col);



相关文章
|
1月前
|
C语言
扫雷游戏(用C语言实现)
扫雷游戏(用C语言实现)
97 0
|
1月前
|
存储 搜索推荐 C语言
深入C语言指针,使代码更加灵活(二)
深入C语言指针,使代码更加灵活(二)
|
1月前
|
存储 程序员 编译器
深入C语言指针,使代码更加灵活(一)
深入C语言指针,使代码更加灵活(一)
|
1月前
|
C语言
深入C语言指针,使代码更加灵活(三)
深入C语言指针,使代码更加灵活(三)
深入C语言指针,使代码更加灵活(三)
|
1月前
|
存储 算法 安全
C语言实现扫雷游戏
C语言实现扫雷游戏
|
2月前
|
安全 C语言
在C语言中,正确使用运算符能提升代码的可读性和效率
在C语言中,运算符的使用需要注意优先级、结合性、自增自减的形式、逻辑运算的短路特性、位运算的类型、条件运算的可读性、类型转换以及使用括号来明确运算顺序。掌握这些注意事项可以帮助编写出更安全和高效的代码。
50 4
|
1月前
|
C语言
初学者指南:使用C语言实现简易版扫雷游戏
初学者指南:使用C语言实现简易版扫雷游戏
37 0
|
1月前
|
C语言
C语言扫雷游戏(详解)
C语言扫雷游戏(详解)
40 0
|
1月前
|
C语言
C语言练习题代码
C语言练习题代码
|
1月前
|
存储 编译器 C语言
【C语言篇】数组和函数的实践:扫雷游戏(附源码)
【C语言篇】数组和函数的实践:扫雷游戏(附源码)
36 0