命令行版扫雷(vc08)
复制代码
模拟鼠标各种按键
左键 翻开
右键 标雷
左右键 翻开周围
先判断当前点是否为已翻开的点
时间
地雷计数器
清屏
展开
大于8时不管
小于等于8时翻开本身
为0时翻开周围的
输出
同雷数图
雷区判断
判断游戏结束
剩下的是否和雷数相等
*标记出所有的雷
踩到雷了
动态数组
第一次操作时才开始布雷
布雷后制作雷数图
0无雷 9本身是雷 10已经翻开的
10+X 表示 已经翻开的有数字的
20+X 表示 标了雷区的 (29则为正确标注的)
20表示边界
雷数选择范围
*翻开标记为雷区的点时进行确认操作
*选择重新开始等
接着这盘游戏
仅悔一步
*保存游戏?
*作弊功能?
//11.27
传值参数有很多的相似,可以进行封装:结构体,容器,数组
复制代码
复制代码
#include <iostream>
#include<vector>
#include<string>
#include"function.h"
using namespace std;
int main()
{
int hight;
int width; //6*6开始
int bob;
while(1){
cout<<"请输入雷阵高度(6-99): " ;
cin>>hight;
if(hight<100 && hight >5){
break;
}
}
while(1){
cout<<"请输入雷阵宽度(6-99): " ;
cin>>width;
if(width<100 && width >5){
break;
}
}
while(1){
cout<<"请输入地雷数目(8-"<<( width*hight/10*9) <<"): " ;
cin>>bob;
if(bob<= (width*hight/10*9) && bob >7){
break;
}
}
vector<vector<int> > map( hight+2, vector<int>(width+2,0) ); //创建地图
#if 0
map[0][0]=9;
map[0][width-1]=9;
map[hight-1][0]=9;
map[hight-1][width-1]=9;
#endif
setGame(map, hight, width, bob);
playGame(map, hight, width, bob);
}
复制代码
复制代码
#include"function.h"
#include<ctime>
#include<vector>
using namespace std;
void setBob(vector<vector<int>> & map, int bob ,int r, int w)
//开始随机布雷,并使得刚开始挖的点不为雷区
{
//变量声明,确定map的高度和宽度等
vector<vector<int>>::difference_type hight = map.end() - map.begin();
vector<int>::difference_type width = map[0].end() - map[0].begin();
vector<vector<int>>::size_type tmpH;
vector<int>::size_type tmpW;
//开始随机布雷
srand(static_cast<int>(time(0)));
for(int i=0;i!=bob;++i){
tmpH = rand() % (hight-2) +1;
tmpW = rand() % (width-2) +1;
if(map[tmpH][tmpW] == 9){
--i;
}
else{
map[tmpH][tmpW] = 9;
}
}
//使刚开始挖的点不为雷区
if(map[r][w] == 9){
do{
tmpH = rand() % (hight-2) +1;
tmpW = rand() % (width-2) +1;
}while(map[tmpH][tmpW] != 9);
}
map[tmpH][tmpW] = 9;
map[r][w] = 0;
}
void setMap(vector<vector<int>> & map)
//设置每格中显示的雷数
{
//变量声明,确定map的高度和宽度等
vector<vector<int>>::difference_type hight = map.end() - map.begin();
vector<int>::difference_type width = map[0].end() - map[0].begin();
for(int i=1;i!=hight-1;++i){
for(int j=1;j!=width-1;++j){
if(map[i][j] > 8){
++map[i-1][j-1];
++map[i-1][j];
++map[i-1][j+1];
++map[i][j-1];
++map[i][j+1];
++map[i+1][j-1];
++map[i+1][j];
++map[i+1][j+1];
}
}
}
for(int i=1;i!=hight;++i){
for(int j=1;j!=width;++j){
if(map[i][j] > 9){
map[i][j] = 9;
}
}
}
//设置边界的数值为20
for(int i=0;i!=width;++i){
map[0][i] = 20;
map[hight-1][i] = 20;
}
for(int i=1;i!=hight;++i){
map[i][0] = 20;
map[i][width-1] = 20;
}
}
int digBob(vector<vector<int>> & map ,int r ,int w)
//挖雷,返回已经挖开点的总数
//-1表示挖到雷了
{
static int count = 0;
if(map[r][w]>9 ){
return count; //挖的点已经翻开,或为边界,或标为雷区
}
else if(map[r][w] == 9){
endGame(map,0,0);
return -1;
}
else{
map[r][w]+=10;
++count; //挖点记数器
//当前点的周围雷数为0则继续挖周围的点
if(map[r][w] == 10){
digBob(map,r-1,w-1);
digBob(map,r-1,w);
digBob(map,r-1,w+1);
digBob(map,r,w-1);
digBob(map,r,w+1);
digBob(map,r+1,w-1);
digBob(map,r+1,w);
digBob(map,r+1,w+1);
}
return count;
}
}
复制代码
复制代码
#include"function.h"
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int getCmd(int & hight, int & width)
//获取用户指令,返回坐标(通过引用)和操作类型
//如输入错误则返回相应错误代码:
//-1:输入错误 -2:坐标越界
//hight及width的值可能会被修改
{
int temp; //存放坐标
string cmd;
do{
cout<<"请输入指令:";
getline( cin,cmd);
}
while(cmd.empty());
int sizeCmd = cmd.size();
if(sizeCmd == 4 || sizeCmd == 5){ //用户输入4或5个字符的可能性最大
//检查输入是否正确
for(int i=0;i!=4;++i){
if(cmd[i]<48 || cmd[i]>57){
return -1;
}
}
temp = (cmd[0]-48)*10 + (cmd[1]-48);
//检查输入坐标是否越界
if(temp <= hight){
hight = temp;
}
else{
return -2;
}
temp = (cmd[2]-48)*10 + (cmd[3]-48);
if(temp <= width){
width = temp;
}
else{
return -2;
}
if(sizeCmd == 4){
return 1; //默认返回值
}
else{
if(cmd[4]>51 || cmd[4]<49){
return -1;
}
else{
return ( cmd[4]-48 );
}
}
}
else if(sizeCmd == 1){
switch(cmd[0])
{
case '?':
case 'h':
case 'H':
return 4; //帮助
break;
case 'r':
case 'R':
return 5; //重新开始
break;
case 'e':
case 'E':
return 6; //退出
break;
default:
return -1;
}
}
else {
return -1;
}
}
void setGame(vector<vector<int>> & map, int hight,int width, int bob)
{
outpMethod();
setMap(map);
outpMap(map);
int hightGet;
int widthGet;
while( 1 ){
hightGet = hight;
widthGet = width;
switch( getCmd(hightGet, widthGet) ){
case -1:
cout<<"输入错误,请重新输入"<<endl;
break;
case -2:
cout<<"坐标越界,请重新输入"<<endl;
break;
case 1:
setBob(map, bob, hightGet, widthGet);
setMap(map);
if( digBob(map, hightGet, widthGet) == hight*width-bob){
endGame(map,0,1);
}
else{
outpGame(map,bob);
}
return; //退出函数
case 2:
case 3:
cout<<"游戏刚开始还是挖雷吧"<<endl;
break;
case 4:
outpHelp();
outpMethod();
outpMap(map);
break;
case 5:
//还没想好怎么重新开始
break;
case 6:
exit(0);
break;
default :
;
}
}
}
void playGame(vector<vector<int>> & map , int hight, int width, int bob)
{
int hightGet;
int widthGet;
int pointAmount = hight * width;
int digCount = 0;
int flatCount = 0;
bool flat = 1;
while( flat ){
hightGet = hight;
widthGet = width;
switch( getCmd(hightGet, widthGet) ){
case -1:
cout<<"输入错误,请重新输入"<<endl;
break;
case -2:
cout<<"坐标越界,请重新输入"<<endl;
break;
case 1:
//挖雷
digCount = digBob(map, hightGet, widthGet);
outpGame(map, bob-flatCount);
if(digCount + bob == pointAmount){
flat = 0;
endGame(map,0,1);
}
break;
case 2:
//标记/取消标记 雷区
if(map[hightGet][widthGet] < 10){
map[hightGet][widthGet] += 20;
++flatCount;
outpGame(map, bob-flatCount);
}
else if(map[hightGet][widthGet] > 19
&& map[hightGet][widthGet] != 30)
{
map[hightGet][widthGet] -= 20;
--flatCount;
outpGame(map, bob-flatCount);
}
else{
cout<<"这个点已经被挖过了"<<endl;
}
break;
case 3:
//翻开周围
if(map[hightGet][widthGet]<11
|| map[hightGet][widthGet]>18)
{
cout<<"不能对该点进行此操作"<<endl;
break;
}
else{
int ardigCount = 0;
if(map[hightGet-1][widthGet-1] >20){
++ardigCount;}
if(map[hightGet-1][widthGet] >20){
++ardigCount;}
if(map[hightGet-1][widthGet+1] >20){
++ardigCount;}
if(map[hightGet][widthGet-1] >20){
++ardigCount;}
if(map[hightGet][widthGet+1] >20){
++ardigCount;}
if(map[hightGet+1][widthGet-1] >20){
++ardigCount;}
if(map[hightGet+1][widthGet] >20){
++ardigCount;}
if(map[hightGet+1][widthGet+1] >20){
++ardigCount;}
if(ardigCount == map[hightGet][widthGet]-10){
digBob(map, hightGet-1, widthGet-1);
digBob(map, hightGet-1, widthGet);
digBob(map, hightGet-1, widthGet+1);
digBob(map, hightGet, widthGet-1);
digBob(map, hightGet, widthGet+1);
digBob(map, hightGet+1, widthGet-1);
digBob(map, hightGet+1, widthGet);
digCount = digBob(map, hightGet+1, widthGet+1);
outpGame(map, bob-flatCount);
}
else{
cout<<"暂时不能对该点进行此操作"<<endl;
}
if(digCount + bob == pointAmount){
flat = 0;
endGame(map,0, 1);
}
}
break;
case 4:
outpHelp();
outpGame(map, bob-flatCount);
break;
case 5:
//还没想好怎么重新开始
break;
case 6:
exit(0);
break;
default :
;
} //switch语句
} //里层while循环
}
void endGame(vector<vector<int>> & map,int bobLeft, int flat)
//结束游戏.
//1表示成功 0表示失败:
{
outpGame(map,bobLeft,1);
}
复制代码
复制代码
#include"function.h"
#include"windows.h"
#include<cstdio>
#include<ctime>
using namespace std;
//inline in function.h
void outpGame(vector<vector<int>> & map, int flat = 0);
void outpHelp( )
//输出操作提示
{
system("cls"); //清屏
printf("\
操作提示: xxyyt\n\
其中 xx表示第xx行,yy表示第yy列,t表示进行的操作\n\
1:挖雷(不输入t值则默认此项) 2; 标记/取消标记 雷区 3; 翻开周围区域\n\
如 05061\n\
请按任意键继续\
"); // "\"
getchar( );
system("cls"); //清屏
}
void outpMap(vector<vector<int>> & map, int flat)
//输出图形,以及坐标
//flat默认为0
{
//顶排输出横坐标
printf(" ");
int i=1;
for(int amount = map[0].end()-map[0].begin(); i <= amount; i+=2){
printf(" %02d",i);
}
printf("\n");
i=0;
for(vector<vector<int> >::iterator iterL = map.begin();
iterL != map.end(); ++iterL)
{
putchar(' ');
//左排纵坐标
if( !(i%2) ){
printf("%02d",i);
}
else{
printf(" ");
}
for(vector<int>::iterator iter = (*iterL).begin();
iter != (*iterL).end(); ++iter)
{
#if 0
cout<<setw(3)<<setfill(' ')<<*iter;
#else
//显示雷区
if(flat && *iter%10 == 9){
printf("★" );
}
//未翻开
else if(*iter < 10 ){
printf("■");
}
//已翻开且周围无雷
else if(*iter == 10){
printf("·");
}
//已翻开且周围有雷
else if(*iter < 19){
printf(" %d",*iter-10);
}
//边界
else if(*iter == 20){
printf("·");
}
//标记为雷区
else {
printf("▲");
}
#endif
}
//右排纵坐标
if(i%2){
printf("%02d",i);
}
++i;
printf("\n");
}
//底排输出横坐标
printf(" ");
i=0;
for(int amount = map[0].end()-map[0].begin(); i < amount; i+=2){
printf(" %02d",i);
}
printf("\n");
}
void outpState(int bobLeft)
//输出当前状态:使用时间,剩余雷数
{
static unsigned long long timeBegin = time(0);
printf("已用时间: %d秒\t\t",time(0)-timeBegin);
printf("剩下地雷: %d个\n",bobLeft);
printf("--------------------------------------------------------------------\n");
}
void outpMethod()
{
printf("1:挖雷(默认) 2:标记/取消标记雷区 3:翻开周围 ?:查看帮助 e:退出\n");
printf("--------------------------------------------------------------------\n");
}
复制代码
在这,碰到了一个比较郁闷的问题:如何清空输入流。如过当前的输入非法,那么当前流得不到释放,会影响下次的输入效果。且C++的流IO效率不是很高。
当时写这个程序的时候,还不会类,而且map的数据结构很有问题,效率低且占用内存大,等以后学习了更多的知识后,将进行修改。
http://www.cnblogs.com/h46incon/archive/2011/01/20/1939843.html
命令行版扫雷(vc08)的更多相关文章
- Python 实现有道翻译命令行版
一.个人需求 由于一直用Linux系统,对于词典的支持特别不好,对于我这英语渣渣的人来说,当看英文文档就一直卡壳,之前用惯了有道词典,感觉很不错,虽然有网页版的但是对于全站英文的网页来说并不支持.索性 ...
- 安装appium桌面版和命令行版
一 桌面版(打开很慢,常用于辅助元素定位) 1.官网下载window版本: 2.直接点击紫色图标即可打开 3.启动server 二 命令行版(打开很快,常用于执行脚本) 1.jdk 安装jdk并 ...
- appium桌面版和命令行版的安装
一.appium桌面版: 启动很慢,一般用于元素定位 Appium-Desktop官方下载地址:https://github.com/appium/appium-desktop/releases/ ( ...
- Windows下安装appium桌面版和命令行版
安装appium桌面版和命令行版 一 桌面版(打开很慢,常用于辅助元素定位) 1.官网下载window版本: github search appium desktop download late ...
- GitBook制作电子书详细教程(命令行版)
GitBook 是一款基于 Node.js 开发的开源的工具,可以通过命令行的方式创建电子书项目,再使用 MarkDown 编写电子书内容,然后生成 PDF.ePub.mobi 格式的电子书,或生成一 ...
- Shell终端收听音乐--网易云音乐命令行版
Musicbox:网易云音乐命令行版本 高品质网易云音乐命令行版本,简洁优雅,丝般顺滑,基于Python编写. 这款命令行的客户端使用 Python 构建,以 mpg123 作为播放后端: Vim 式 ...
- Centos 7 命令行版虚拟机安装
使用VMware创建虚拟机 点击下一步 点击下一步 下一步 选择你要安装的虚拟机是哪种操作系统 选择虚拟机的安装位置 选择处理器 自定义内存 选择网络 下一步 下一步 下一步就可以 自定义磁盘容量 然 ...
- Shell终端收听音乐--豆瓣FM命令行版
douban.fm Terminal-based douban.fm inspired by douban.fm.该版本版基于Python2.* 安装Python2.* pacman -S pytho ...
- foobar2000实现用手机远程控制PC命令行版
实现此功能主要是在手机上使用Telnet命令实现下一首播放. 1.安装Telnet守护进程插件:http://www.foobar2000.org/components/view/foo_telnet ...
随机推荐
- Java Service Wrapper 使用(windows)
1 简介 最近项目中需要做一个Windows系统服务,记录一下使用过程. Java Service Wrapper 可以将Java程序包装成系统服务,这样就可以随着系统的运行而自动运行.J ...
- @AspectJ support (good)
AspectJ类型匹配的通配符:*:匹配任何数量字符:..:匹配任何数量字符的重复,如在类型模式中匹配任何数量子包:而在方法参数模式中匹配任何数量参数.+:匹配指定类型的子类型:仅能作为后缀放在类型模 ...
- Net锁
Net分布式锁的实现 序言 我晚上有在公司多呆会儿的习惯,所以很多晚上我都是最后一个离开公司的.当然也有一些同事,跟我一样喜欢在公司多搞会儿.这篇文章就要从,去年年末一个多搞会的晚上说起,那是一个夜黑 ...
- node assert模块 Study.1
1.assert() 大体理解意思:assert可以抽象理解为node中的alert++ assert模块是Node的内置模块,用于断言的作用,如果不是自己想要的就抛出错误 assert(arg1, ...
- 外部进程嵌入到Qt进程界面(使用QWindow::fromWinId)
有时候需要做框架集成的东西,需要把其他客户端像组件一样集成到一个客户端中,类似于一个软件集成的平台客户端,统一用一个中心管理的客户端做类似于控制面板一样的东西去调用不同的软件.此时就必须相应不同的点击 ...
- QT 内存文件映射就是如此简单!
QFile file(fileName); file.open(QIODevice::ReadWrite ); uchar* fpr = file.map(0, file.size());//映射文件 ...
- 统计web訪问前10的ip
cat access.log|awk '{print $0}'|sort|uniq -c|sort -nr|head -n 10
- Distinct去除重复项
之前在做权限模块时,因不同角色可能拥有相同的菜单,导致呈现在浏览器上时出现重复菜单项,所以需要在获取用户拥有菜单项时需要过滤重复项, 用到了Distinct,两个重载 public static IQ ...
- AABB边框、OBB边框、通过比较球包围
1) AABB 包围盒: AABB 包围盒是与坐标轴对齐的包围盒, 简单性好, 紧密性较差(尤其对斜对角方向放置的瘦长形对象, 採用AABB, 将留下非常大的边角空隙, 导致大量不是必需的包围盒相交測 ...
- WPF_界面_图片/界面/文字模糊解决之道整理
原文:WPF_界面_图片/界面/文字模糊解决之道整理 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010265681/article/detai ...