用C语言实现扫雷部分功能(可连续展开)

用了用了两天时间,写了个扫雷的小程序,是不是有点慢了。不过我是真觉得用c写小东西很有意思。
PS:重新游戏那里还没开始写,后面会补上。

**

感觉最困难,花费时间最多的在棋盘中无雷周边区域显示的算法上。

**

具体程序见下:

头文件

#ifndef   __SAOLEI_H
#define   __SAOLEI_H

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

#define X 9//棋盘大小
#define Y 9
#define LAND 10//地雷个数

int a[X][Y]={0} ;
char b[X][Y] ;
void menu_game(void);//打印菜单栏
int mode_game(void);//功能
void generate_initgame(void);//生成初始棋盘
void generate_game(void);//生成棋盘
int start_game(void);
int judge_game(int x,int y);
void explore_game(void);
void updata_game(void);//更新棋盘
void euqal_game(int x,int y);
void extend_game(int x,int y);
int judge_game(int x,int y);
void disappear_game(int x,int y);
void printnew_game(void);
void show_game(int x,int y);
int check_game(int x,int y);

#endif // __SAOLEI_H

主程序

#include "saolei.h"

void bye_game(void);
void replay_game(void);
int main()
{
    int mode,status;//记录用户选择什么功能
    memset(b, '*', X*Y*sizeof(char));
    START:
    menu_game();//打印菜单栏
    mode = mode_game();//选择功能
    generate_initgame();//生成棋盘(看不见地雷)
    generate_game();//生成原始地雷
    while(1)
    {
       switch(mode)
       {
          case 1:status = start_game();if(status == 0){goto END;}break;
          case 2:replay_game();goto END;break;
          case 0:bye_game();goto END;break;
       }
    }
  END:
    return 0;
}
void replay_game(void)
{
    printf("重新开始游戏!\n");
}
void bye_game(void)
{
    printf("成功退出游戏!\n");
}
int over_game()
{
    printf("踩到地雷了!Game Over!\n");
    return 0;
}
int judge_game(int x,int y)
{
  int aa = a[x][y],status;
  if(aa == 9) {status = over_game();return status;}
  if((x>=0)&(x<=8)&(y>=0)&(y<=8)){
     switch(aa)
     {
        case 0:disappear_game(x,y);show_game(x,y);extend_game(x,y);break;//检测八个方向
        case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:euqal_game(x,y);break;//检测八个方向
        default: printf("\n未知错误!!\n");return 0;
     }
     status = 1;
  }
  return status;
}
void extend_game(int x,int y)
{
    int i ,j;
    i = x;j = y;
    if(((i-1)>=0)&((j-1)>=0)){if(b[i-1][j-1]==0) judge_game(i-1,j-1);else euqal_game(i-1,j-1);}
    if((i-1)>=0)             {if(b[i-1][j]==0) judge_game(i-1,j);    else euqal_game(i-1,j);}
    if(((i-1)>=0)&((j+1)<=8)){if(b[i-1][j+1]==0) judge_game(i-1,j+1);else euqal_game(i-1,j+1);}
    if((j-1)>=0)             {if(b[i][j-1]==0) judge_game(i,j-1);    else euqal_game(i,j-1);}
    if((j+1)<=8)             {if(b[i][j+1]==0) judge_game(i,j+1);    else euqal_game(i,j+1);}
    if(((i+1)<=8)&((j-1)>=0)){if(b[i+1][j-1]==0) judge_game(i+1,j-1);else euqal_game(i+1,j-1);}
    if((i+1)<=8)             {if(b[i+1][j]==0) judge_game(i+1,j);    else euqal_game(i+1,j);}
    if(((i+1)<=8)&((j+1)<=8)){if(b[i+1][j+1]==0) judge_game(i+1,j+1);else euqal_game(i+1,j+1);}
}
void euqal_game(int x,int y)
{
    if(b[x][y] != '$')
    b[x][y] = a[x][y];
}
void disappear_game(int x,int y)//当检测到0,把这个值赋值'$'
{
    b[x][y] = '$';
}
//若所选位置周围八个方向没有雷(0),把周边值给b;
void show_game(int x,int y)
{
    int i ,j;
    i = x;j = y;
    if(((i-1)>=0)&((j-1)>=0)& (b[i-1][j-1]=='*')) b[i-1][j-1] = a[i-1][j-1];
    if(((i-1)>=0)&(b[i-1][j]=='*'))               b[i-1][j] = a[i-1][j];
    if(((i-1)>=0)&((j+1)<=8)&(b[i-1][j+1]=='*'))  b[i-1][j+1] = a[i-1][j+1];
    if(((j-1)>=0)&(b[i][j-1]=='*'))               b[i][j-1] = a[i][j-1];
    if(((j+1)<=8)&(b[i][j+1]=='*'))               b[i][j+1] = a[i][j+1];
    if(((i+1)<=8)&((j-1)>=0)& (b[i+1][j-1]=='*')) b[i+1][j-1] = a[i+1][j-1];
    if(((i+1)<=8)&(b[i+1][j]=='*'))               b[i+1][j] = a[i+1][j];
    if(((i+1)<=8)&((j+1)<=8)& (b[i+1][j+1]=='*')) b[i+1][j+1] = a[i+1][j+1];
}
int start_game()
{
    int x,y,status,isc;
    printf("请输入坐标:");
    scanf("%d %d",&x,&y);
    fflush(stdin);
    x=x-1;y=y-1;
    //b[x][y] = a[x][y];
    isc = check_game(x,y);
    if(isc == 1) {
        status = judge_game(x, y);
        if(status == 1)
        printnew_game();
        else
        updata_game();
        }//该点并没有被探索过!,然后打印棋盘
    else start_game();
    return status;
}
void printnew_game()
{
    char c[X][Y] = {NULL};
    printf("   1 2 3 4 5 6 7 8 9\n");
    for (int i=0; i<=X-1; i++)
    {
       printf("%2d", i+1);
       for(int j=0; j<=Y-1; j++)
       {
          if (b[i][j] == '*') printf("%2c", b[i][j]);
          else if (b[i][j] == '$') printf("%2c", c[i][j]);//'$'表示该点处周边无雷,也就是0,这时候棋盘上显示空
          else printf("%2d", b[i][j]);
          if(j == Y-1) printf("\n");
       }
    }
}
int check_game(int x,int y)
{
   int isc = 1;
   if(b[x][y] != '*')
        {printf("该点已经被探索过!请重新输入!\n");isc = 0;}
   return isc;
}
//生成棋盘
void generate_initgame(void)
{
    printf("   1 2 3 4 5 6 7 8 9\n");
    printf(" 1 * * * * * * * * *\n");
    printf(" 2 * * * * * * * * *\n");
    printf(" 3 * * * * * * * * *\n");
    printf(" 4 * * * * * * * * *\n");
    printf(" 5 * * * * * * * * *\n");
    printf(" 6 * * * * * * * * *\n");
    printf(" 7 * * * * * * * * *\n");
    printf(" 8 * * * * * * * * *\n");
    printf(" 9 * * * * * * * * *\n");
}
//  生成原始地雷
void generate_game(void)
{
    int i,j,xc,yc,n;
    srand((unsigned) (time(NULL)));//调用time函数来获取随机数
    while (!(n == 10))//防止生成雷数少于10个
    {
       xc = rand()%9;
       yc = rand()%9;
       a[xc][yc] = 9;
  //     printf("%d  ",a[xc][yc]);
       n = 0;
       for(i=0; i<X; i++)
      {
         for(j=0; j<Y; j++)
         {
           if(a[i][j] == 9)
           n++;
         }
      }
    }
    //用于调试
//    printf("   1 2 3 4 5 6 7 8 9\n");
//    for (i=0; i<=X-1; i++)
//    {
//       printf("%2d", i+1);
//       for(j=0; j<=Y-1; j++)
//       {
//          printf("%2d", a[i][j]);
//          if(j == Y-1) printf("\n");
//       }
//    }
    explore_game();
}
void explore_game(void)
{
    int n=0;
    int i,j;
    for(i=0; i<X; i++){
      for(j=0; j<Y; j++)
      {
        if(a[i][j] == 9)
        {
              if(((i-1)>=0)&((j-1)>=0)) {if(!(a[i-1][j-1]==9))  a[i-1][j-1]++;}
              if(((i-1)>=0)&((j)>=0))   {if(!(a[i-1][j]==9))    a[i-1][j]++;}
              if(((i-1)>=0)&((j+1)>=0)) {if(!(a[i-1][j+1]==9))  a[i-1][j+1]++;}
              if(((i)>=0)&((j-1)>=0))   {if(!(a[i][j-1]==9))    a[i][j-1]++;}
              if(((i)>=0)&((j+1)>=0))   {if(!(a[i][j+1]==9))    a[i][j+1]++;}
              if(((i+1)>=0)&((j-1)>=0)) {if(!(a[i+1][j-1]==9))  a[i+1][j-1]++;}
              if(((i+1)>=0)&((j)>=0))   {if(!(a[i+1][j]==9))    a[i+1][j]++;}
              if(((i+1)>=0)&((j+1)>=0)) {if(!(a[i+1][j+1]==9))  a[i+1][j+1]++;}
              n++;
              //printf("n = %d,", n);
        }
     }
   }
   //if(n==10) updata_game();//生成原始棋盘(用于调试,用户不可看到)
   if(n != 10) printf("棋盘生成发生错误!\n");
}
//生成原始棋盘
void updata_game(void)
{
    int i,j;
    printf("\n   1 2 3 4 5 6 7 8 9\n");
    for (i=0; i<=X-1; i++)
    {
       printf("%2d", i+1);
       for(j=0; j<=Y-1; j++)
       {
          printf("%2d", a[i][j]);
          if(j == Y-1) printf("\n");
       }
    }
}
//选择功能
int mode_game(void)
{
   int j;
   while(1)
   {
      printf("请选择想要进行的操作:");
      scanf("%d",&j);
      fflush(stdin) ;
      switch(j)
      {
         case 1: printf("开始游戏!\n");return j;
         case 2: printf("重新开始游戏!\n");return j;
         case 0: printf("退出游戏!\n");return j;
         default:  printf("输入有误,请输入1,2,3来选择相应功能!(1.开始游戏,2.重新开始,0.结束游戏)!\n");
      }
   }
}
//打印菜单栏
void menu_game(void)
{
    printf("*********************************\n");
    printf("***********1. 开始游戏***********\n");
    printf("***********2. 重新开始***********\n");
    printf("***********0. 结束游戏***********\n");
    printf("*********************************\n");
}

运行结果显示
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_40890148/article/details/84703545