用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 init_game(void);
void menu_game(void);//打印菜单栏
int mode_game(void);//功能
void generate_initgame(void);//生成初始棋盘
void generate_game(void);//生成棋盘

//功能菜单
int start_game(void);//mode1开始游戏
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);

void replay_game(void);//mode2开始游戏
void bye_game(void);//mode0结束游戏

#endif // __SAOLEI_H

主程序


#include "saolei.h"
    int a[X][Y]={0} ;
    char b[X][Y] ;

int main()
{

    int mode,status;//记录用户选择什么功能
    memset(b, '*', X*Y*sizeof(char));
    mode = init_game();
    while(1)
    {
       switch(mode)
       {
          case 1:
                      status = start_game();
                      if(status == 0) return 0;
                      break;
          case 2:              //(并未实现)
                     replay_game();
                     break;
          case 0:
                    bye_game();
                    return 0;
       }
    }
  END:
    return 0;
}

主函数中具体代码


#include "saolei.h"

extern int a[X][Y];
extern char b[X][Y];
//初始化棋盘,关键是生成具体棋盘(某坐标可以显示周围地雷个数)
int init_game()
{
    int i;
    menu_game();//打印菜单栏
    generate_initgame();//生成棋盘(看不见地雷)
    generate_game();//生成原始地雷
    i = mode_game();//选择功能
    return i;
}
//初始化棋盘,需要显示具体信息,包括棋盘上每个点周围雷数
//1.打印菜单栏
void menu_game(void)
{
    printf("*********************************\n");
    printf("***********1. 开始游戏***********\n");
    printf("***********2. 重新开始***********\n");
    printf("***********0. 结束游戏***********\n");
    printf("*********************************\n");
}
//2.生成棋盘
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");
}
// 3.生成看不见棋盘,包含具体信息,重要!
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();
}
// 3.1这里是实现了具体棋盘的关键程序
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");
}


//4.选择功能
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");
      }
   }
}

//mode1:开始游戏
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;
}
//检测该区域是否被检测过
int check_game(int x,int y)
{
   int isc = 1;
   if(b[x][y] != '*')
        {printf("该点已经被探索过!请重新输入!\n");isc = 0;}
   return isc;
}
//检测是否踩到雷
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;
}
//当检测到0,把这个值赋值'$'
void disappear_game(int x,int y)
{
    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];
}
//展开,若周围无雷,展开
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 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");
       }
    }
}
//生成看不见的棋盘
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");
       }
    }
}


//mode2:重新开始游戏
void replay_game(void)
{
    printf("重新开始游戏!\n");
}
//mode0:结束游戏
void bye_game(void)
{
    printf("成功退出游戏!\n");
}

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

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值