简易版扫雷

1.设计过程

1.定义一个主函数,以及一个game()函数,在其中进行游戏过程
2.首先定义两个字符型的二维数组,一个用来放雷,一个用来显示
3.定义一个初始化数组的函数,将显示棋盘全设置为‘*’
4.定义一个设置雷的函数,随机生成20个雷
5.定义一个确定每个坐标周围雷的个数的函数
6.定义一个排雷的函数
7.定义一个显示棋盘的函数
8.定义一个判断输赢的函数

2.代码实现

头文件代码

#ifndef __SAOLEI_H__
#define __SAOLEI_H__
#define ROW 10
#define CLU 10
//1.初始化棋盘
void initBoard(char board[ROW+2][CLU+2], int row, int clu);
//2.显示棋盘 
void display(char board[ROW+2][CLU+2], int row, int clu);
//3.设置雷
void set(char mine[ROW+2][ROW+2],int row, int clu);
//4.确定附近雷数
void mineNum(char mine[ROW + 2][ROW + 2], int row, int clu);
//5.排雷
int reMine(char board[ROW + 2][CLU + 2], char mine[ROW + 2][CLU + 2],
 int row, int clu, int num);
//6.遇到‘0’展开
void spread(char board[ROW + 2][CLU + 2], char mine[ROW + 2][CLU + 2],
 int row, int clu, int x, int y);
//6.判断输赢
int isWin(char board[ROW + 2][CLU + 2],  int row, int clu);
#endif

源文件代码
1.主函数接受菜单函数的choose返回值判断是否进行游戏

//主函数
int main()
{
    int choose = 0;
    do
    { 
    choose =  meau();
    switch(choose)
    {
        case 1:
            game();
            break;
        case 0:
            printf("退出游戏\n");
            break;
        default:
            printf("输入错误,请重新输入\n:");
            break;
    }
    }while(choose);
    return 0;
}

2.菜单函数打印菜单界面,并调用scanf函数,获取输入值

//游戏菜单
int meau()
{
    int choose = 0;
    printf("*********************\n");
    printf("*******1.play********\n");
    printf("*******0.exit********\n");
    printf("*********************\n");
    printf("请选择->");
    int num = scanf("%d", &choose);
    if (num != 1)//防止输入非整形数据
    {
        while (getchar() != '\n')
        {
            ;
        }
        choose = -1;
    }
    return choose;
}

3.初始化数组的函数,将显示棋盘全设置为‘*’

//初始化棋盘
void initBoard(char board[ROW+2][CLU+2], int row, int clu)
{
   int i = 0;
   for(i=1; i<row-1; i++)
   {
       int j = 0;
       {
           for(j=0; j<clu-1; j++)
           {
             board[i][j]   = '*';//未排雷时全部表示成‘*’
           }
       }
   }
}

4.设置雷的函数,随机生成20个雷

//设置雷
void set(char mine[ROW+2][ROW+2],int row, int clu)
{
  int count = 0;
  srand((unsigned int)time(NULL));
 do
 {
  int i = rand()%(row-2)+1;
  int j = rand()%(clu-2)+1;
  if(mine[i][j] != '*')
  {
      mine[i][j] = '*';
      count++;
  }
 }while(count<20);
 mineNum(mine, ROW + 2, CLU + 2);
}

5.确定每个坐标周围雷的个数的函数

void mineNum(char mine[ROW + 2][ROW + 2], int row, int clu)
{
    int i = 0;
    for (i = 1; i<row - 1; i++)
    {
        int j = 0;
        {
            for (j = 1; j<clu - 1; j++)
            {
                if (mine[i][j] != '*')
                {
                    int num = 0;
                    //如果周围有雷就让num++
                    if (mine[i - 1][j - 1] == '*')
                        num++;
                    if (mine[i - 1][j] == '*')
                        num++;
                    if (mine[i - 1][j + 1] == '*')
                        num++;
                    if (mine[i][j - 1] == '*')
                        num++;
                    if (mine[i][j + 1] == '*')
                        num++;
                    if (mine[i + 1][j - 1] == '*')
                        num++;
                    if (mine[i + 1][j] == '*')
                        num++;
                    if (mine[i + 1][j + 1] == '*')
                        num++;
                    mine[i][j] = num + '0';
                }
            }
        }
    }
}

