即时显示时间(或者限时通关)的扫雷游戏(利用_kbhit())

使用二维数组,指针和函数的知识实现地雷数和棋盘大小可变的扫雷游戏
完整代码如上,此代码在上文基础上增加了即时显示时间和限时通关的功能。

程序截图

在这里插入图片描述

1.时间计算

  • 通过time函数获取时间戳
  • 在游戏开始的时候获取一次,赋给变量timeStart,作为初始时间
  • 之后每此循环获取一次,赋给变量timeCurrent,作为当前时间
  • 则时间差值就是游戏时长timeDifference = timeCurrent - timeStart;
void game(int x, int y, int nummine) {
   time_t timeStart = time(NULL);//初始时间
   int num = x * y - nummine; //统计无雷且未被探测的格子数,当为0时退出退出,此时所有未探测的地方都有雷
   char flag[100][100]; //标记已经探测过的位置,当已经探测过,显示周围地雷数,否则显示*
   int mine[101][101]; // 统计地雷位置,有雷时为1,无雷时为0;
   int bl = 0;
   Lay(x, y, nummine, flag, mine); //初始化游戏数据
   system("CLS");
   do {
       time_t timeCurrent = time(NULL);//当前时间
       int timeDifference = difftime(timeCurrent,timeStart);//时间差
       if(bl != 4) interfaceone(x, y, flag); //打印游戏界面
       printf("(还有%d个无雷格子待探测)", num);
       bl = detect(x, y, &num, bl, mine, flag, timeDifference); //进行扫雷行为
       Sleep(10);//程序休眠10ms
       if (bl == 4) printf("\r"); 
       else system("CLS");//清空屏幕
       if (num == 0) break;//剩余无雷格子数为0时游戏胜利。
   } while (bl);
   if (bl) printf("*********扫雷完成**********\n");
   else print(x, y, mine);
}

2.无输入时继续程序运行

正常来说,循环计算时间差值打印在屏幕上作为程序运行时间没有问题。但是C语言的语句执行时顺序的,而我们每次循环都需要输入一个坐标来进行地雷探测。在输入的时候,程序会停止在这一行。此时屏幕上的时间计数也会停止;
我们需要程序在我们没有输入的时候继续循环打印时间,在有输入的时候获取输入。
这时候使用__kbhit()

if(_kbhit())
	scanf("%d %d",&a,&b);//有输入时获取输入 赋值给变量a,b
else
	return;//无输入时结束函数

3.扫雷过程中实现即时显示时间

int detect(int x, int y, int* num, int bl, int mine[101][101], char flag[100][100],int timeDifference) {
    int a, b;
    if (bl == 2) printf("这个位置已经探测过了,请输入一个未探测过的位置(%ds):>", timeDifference);
    else if (bl == 3) printf("这个位置不在棋盘上,请重新输入(%ds):>", timeDifference);
    else printf("请输入你要探测的位置(%ds):>", timeDifference);
    if (_kbhit()){//有输入时开始探测
        scanf("%d %d", &a, &b);
        if (a <= x && b <= y && a > 0 && b > 0) {
            if (mine[a][b]) return 0;//如果有雷则退出
            else if (flag[a][b] != 42) return 2;
            else {
                flag[a][b] = numminearound(a, b, mine);
                (*num)--;
                return 1;
            }
        }
        else return 3;//
    }
    else return 4;//无输入时返回3
}

4. 保持屏幕干净

  • system(“CLS”)可以实现清空控制台界面;
  • printf(“\t”);可以让指针回到行首,实现删除指针所在行的功能

4.1 detect的返回值

  • 在返回数为0时,表示扫到了雷,游戏失败
  • 返回数为1时,表示探测地无雷。且已经显示探测地周围雷数。
  • 返回数为2时,表示新的探测地点在前面的游戏行为中已经被探测过了。直接退出,不在探测周围雷数。
  • 返回值为3时,则探测的地方不在棋盘上。请求重新输入
  • 返回值为4时,玩家没有输入行为

4.2 根据返回值判断如何清理屏幕

  • 返回值为0时,游戏失败,运行system(“CLS”)打印地雷棋盘和开始菜单。玩家可以选择重新开始游戏或者退出。
  • 返回值为4时,玩家没有输入,运行printf(“\t”)。使得屏幕上显示时间戳被清除。重新打印。(此时只是在屏幕的相同位置循环打印时间,不影响棋盘)
  • 返回值为其他,此时玩家有输入。运行system(“CLS”)清除屏幕,并打印棋盘和时间。(此时同时打印棋盘和时间)
    do {
       time_t timeCurrent = time(NULL);//当前时间
       int timeDifference = difftime(timeCurrent,timeStart);//时间差
       if(bl != 4) interfaceone(x, y, flag); //打印游戏界面
       printf("(还有%d个无雷格子待探测)", num);
       bl = detect(x, y, &num, bl, mine, flag, timeDifference); //进行扫雷行为
       Sleep(10);//程序休眠10ms
       if (bl == 4) printf("\r"); //只清理时间
       else system("CLS");//清空屏幕
       if (num == 0) break;
   } while (bl);

5.实现限时通关

  • 我们已经成功统计了游戏内的时间
  • 只需要设置一个时间最大值,在时间超过这个最大值时退出
int timemax = 0;

if(timemax){	//当时间最大值大于0时判断是否超时,否则表示没设置时间上限
	if(timeDifference > timemax) {
		bl = 0; //bl为detect函数的返回值,当bi为0时表示扫到雷了,循环退出。
	}
}

还需要修改bl等于0时的逻辑,之前bl=0时只有一种情况:踩到雷了;现在多了一种:超出时间

if (bl) printf("*********扫雷完成**********\n");
else {  
	if(timeDifference > timemax) printf("*****扫雷失败,时间耗尽*****\n");
	else printf("*****扫雷失败,踩到雷了*****\n");
	print(x, y, mine)
}

游戏内打印的时间变为剩余时间

else printf("请输入你要探测的位置(%ds):>", timemax-timeDifference);
//可以直接把timemax-timeDifference的结果当参数传入detect函数,否则还要把两个变量都传入
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值