欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用C来实现扫雷小游戏

程序员文章站 2024-03-18 12:17:28
...

实现扫雷的基本流程

  • 生成棋盘
  • 初始化棋盘
  • 设置地雷数量
  • 显示最终展示的棋盘
  • 开始游戏
  • 输入坐标
  • 判断各种情况:1.输入坐标是否合法。2.是否输入了之前已经排过的雷区 等等
  • 避免第一次直接踩到雷的解决方法
  • 展开一片无雷区域
  • 判断扫雷是否输赢

头文件lei.h

这里面写了实现扫雷各种操作的方法。

#ifndef __LEI_H__
#define __LEI_H__
#include<stdio.h>
#include<stdlib.h>
#define ROW 12//底层面板12行12列,雷区为10*10,最外面的一圈是为了考虑雷区面板的边界情况
#define COL 12
#define MINES 10//设置了10个雷

void InitBoard(char show[ROW][COL], char mine[ROW][COL]);//初始化面板
void Display(char show[ROW][COL], char mine[ROW][COL]);//显示雷区面板或者游戏面板
void SetMine(char show[ROW][COL]);//设置地雷数量,随机设置
int MineNum(char mine[ROW][COL], int a, int b);//统计周围的地雷数目
void Start(char show[ROW][COL], char mine[ROW][COL]);//开始扫雷
void Firstblood(char show[ROW][COL], char mine[ROW][COL], int i, int j);//避免第一次被炸死
void Expand(char show[ROW][COL], char mine[ROW][COL],int x,int y);//展开一片连续无雷区,并在显示雷数
int Iswin(char show[ROW][COL]);//判断游戏输赢
void game(char show[ROW][COL], char mine[ROW][COL]);//游戏函数
#endif

lei.c文件

具体实现扫雷各个操作的步骤:

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include"lei.h"
//初始化
void InitBoard(char show[ROW][COL], char mine[ROW][COL])
{
    int i = 0;
    int j = 0;
    for (i = 0; i < ROW; i++)
    {
        for (j = 0; j < COL; j++)
        {
            mine[i][j] = '0';//将雷区面板的所有元素用字符0来表示,表示没有地雷
            show[i][j] = '*'; //将展示面板的所有元素用字符*来表示,表示还没有点击此区域
        }
    }
}
//打印雷区面板或者游戏面板
void Display(char show[ROW][COL])
{
    int i = 0;
    int j = 0;
    for (i = 1; i < ROW - 1; i++)
    {
        printf("----------------------------------------\n");
        for (j = 1; j < COL - 1; j++)
        {
            printf("%3c|", show[i][j]);
        }
        printf("\n");
    }
    printf("----------------------------------------\n");
}
//使用随机方法来设置地雷,地雷应该设置在里面白色区域
void SetMine(char mine[ROW][COL])
{
    srand((unsigned)time(NULL));
    int mines = MINES;
    while (mines > 0)
    {
        int i = rand() % (ROW - 2) + 1;//1-10
        int j = rand() % (COL - 2) + 1;//1-10
        if (mine[i][j] != '+')
        {
            mine[i][j] = '+';
            mines--;
        }
    }
}

使用C来实现扫雷小游戏