6.排雷的函数

int reMine(char board[ROW + 2][CLU + 2], char mine[ROW + 2][CLU + 2],
 int row, int clu, int num)
{
    int x = 0;
    int y = 0;
  printf("请输入坐标(x,y)->");
  if (scanf("%d%d", &x, &y) != 2)//防止输入非整形数据
  {
      while (getchar() != '\n')//刷新缓存区
      {
          ;
      }
      x = -1;
      y = -1;
  }

  //输入正确
  if((x>=1 && x<=10)&&(y>=1 &&y<=10)&&board[x][y] == '*')
  {
      if ((num == 1) && (mine[x][y] == '*'))//第一次踩中雷,移走雷
      {
          mine[x][y] = '0';//将该雷替换为‘0’
          board[x][y] = mine[x][y];
          spread(board, mine, ROW + 2, CLU + 2, x, y);
          do//重新生成一个雷
          {
              int i = rand() % (row - 2) + 1;
              int j = rand() % (clu - 2) + 1;
              if (mine[i][j] == '0')
              {
                  mine[i][j] = '*';
                  break;
              }
          } while (1);
      }
      //踩中雷
      else if(mine[x][y] == '*')
      { 
        return -1;
      }
      //没踩中雷
      else
      {
        board[x][y] = mine[x][y];
        //如果点到‘0’,进行展开
        if (board[x][y] == '0')
        {
            spread(board, mine, ROW + 2, CLU + 2, x, y);
        }
      }
  }
  //输入有误
  else
  {
      printf("输入错误\n");
  }
  return 0;
}

6.显示棋盘的函数

//显示棋盘
void display(char board[ROW+2][CLU+2], int row, int clu)
{
   int i = 0;
   printf("    1 2 3 4 5 6 7 8 9 10\n");
   printf("    ____________________\n");
   for(i=1; i<row-1; i++)
   {
       printf("%2d|",i);
       int j = 0;
       {
           for(j=1; j<clu-1; j++)
           {
               printf("%2c",board[i][j]);
           }
           printf("\n");
       }
   }
}

7.判断输赢的函数

//判断输赢
int isWin(char board[ROW + 2][CLU + 2],  int row, int clu)
{
    int count = 80;
    int i = 0;
    for (i = 1; i<row - 1; i++)
    {
        int j = 0;
        {
            for (j = 1; j<clu - 1; j++)
            {
                if (board[i][j] != '*')
                    count--;
            }
        }
    }
    return count;
}

8.game()函数

//游戏过程
void game()
{
    int count = 0;
    int num = 1;//作为参数传给排雷的函数,用来判断是否第一次排雷
    int n = 0;
    char board[ROW + 2][ROW + 2] = { 0 };//创建一个用来显示的数组
    char mine[ROW + 2][CLU + 2] = { 0 };//创建一个用来放雷的数组
    initBoard(board, ROW + 2, CLU + 2);
    set(mine, ROW + 2, CLU + 2);

    do
    {
        n = reMine(board, mine, ROW + 2, CLU + 2,num);
        num--;
        if (n == -1)//如果返回值为-1,判断为输
        {
            printf("you lost!\n");
            display(mine, ROW + 2, CLU + 2);
            break;
        }
        display(board, ROW + 2, CLU + 2);
        count = isWin(board, ROW + 2, CLU + 2);
    } while (count);

    if (count == 0)
    {
        printf("you win!\n");
    }
}

运行
1.游戏菜单
这里写图片描述
2.选择1.play
这里写图片描述
3.输入坐标(1,1)
这里写图片描述
4.输入错误坐标
这里写图片描述
5.输掉游戏
这里写图片描述
6.赢得游戏
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值