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

C实现扫雷

程序员文章站 2024-03-19 16:33:34
...

实现思路

  • 定义两个字符型数组
    -mine[11][11] 用来存放电脑随机布的雷,show[9][9]用来向玩家展示游戏的界面,玩家在看不到雷的数组输入坐标,然后在布雷的数组里判断输赢,在玩家看到的游戏数组里显示该坐标周围的雷数,展开一片。
  • 布置雷
    • 设置雷数,用rand()随机产生合法的坐标,坐标从1到9,rand()%9+1,使用rand时不能忘了加 srand((unsigned int)time(NULL))。
      雷用字符1表示,其余地方存为字符0.
  • 保证第一步 不会被炸死
    • 为了让这个游戏的可玩性增加,写一个safe函数,如果玩家第一步遇到雷,把这个位置改为不是雷,在其他非雷的地方再放一颗雷。
  • 排查雷
    • 玩家输入坐标,如果这个坐标不是雷,但是周围有雷,写一个GetMineCount函数,计算这个坐标周围8个坐标的总雷数,把这个数字返回到show数组里,显示给玩家。如果这个坐标不是雷,周围也没有雷,写一个Open函数,展开这个坐标及其周围,显示为空格,用函数的递归炸开一片,直到遇到一个坐标周围有雷,则不递归了,还是显示周围的雷数。
  • 判断输赢
    • 写一个IsWin函数,计算show数组里还未展开的格数,如果等于布置的雷数,则输出玩家赢,游戏结束。


一、打印游戏界面

void menu()
{
    printf("********************************\n");
    printf("*****  1.play      0.exit ******\n");
    printf("********************************\n");

}
void test()
{
    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);

}

C实现扫雷


二、定义两个二维数组,并打印

//头文件game.h
#define  EASY_COUNT 10          
#define  ROW 9
#define  COL 9

#define  ROWS ROW+2
#define  COLS COL+2
//源文件game.c
void InitBoard(char board[ROWS][COLS],int rows,int cols,char set)
{
    memset(board, set, rows*cols*sizeof(board[0][0]));
}
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
    int i = 0;
    int 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");

}
//源文件test.c中的game函数
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
InitBoard(mine, ROWS, COLS,'0');
InitBoard(show, ROWS, COLS,'*');

三、埋雷

void SetMine(char board[ROWS][COLS], int row, int col)
{
    int x = 0;
    int y = 0;
    int count = EASY_COUNT;
    while (count)
    {
        x = rand() % 9 + 1;
        y = rand() % 9 + 1;
      if (board[x][y] == '0')
        {
            board[x][y] = '1';
            count--;

}

   }  
} 

C实现扫雷


四、输入坐标排雷

//第一步安全
void Safe(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
    int x = 0;
    int y = 0;
    int count = 0;
    int a = 0;
    int b = 0;
    printf("请输入要排查的坐标:");
    scanf("%d%d", &x, &y);
    a = x;
    b = y;
    if (mine[x][y] == '1')
    {
        mine[x][y] = '0';
        while(1)
        {
            x = rand() % 9 + 1;
            y = rand() % 9 + 1;
            if (mine[x][y] == '0')
            {
                mine[x][y] = '1';
            }
            break;
        }

    }
    Open(mine, show, a, b);
    //DisplayBoard(mine, row, col);
    DisplayBoard(show, row, col);
}
//计算输入坐标周围的雷数
int GetMineCount(char mine[ROWS][COLS], int x, int y)
{
        return 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';  //返回坐标周围的雷数
}
//把坐标周围8个格子没有雷的地方展开,周围有雷的输出数字
void Open(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
    int ret = 0;
    ret = GetMineCount(mine, x, y);
    if (ret == 0)
    {
        show[x][y] = ' ';  //不是雷改为空格
        if (x - 1 > 0 && y > 0 && show[x - 1][y] == '*')
            Open(mine, show,x-1, y);

        if (x - 1 > 0 && y+1 <= COL && show[x - 1][y+1] == '*')
            Open(mine, show, x-1, y+1);

        if (x > 0 && y+1 <=COL && show[x][y+1] == '*')
            Open(mine, show, x, y+1);

        if (x + 1 <ROW && y+1 <=COL && show[x + 1][y+1] == '*')
            Open(mine, show, x+1, y+1);

        if (x + 1 <=ROW  && y > 0 && show[x + 1][y] == '*')
            Open(mine, show, x+1, y);

        if (x + 1<=ROW && y-1 > 0 && show[x + 1][y-1] == '*')
            Open(mine, show, x+1, y-1);

        if (x > 0 && y-1 > 0 && show[x][y-1] == '*')
            Open(mine, show, x, y-1);

        if (x - 1 > 0 && y-1 > 0 && show[x - 1][y-1] == '*')
            Open(mine, show, x-1, y-1);

    }  
       else
        {
            show[x][y] = GetMineCount(mine, x , y ) + '0';
             //x,y周围有雷,显示雷的个数
        }

}
//计算数组里*的个数,判断输赢
int IsWin(char show[ROWS][COLS], int row, int col)
{
    int i = 0;
    int j = 0;
    int c = 0;
    for (i = 1; i <= row; i++)
    {
        for (j = 1; j <= col; j++)
        {
            if (show[i][j] == '*')
            {
                c++;
            }
        }
    }
    return c;
}
//输入坐标排雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
    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");
                DisplayBoard(mine, row, col);
                break; 
            }
          else
            {
                int count = 0;
                count = GetMineCount(mine,x,y);
                show[x][y] = count + '0';
                Open(mine, show, x, y);
                DisplayBoard(show, row, col);
                if (IsWin(show, row, col) == EASY_COUNT)  //*数等于雷数
                {
                    printf("恭喜你,排雷成功!\n");
                    DisplayBoard(mine, row, col);
                    break;
                 }  
            }
        }
        else
        {
           printf("坐标非法\n");
        }
    }

}     


