7.C语言 如何实现扫雷游戏

本文围绕扫雷游戏展开,介绍了其大体设计、思想架构和代码实现。涉及test.c文件实现进入和退出游戏界面及调用游戏函数,game.h游戏头文件,game.c源文件包含初始化棋盘、打印棋盘界面、布置雷和排查雷等函数,还提及写代码时遇到的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


咱们来用C语言写一个扫雷游戏吧。
棋盘格子是9*9,默认设置10个雷
先设想粗糙的游戏画面

在这里插入图片描述
在这里插入图片描述

扫雷游戏大体设计、思想架构和代码实现

test.c文件
game.h头文件
game.c文件

(1)test.c文件

调用菜单函数实现进入游戏和退出游戏功能的界面,
调用游戏函数嵌套调用初始化棋盘函数,打印棋盘界面函数,布置雷函数,排查雷函数。
代码实现:

#include"game.h"
void menu()
{
    printf("**********************\n");
    printf("***** 1.开始游戏 *****\n");
    printf("***** 0.退出游戏 *****\n");
    printf("**********************\n");
}
void game()
{
    char mine[ROWS][COLS];
    char show[ROWS][COLS];
    InitBoard(mine, ROWS, COLS, '0');// 先初始化第一个mine数组,最开始全是'0'
    InitBoard(show, ROWS, COLS, '*');// 然后初始化第二个show数组,全是 '*'。
    DisplayBoard(show, ROW, COL);
    SetMine(mine, ROW, COL);
    FindMine(mine, show, ROW, COL);
}
int main()
{
    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);

    return 0;
}

(2)game.h游戏头文件

声明函数
声明函数
声明函数
声明函数
引用
宏定义define
game.h
初始化棋盘
打印棋盘
布置雷
排查雷
需要的头文件
行列和10个雷
InitBoard
DisplayBoard
SetMine
FindMine

代码实现:
game.h:

#pragma once
#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 set);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char board[ROWS][COLS], int row, int cow);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

(3)game.c源文件

1.初始化棋盘函数, 11*11的二维数组board[rows][cols]。(为什么是11行11列后面的GetMineCount函数有说明)
在这里插入图片描述

先初始化第一个mine数组,最开始全是‘0’,
然后初始化第二个show数组,全是’ * '。

Created with Raphaël 2.3.0 InitBoard i=0,j=0 i<rows? j<cols board[i][j]=set j++ 结束 yes no yes no
#include"game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
    int i = 0;
    int j = 0;
    for (i = 0; i < rows; i++)
    { 
        
        for (j = 0; j < cols; j++)
        {
            board[i][j] = set;
        }
    }
}

2.打印棋盘界面函数,9*9的二维数组board[rows][cols]棋盘界面,
在这里插入图片描述

第一个循环
第二个循环
第三个循环
DisplayBoard
实现x轴坐标0-9
实现y轴坐标
打印show数组下标1-9
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
    int i = 0;
       int j = 0;
    printf("-------扫雷游戏--------\n");
    for (i = 0; i <=col; 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");
    }

}

3.布置雷函数。实现随机10个雷分布在元素全为0的9*9的二维数组board[rows][cols]中,将1~9生成随机的坐标布置成雷。棋盘本来全是0,所以雷赋值为1。

随机数下标
假--count减1
count减1
SetMine
10个雷count
每次循环生成下标的随机数
下标对应的元素为0
将1赋值该下标的元素
end
 void SetMine(char board[ROWS][COLS], int row, int col)
{
    int count = EASY_COUNT;
   
    while (count)
    {
        int x =  1+rand() % row;//行坐标的随机数
        int y =  1+rand() % col;//列坐标的随机数
        if (board[x][y] == '0')
        {
            board[x][y] = '1';
            count--;
        } 
        
    }


}

随机数生成可以观看文章猜数字有详细说明
http://t.csdn.cn/KvfjN

4.排查雷函数。
思路:总空间9*9-10个雷=71,我们要排除完71个空间,排雷成功,游戏结束。

Yes
yes
yes
no
yes
no
no
No
win < row * col - EASY_COUNT
输入下标x,y
在1-9下标范围内
show数组下标xy对应的元素不是*
已排查过重新输入
mine数组下标xy对应的元素是1
被炸死打印mine数组
调用GetMineCount计算周围雷的个数
雷的个数赋值show数组对应下标的元素
打印show数组win++
重新输入
打印mine数组

GetMineCount函数,实现返回坐标(x,y)周围雷的个数(这也是为什么最初的数组要设置成11行11列,因为会超过9行9列范围找雷个数)
数字字符转换成数字规律是,数字字符相减转换成ASCLL码相减。
例如’1’-‘0’=49-48=1 ‘2’-‘0’=50-48=2
所以:
周围雷的个数==除了(x,y)的所有坐标对应的字符’0’或’1’相加-8字符’0’
在这里插入图片描述
例如要找这个四个角的周围的雷就会超出9
9,所以我们实际范围是11*11
在这里插入图片描述
当我们用下标显示时,实际是这样的:
在这里插入图片描述

代码实现
game.c:

//static保证了该函数仅在game.c文件中实现
static int GetMineCount(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 FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
    int x = 0;
    int y = 0;
    int win = 0;
    while (win < row * col - EASY_COUNT)
    {
        printf("请输入要查找的坐标:>");
        scanf("%d %d", &x, &y);
        if (x >= 1 && x <= row && y >= 1 && y <= col)
        {
         //如果输入的坐标已经排查过,则要重新输入
            if (show[x][y] != '*')
            {
                printf("该坐标已排查过,请重新输入\n");
            }
               else if (mine[x][y] == '1')
              {
                printf("你被炸死了,游戏结束\n");
                DisplayBoard(mine, ROW, COL);
                break;
              }
              else
             {
                int count = GetMineCount(mine, x, y);
                show[x][y] = count + '0';
                DisplayBoard(show, ROW, COL);
                win++;
             }

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

}

写代码过程中遇到的问题:
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值