//计算一个坐标周围的地雷总数
int MineNum(char mine[ROW][COL], int a, int b)
{
    int sum = 0;
    if (mine[a - 1][b] == '+') { sum++; }
    if (mine[a - 1][b - 1] == '+') { sum++; }
    if (mine[a - 1][b + 1] == '+') { sum++; }
    if (mine[a][b - 1] == '+') { sum++; }
    if (mine[a][b + 1] == '+') { sum++; }
    if (mine[a + 1][b] == '+') { sum++; }
    if (mine[a + 1][b - 1] == '+') { sum++; }
    if (mine[a + 1][b + 1] == '+') { sum++; }
    return sum;
}
//避免第一次就踩到地雷
void Firstblood(char show[ROW][COL], char mine[ROW][COL],int i,int j)
{
    int a = 0;
    int b = 0;
    if (mine[i][j] == '+')//如果第一次踩到雷
    {
        do
        {
            //再随机生成一个坐标
            int a = rand() % (ROW - 2) + 1;
            int b = rand() % (COL - 2) + 1;
            if (mine[a][b] != '+')//如果新生成的坐标位置,原来没有地雷
            {
                mine[a][b] = '+';//那么就可以在此位置设一个地雷
                mine[i][j] = '0';//把之前的那个雷去掉,变成无雷
                break;//跳出循环即可
            }
        } while (1);
    }
}
//展开一片无雷区的方法
void Expand(char show[ROW][COL], char mine[ROW][COL],int x,int y)
{
    int leisum = 0;
    leisum = MineNum(mine, x, y);//先计算一个坐标周围的雷数
    show[x][y] = '0' + leisum;//游戏面板显示那个坐标的雷数
    if (show[x][y] == '0')//如果一个坐标周围没有地雷,进入判断
    {
    //在上面条件满足情况下,如果输入坐标的周围八个区域没有雷,并且坐标还没有被排过雷,就进行展开,并计算显示雷数
        if (x - 1 >= 1 && x - 1 <= 10 && y - 1 >= 1 && y - 1 <= 10 && show[x - 1][y - 1] == '*')
            Expand(show, mine, x - 1, y - 1);
        if (x - 1 >= 1 && x - 1 <= 10 && y >= 1 && y <= 10 && show[x - 1][y] == '*')
            Expand(show, mine, x - 1, y);
        if (x - 1 >= 1 && x - 1 <= 10 && y + 1 >= 1 && y + 1 <= 10 && show[x - 1][y + 1] == '*')
            Expand(show, mine, x - 1, y + 1);
        if (x >= 1 && x <= 10 && y - 1 >= 1 && y - 1 <= 10 && show[x][y - 1] == '*')
            Expand(show, mine, x, y - 1);
        if (x >= 1 && x <= 10 && y + 1 >= 1 && y + 1 <= 10 && show[x][y + 1] == '*')
            Expand(show, mine, x, y + 1);
        if (x + 1 >= 1 && x + 1 <= 10 && y - 1 >= 1 && y - 1 <= 10 && show[x + 1][y - 1] == '*')
            Expand(show, mine, x + 1, y - 1);
        if (x + 1 >= 1 && x + 1 <= 10 && y >= 1 && y <= 10 && show[x + 1][y] == '*')
            Expand(show, mine, x + 1, y);
        if (x + 1 >= 1 && x + 1 <= 10 && y + 1 >= 1 && y + 1 <= 10 && show[x + 1][y + 1] == '*')
            Expand(show, mine, x + 1, y + 1);
    }
}
//判断输赢
int Iswin(char show[ROW][COL])
{
    int i = 0;
    int j = 0;
    int sum = 0;
    //统计游戏棋盘中*的个数
    for (i = 1; i < ROW - 1; i++)
    {
        for (j = 1; j < COL - 1; j++)
        {
            if (show[i][j] == '*')
            {
                sum++;
            }
        }
    }
    if (sum == 10)//如果*剩下10个,说明剩下的都是地雷
    {
        return 1;
    }
    return 0;
}
//扫雷流程
void Start(char show[ROW][COL], char mine[ROW][COL])
{
    int a = 0;
    int b = 0;
    int i = 1;
    while (1)
    {
    //这个死循环是为了判断是否输入了排过雷的坐标
        for (;;)
        {
            printf("请输入坐标:");
            scanf("%d%d", &a, &b);
            if (show[a][b] != '*')
            {
                printf("您已经排查过这里的地雷!\n");
            }
            else
                break;
        }

        if (i == 1)//防止第一输入踩到雷
        {
            Firstblood(show, mine, a, b);
        }
        i++;

        int mines = MineNum(mine, a, b);//计算周围雷数

        if (mine[a][b] == '+')//如果猜到了地雷,游戏结束
        {
            printf("loose\n");
            break;
        }
        else if (mine[a][b] == '0')//如果不是雷,则显示周围雷的数量
        {
            show[a][b] = '0' + mines;
        }

        Expand(show, mine, a, b);//然后展开周围无雷区域
        Display(show);//到此,可以展示给玩家现在的游戏棋盘
        Iswin(show);//判断输赢
        if (Iswin(show) == 1)
        {
            printf("win\n");
            break;
        }
    }

}
//总游戏函数
void game(char show[ROW][COL], char mine[ROW][COL])
{
    InitBoard(show, mine);
    SetMine(mine);
    Display(mine);
    Display(show);
    Start(show, mine);
}

主函数文件 main.c

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include"lei.h"
#define ROW 12
#define COL 12

int menu()
{
    int sele = 0;
    printf("---------------------\n");
    printf("------1.开始游戏-----\n");
    printf("------0.退出游戏-----\n");
    printf("---------------------\n");
    printf("请输入菜单号码:>");
    scanf("%d", &sele);
    return sele;
}

int main()
{
    char mine[ROW][COL] = { '0' };
    char show[ROW][COL] = { '0' };
    int choose = 0;
    do
    {
        choose = menu();
        switch (choose)
        {
        case 1:
            game(show, mine);
            break;
        case0:
            break;
        default:
            break;
        }
    } while (choose);
}

使用C来实现扫雷小游戏
使用C来实现扫雷小游戏