以上是扫雷的全部过程,下面附上完整代码
C实现扫雷

//game.h
#ifndef _GAME_H__
#define _GAME_H__


#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>

#define  EASY_COUNT 10
#define  ROW 9
#define  COL 9

#define  ROWS ROW+2
#define  COLS COL+2

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 col);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);


#endif //_GAME_H__#define _CRT_SECURE_NO_WARNINGS 1

//game.c
#include "game.h"

void InitBoard(char board[ROWS][COLS],int rows,int cols,char set)
{
    memset(board, set, rows*cols*sizeof(board[0][0]));
}
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
    int i = 0;
    int 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 SetMine(char board[ROWS][COLS], int row, int col)
{
    int x = 0;
    int y = 0;
    int count = EASY_COUNT;
    while (count)
    {
        x = rand() % 9 + 1;
        y = rand() % 9 + 1;
        if (board[x][y] == '0')
        {
            board[x][y] = '1';
            count--;

        }
    }


}

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

void Open(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
    int ret = 0;
    ret = GetMineCount(mine, x, y);
    if (ret == 0)
    {
        show[x][y] = ' ';
        if (x - 1 > 0 && y > 0 && show[x - 1][y] == '*')
            Open(mine, show,x-1, y);

        if (x - 1 > 0 && y+1 <= COL && show[x - 1][y+1] == '*')
            Open(mine, show, x-1, y+1);

        if (x > 0 && y+1 <=COL && show[x][y+1] == '*')
            Open(mine, show, x, y+1);

        if (x + 1 <ROW && y+1 <=COL && show[x + 1][y+1] == '*')
            Open(mine, show, x+1, y+1);

        if (x + 1 <=ROW  && y > 0 && show[x + 1][y] == '*')
            Open(mine, show, x+1, y);

        if (x + 1<=ROW && y-1 > 0 && show[x + 1][y-1] == '*')
            Open(mine, show, x+1, y-1);

        if (x > 0 && y-1 > 0 && show[x][y-1] == '*')
            Open(mine, show, x, y-1);

        if (x - 1 > 0 && y-1 > 0 && show[x - 1][y-1] == '*')
            Open(mine, show, x-1, y-1);

    }
            else
        {
            show[x][y] = GetMineCount(mine, x , y ) + '0';

        }

}

int IsWin(char show[ROWS][COLS], int row, int col)
{
    int i = 0;
    int j = 0;
    int c = 0;
    for (i = 1; i <= row; i++)
    {
        for (j = 1; j <= col; j++)
        {
            if (show[i][j] == '*')
            {
                c++;
            }
        }
    }
    return c;
}

void Safe(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
    int x = 0;
    int y = 0;
    int count = 0;

    int a = 0;
    int b = 0;
    printf("请输入要排查的坐标:");
    scanf("%d%d", &x, &y);
    a = x;
    b = y;
    if (mine[x][y] == '1')
    {
        mine[x][y] = '0';
        while(1)
        {
            x = rand() % 9 + 1;
            y = rand() % 9 + 1;
            if (mine[x][y] == '0')
            {
                mine[x][y] = '1';
            }
            break;
        }

    }
    Open(mine, show, a, b);
    DisplayBoard(mine, row, col);
    DisplayBoard(show, row, col);
}

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
    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");
                DisplayBoard(mine, row, col);
                break; 
            }
          else
            {
                int count = 0;
                count = GetMineCount(mine,x,y);
                show[x][y] = count + '0';
                Open(mine, show, x, y);
                DisplayBoard(show, row, col);
                if (IsWin(show, r 
  ow, col) == EASY_COUNT)
                {
                    printf("恭喜你,排雷成功!\n");
                    DisplayBoard(mine, row, col);
                    break;
                 }  
            }
        }
        else
        {
            printf("坐标非法\n");
        }
    }

}
//test.c
#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void menu()
{
    printf("********************************\n");
    printf("*****  1.play      0.exit ******\n");
    printf("********************************\n");

}
void game()
{
    char mine[ROWS][COLS] = { 0 };
    char show[ROWS][COLS] = { 0 };
    InitBoard(mine, ROWS, COLS,'0');
    InitBoard(show, ROWS, COLS,'*');
    SetMine(mine, ROW, COL);
    DisplayBoard(mine, ROW, COL);
    DisplayBoard(show, ROW, COL);
    Safe(mine, show, ROW, COL); 
    FindMine(mine, show, ROW, COL);

}
void test()
{
    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);

}
int main()
{
    test();
    system("pause");
    return 0;
}

C实现扫雷
C实现扫雷
C实现扫雷
C实现扫雷
C实现扫雷
C实现扫雷
C实现扫雷