当前位置: 首页 > 工具软件 > 扫雷放置 > 使用案例 >

扫雷

翁宏茂
2023-12-01

扫雷

扫雷相信大家都玩过,今天我将使用C语言实现简单地扫雷。

为方便调用,创建mine.h

#include <stdio.h>

/**
 * @author: 张翊
 * @TIME: 2021/5/4 8:38
 * @Description:
 */
#ifndef UNTITLED_MINE_H
#define UNTITLED_MINE_H

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1

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

#define row 9 //棋盘行数
#define col 9 //棋盘列数

#define rows row+2 //为方便计数,将棋盘行列各加2
#define cols col+2
#define COUNT 10 //地雷总数

int menu();//菜单函数

void game();//游戏逻辑函数啊

void InitBoard(char board[rows][cols], int ROW, int COL, char set);//初始化函数

void FindMine(char mine[rows][cols], char show[rows][cols], int ROW, int COL);//扫雷函数

void DisplayBoard(char board[rows][cols], int ROW, int COL);//展示棋盘函数

void SetMine(char board[rows][cols]);//布置地雷函数

int GetCount(char mine[rows][cols], int x, int y);//统计地雷个数函数

int Win(char show[rows][cols]);//判断是够获胜函数

#endif

1.主函数

/**
 * @author: 张翊
 * @TIME: 2021/5/4 8:38
 * @Description:
 */
int main()
{
    while (1)
    {
        int choice = menu();
        switch (choice)
        {
            case 1:
                game();//游戏实现
                break;
            case 2:
                printf("谢谢您的使用,再见!");
                return 0;
            default:
                system("cls");
                printf("您的选择有误,请重新输入:\n");
        }
    }
}

2.菜单函数

int menu()
{
    int input;
    printf("**************************\n");
    printf("**********1.play *********\n");
    printf("**********2.exit *********\n");
    printf("**************************\n");
    printf("请选择:>");
    scanf("%d", &input);
    return input;
}

3. 游戏逻辑函数

第一步,创建两个数组,一个是雷盘数组,一个是向用户展示的数组,两个数组大小相同。

第二步,初始化这两个数组。

第三步,布置地雷

第四步,扫雷

void game()
{
    char mine[rows][cols] = {0};
    char show[rows][cols] = {0};
    InitBoard(mine, rows, cols, '0');
    InitBoard(show, rows, cols, '*');
    SetMine(mine);
    DisplayBoard(show, row, col);
    FindMine(mine, show, row, col);
}

4.初始化棋盘

通过传入不同的set,将两个数组初始化成不同的形式。

/**
 * 初始化函数
 * @param board  棋盘数组
 * @param ROW 行数
 * @param COL 列数
 * @param set 初始符号
 */
void InitBoard(char board[rows][cols], int ROW, int COL, char set)
{
    for (int i = 0; i < ROW; ++i)
    {
        for (int j = 0; j < COL; ++j)
        {
            board[i][j] = set;
        }
    }
}

5.展示棋盘

为方便输入坐标,再打印棋盘时同时打印行列坐标,并且只打印数组1-9索引的元素

/**
 *  打印雷盘
 * @param board
 * @param ROW
 * @param COL
 */
void DisplayBoard(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 <= COL; i++)
    {
        printf("%d ", i);

        for (int j = 1; j <= COL; j++)
        {
            printf("%c ", board[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

6.布置地雷

/**
 * 布置雷盘
 * @param board 
 */
void SetMine(char board[rows][cols])
{
    srand((unsigned int) time(NULL));//使用系统时间作为随机值的种子
    int count = COUNT;//雷的个数
    while (count)//控制雷个数
    {
        int x = rand() % row + 1;//x会在1-9之间随机生成一个值
        int y = rand() % col + 1;//y会在1-9之间随机生成一个值

        if (board[x][y] == '0')//避免重复放雷
        {
            board[x][y] = '1';//雷的放置用字符'1'表示
            count--;//放置一个。地雷个数减1,直至0退出
        }
    }
}

7.扫雷

/**
 * 扫雷
 * @param mine
 * @param show
 * @param ROW
 * @param COL
 */
void FindMine(char mine[rows][cols], char show[rows][cols], int ROW, int COL)
{
    //row和col传递过来的是ROW和COL,这里用x,y来控制数组下标。
    int x = 0;
    int y = 0;
    while (1)
    {
        printf("请输入排雷的坐标:>>>");
        scanf("%d %d", &x, &y);
        //如果输入坐标合法
        if (x >= 1 && x <= row && y >= 1 && y <= col)
        {
            //玩家输入的坐标埋放了雷,那么对不起,打印雷分布情况,游戏结束
            if (mine[x][y] == '1')
            {
                printf("\n很不幸,您被炸死了!!!\n雷的分布情况如下:\n");
                DisplayBoard(mine, row, col);
                printf("-----------游戏结束----------\n\n");
                break;
            }
               //如果玩家周围有雷,直接显示周围雷的个数。
            else if (mine[x][y] == '0')
            {
                show[x][y] = GetCount(mine, x, y) + '0';
                DisplayBoard(show, row, col);
                if (Win(show) == 1)//判断此时雷盘剩余的*数目,如果等于雷数,则玩家排雷成功。
                {
                    DisplayBoard(mine, row, col);
                    break;
                }
            }
        }
        else//如果输入坐标非法,提示
        {
            printf("您的坐标输入有误,请重新输入\n");
        }
    }
}

8. 计算选择的坐标周围的地雷个数

由于地雷二维数组中存放的数据为char型(’0’为无雷,‘1’为有雷),为方便统计个数,将周围==8个格子的值相加减去‘0’==即可(ASCII码计算)。

/**
 * 计算周围八个格子中雷的个数
 * @param mine
 * @param x
 * @param y
 * @return
 */
int GetCount(char mine[rows][cols], int x, int y)
{
    int count = mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] +
                mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0';
    return count;
}

9.判断是否获胜

int Win(char show[rows][cols])
{
    int count = 0;
    for (int i = 1; i <= row; i++)
    {
        for (int j = 1; j <= col; j++)
        {
            if (show[i][j] == '*')
            {
                count++;
            }
        }
    }
    if (count == COUNT)//判断此时雷盘剩余的*数目,如果等于雷数,则玩家排雷成功。
    {
        printf("恭喜你成功排雷,太棒了,太棒了,送你一朵小红花!!!\n");
        printf("雷的分布情况如下:\n");
        return 1;
    }
    return 0;
}
 类似资料: