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

C语言经典项目之二——扫雷

程序员文章站 2022-04-07 15:37:42
...

扫雷是一款家喻户晓的windows自带游戏,为了提高初学者学习兴趣,扫雷也是一个经典的C语言项目,今天就给大家分享一下。

我这个版本提供了可展开,第一次不会被炸死的功能。

/*================================================================

# File Name: game.h
# Author: rjm
# mail: aaa@qq.com
# Created Time: 2018年05月03日 星期四 18时14分07秒

================================================================*/

#pragma once

#include <stdio.h>
#include  <stdlib.h>
#include  <time.h>
#define M  10//定义炸弹数量
#define ROW 10//定义棋盘大小
#define COL 10
void init(char mine[ROW][COL], char show[ROW][COL], char spread[ROW][COL]);
void displayboard(char show[ROW][COL]);
void displaymine(char mine[ROW][COL]);
void Set_Mine(char mine[ROW][COL],  int m);
void sweep_Mine(char mine[ROW][COL], char show[ROW][COL],   int x, int y);
int check_win(char mine[ROW][COL], char show[ROW][COL], int m );
void prevent_first_death(char mine[ROW][COL], int x, int y);
int mineNum(char mine[ROW][COL], int x, int y);
void spread(char mine[ROW][COL], char show[ROW][COL], const int x, const int y);
//简易实现扫雷
#include "game.h"

//初始化棋盘
void init(char mine[ROW][COL], char show[ROW][COL], char spread[ROW][COL])//初始化棋盘
{
    int i = 0;
    int j = 0;
    for (i = 0; i < ROW-1 ; i++)//初始化9*9棋盘
    {
        for (j = 0; j < COL-1; j++)
        {
            mine[i][j] = ' ';
            show[i][j] = '*';
        }
    }
}
//打印棋盘
void displayboard(char show[ROW][COL])//打印9*9棋盘
{
    printf("\n==========棋盘==========\n\n");
    int i,  j;
    printf("  |");
    for (i = 1; i < ROW; i++)
    {
        printf("%d ", i);
    }
    printf("\n--|--------------------\n");
    for(i = 0; i < ROW-1; i++)
    {
        printf("%2d|", i + 1);
        for (j = 0; j < COL-1; j++)
        {
            printf("%c ",show[i][j]);
        }
        printf("\n");
    }
}
//展示雷盘
void displaymine(char mine[ROW][COL]) //展示雷盘 测试时使用
{
    printf("\n==========雷盘==========\n\n");
    int i, j;
    printf("  |");
    for (i = 1; i <= 10; i++)
    {
        printf("%d ", i);
    }
    printf("\n--|--------------------\n");
    for (i = 0; i < ROW - 1; i++)
    {
        printf("%2d|", i + 1);
        for (j = 0; j < COL - 1; j++)
        {
            printf("%c ", mine[i][j]);
        }
        printf("\n");
    }
}
//随机放置雷
void  Set_Mine(char mine[ROW][COL], int m) //随机放置雷,可以通过在头文件中修改 M 的值
        //从而修改 m 的大小改变布置的雷数
{
    int x, y;
    srand((unsigned)time(NULL));
    while(m)
    {
        x = rand() % 10 + 0;
        y = rand() % 10 + 0;
        if (mine[x][y] == ' ')
        {
            mine[x][y] = '$';
            m--;
        }
    }
    m = M;
}
int mineNum(char mine[ROW][COL], int x, int y)  //统计周边8个格子的雷数
{
    int count = 0;
    if (mine[x - 1][y - 1] == '$')
    {
        count++;
    }
    if (mine[x - 1][y] == '$')
    {
        count++;
    }
    if (mine[x - 1][y + 1] == '$')
    {
        count++;
    }
    if (mine[x][y + 1] == '$')
    {
        count++;
    }
    if (mine[x + 1][y + 1] == '$')
    {
        count++;
    }
    if (mine[x + 1][y] == '$')
    {
        count++;
    }
    if (mine[x + 1][y - 1] == '$')
    {
        count++;
    }
    if (mine[x][y - 1] == '$')
    {
        count++;
    }
    return count;
}
void spread(char mine[ROW][COL], char show[ROW][COL], const int x, const int y)   //展开函数
{
    int ret = 0;
    int i = 0;
    int j = 0;
    int a = x;
    int b = y;
    if (   (x >= 0)
                && (x <= 9)
                && (y >= 0)
                && (y <= 9))
    {
        if (mine[x - 1][y - 1] == ' ')                        //如果该区域不是雷
        {
            a = x - 1;
            b = y - 1;
            ret = mineNum(mine, a, b);                     //返回以该区域为中心雷的数量
            if (ret == 0)                                 //若在这八个区域中哪个区域的周围8个格子无雷
            {
                show[a][b] = ' ';                        //如果周围没有雷就向玩家展示‘ ’空格
                mine[a][b] = '0';                        //将雷盘中的区域改为‘0’可方便测试用
                spread(mine, show, a, b);              //则将这个区域的坐标赋值给x和y,再次进行展开
            }
            else
            {
                show[a][b] = '0' + ret;
                mine[a][b] = '0';
            }
        }
        if (mine[x][y - 1] == ' ')                                //以下的另外七个区域同理
        {
            a = x;
            b = y - 1;
            ret = mineNum(mine, a, b);
            if (ret == 0)
            {
                show[a][b] = ' ';
                mine[a][b] = '0';
                spread(mine, show, a, b);
            }
            else
            {
                show[a][b] = '0' + ret;
                mine[a][b] = '0';
            }
        }
        if (mine[x - 1][y] == ' ')
        {
            a = x - 1;
            b = y;
            ret = mineNum(mine, a, b);
            if (ret == 0)
            {
                show[a][b] = ' ';
                mine[a][b] = '0';
                spread(mine, show, a, b);
            }
            else
            {
                show[a][b] = '0' + ret;
                mine[a][b] = '0';
            }
        }
        if (mine[x + 1][y - 1] == ' ')
        {
            a = x + 1;
            b = y - 1;
            ret = mineNum(mine, a, b);
            if (ret == 0)
            {
                show[a][b] = ' ';
                mine[a][b] = '0';
                spread(mine, show, a, b);
            }
            else
            {
                show[a][b] = '0' + ret;
                mine[a][b] = '0';
            }
        }
        if (mine[x + 1][y] == ' ')
        {
            a = x + 1;
            b = y;
            ret = mineNum(mine, a, b);
            if (ret == 0)
            {
                show[x + 1][y] = ' ';
                mine[a][b] = '0';
                spread(mine, show, a, b);
            }
            else
            {
                show[x + 1][y] = '0' + ret;
                mine[a][b] = '0';
            }
        }
        if (mine[x + 1][y + 1] == ' ')
        {
            a = x + 1;
            b = y + 1;
            ret = mineNum(mine, a, b);
            if (ret == 0)
            {
                show[x + 1][y + 1] = ' ';
                mine[a][b] = '0';
                spread(mine, show, a, b);
            }
            else
            {
                show[x + 1][y + 1] = '0' + ret;
                mine[a][b] = '0';
            }
        }
        if (mine[x][y + 1] == ' ')
        {
            a = x;
            b = y + 1;
            ret = mineNum(mine, a, b);
            if (ret == 0)
            {
                show[x][y + 1] = ' ';
                mine[a][b] = '0';
                spread(mine, show, a, b);
            }
            else
            {
                show[x][y + 1] = '0' + ret;
                mine[a][b] = '0';
            }
        }
        if (mine[x - 1][y + 1] == ' ')
        {
            a = x - 1;
            b = y + 1;
            ret = mineNum(mine, a, b);
            if (ret == 0)
            {
                show[x - 1][y + 1] = ' ';
                mine[a][b] = '0';
                spread(mine, show, a, b);
            }
            else
            {
                show[x - 1][y + 1] = '0' + ret;
                mine[a][b] = '0';
            }
        }
    }
}
void sweep_Mine(char mine[ROW][COL], char show[ROW][COL],   int x, int y)   //扫雷函数
{
    int ret = 0;
    if ( mine[x][y] == ' ' )      //玩家没有踩到雷,即展示该区域周边的雷数,如果雷数为0就显示空格
    {
        ret = mineNum(mine, x, y);
        if (ret == 0)
        {
            show[x][y] = ' ';
        }
        else
        {
            show[x][y] = '0' + ret;                           //如果有炸弹就显示炸弹的数量
        }
        spread(mine, show, x, y);                      //并在此调用展开函数,对周边区域进行展开
    }
    else if(mine[x][y] == '$')
    {
        show[x][y] = mine[x][y];                             //如果玩家踩到炸弹就显示$
    }
}
void prevent_first_death(char mine[ROW][COL], int x, int y)    //防止玩家第一次被炸死
{
    int m = 0;
    int n = 0;
    if(mine[x][y] == '$')
    {
        do
        {
            m = rand() % 11 + 0;
            n = rand() % 11 + 0;                  //如果玩家踩到雷,就重新随机一个没有雷的地方,将炸弹移动到那里
            if (mine[m][n] == ' ')
            {
                mine[x][y] = ' ';             //将该区域设置为空格
                mine[m][n] = '$';
                break;
            }
        }
        while (1);
    }
}

//判断输赢
int check_win(char mine[ROW][COL], char show[ROW][COL], int m)
{
    int i, j, num = 0;
    for (i = 0; i < ROW; i++)
    {
        for (j = 0; j < COL; j++)
        {
            if (show[i][j] == '*')  //如果在展示棋盘上剩余 * 的数量等于雷的数量,就说明扫雷成功
            {
                num++;
            }
            else if (show[i][j] == '$')         //如果显示盘上出现了 $ 说明踩到了雷
            {
                return 1;
            }
        }
    }
    if(M == num)
      return 0;

    return -1;
}

/*================================================================

# File Name: test.c
# Author: rjm
# mail: aaa@qq.com
# Created Time: 2018年05月03日 星期四 18时15分26秒

================================================================*/



#include "game.h"

//游戏菜单
void menu()
{
    printf("=======================================\n");
    printf("---------------扫雷游戏----------------\n");
    printf("=====1,开始================2,退出======\n");
    printf("=======================================\n");
}

void game()
{
    char mine[ROW][COL];
    char show[ROW][COL];
    char spread[ROW][COL];
    int x, y, m;
    int row, col;
    int count=0;
    int ret;
    row = ROW;
    col = COL;
    m = M;
    init(mine, show, spread);
    displayboard(show);
    Set_Mine(mine, m);
    displaymine(mine);
    do
    {
        displayboard(show);
        count++;
        printf("==========开始扫雷>:");
        scanf("%d %d", &x, &y);
        getchar();
        x = x - 1;
        y = y - 1;
        if (count == 1)
        {
            prevent_first_death(mine, x, y);
        }
        sweep_Mine(mine, show, x, y);
        ret = check_win(mine, show, m);
        if(ret == 1)
        {
            displayboard(show);
            printf("\n=========踩到炸弹! gg========\n\n");
            break;
        }
        else if(ret == 0)
        {
            displayboard(show);
            printf("\n==========扫雷成功!==========\n\n");
            break;
        }
    }
    while (1);
}

int main()
{
    int n = 0;
    do
    {
        menu();
        printf("=====请选择=>");
        scanf("%d", &n);
        printf("==================================\n");
        getchar();
        if(n == 1)
        {
            game();
        }
        else if(n == 2)
        {
            printf("\nbye!\n");
            break;
        }
        else
        {
            printf("输入有误 重新输入\n");
        }
    }
    while (1);
    printf("\n\n\n");
    printf("\n\n\n");
    printf("\n\n\n");
    return 0;
}

效果展示
C语言经典项目之二——扫雷
C语言经典项目之二——扫雷
C语言经典项目之二——扫雷

相关标签: c语言 扫雷