VC6 + XP/Vista 调试成功
这是我自己写的一个字符版扫雷的控制台程序(有些功能还比较欠缺)...
编程不久,第一次写这么多的代码,有些注释以及变量命名不合规范,还望指出交流..
也有朋友指出这个代码更像是C风格的而不是C++的,对于C++风格我确实了解不多,希望大家能来信指出
我的邮件地址是liliflashfly(at)gmail.com,你的意见将是我前进的动力,谢谢!
相关工程(VC6版)可以在CSDN的资源http://download.csdn.net/source/799581上下载....
思路请见
说明文档:
初始化
得到边界n,m值,
建立数组mine_count,全部初始化为0(作为后台数据界面,-1表示地雷,非负数表示周围的地雷数)
建立字符数组mine_state,全部初始化为'#',表示还未探索
挖出的地雷数dig_num=0,游戏结束mine_end=false,游戏胜利mine_win=false
得到地雷值mine_num,建立循环,利用随机函数,产生mine_num个坐标(越界和地雷覆盖(bool IsMine)判断),
并且每个坐标周围的坐标地雷值(mine_count)自增一次(通过MineCountPP(y,x)函数)。
并且这些地雷坐标保存到结构体(x,y)数组Mine_Location[mine_count]中.
界面
0 1 2 3 4 5 6 7 8 9 10
1 # # # # # # # # # #
2 # # # 1 # # # # # #
3 # # # 2 # # # # # #
4 # # # # # # # # # #
5 # # 1 # # # # # # #
6 # # 1 P # # # # # #
7 # # # # # # # # # #
8 # # # # # # # # # #
9 # # # # # # # # # #
10# # # # # # # # # #
你还有8个地雷没有挖出。。。
开始游戏
输入一次坐标,返回一次全局状态(mine_state)
状态:
未探索: '#'
已探索: mine_state[x][y]!='#'
周围有地雷:相应数字,如 '6'
插旗(挖雷成功): 笑脸图案,char值为2
空的: ' '
地雷: 'O'
判断错误: 'X'
爆炸点: '_'
输入方式
s y x (step到某个坐标(x,y),即确定那里没有地雷)
d y x (dig某个坐标(x,y),即确定那里有地雷,插旗)
输入后先执行x--,y--,再判断是否越界和mine_state是否为'#',否则提示出错。
坐标输入后判断
1、s输入,是地雷(mine_count==-1)
此坐标mine_state为'_',
遍历Mine_Location[],使剩下的未探索的地雷click=true,mine_state为'*'(通过fail()函数)
d输入,不是地雷(mine_count!=-1)
此坐标mine_state为'X',
遍历Mine_Location[],使剩下的未探索的地雷click=true,mine_state为'*'(通过fail()函数)
然后游戏结束(mine_end=true),输出mine_state。
2、s输入,不是地雷(mine_count!=-1)
mine_count>0
mine_state[y][x]=mine_count+'0';
mine_count==0
mine_state[y][x]=' ';
回溯第归直到mine_count>0 或者 到了边界
3、d输入,是地雷(mine_count==-1)
mine_state[y][x]='P';
dig_num++;
if(dig_num==mine_num)
输出,胜利,结束(mine_end=true)
- #ifndef _MINE_CTRL_
- #define _MINE_CTRL_
- #include "iostream"
- #include "iomanip"
- #include "string"
- #include "ctime"
- #include "cstdlib"
- using namespace std;
- struct Mine_coordinate{
- int x,y;
- };
- class Mine
- {
- friend void Run(Mine *oMine);
- public:
- Mine(void){};
- Mine(int x,int y,int MineNum);
- virtual ~Mine(void);
- private:
-
- void MineCountPP(int y,int x);
- void GetXY(int *x,int *y);
- void Help(void);
-
- void Screen_Out(void);
- void Operate(void);
- void Deal_blank(int x,int y);
- bool Mine::IsInputOk(char &ch,int &x,int &y);
-
- void Fail(void);
- bool GoOn(void);
- bool Win(void);
- char **mine_state;
- int **mine_count;
- int dig_num,mine_num;
- int X,Y;
- bool mine_end,mine_win;
- Mine_coordinate *Mine_Location;
- };
- #endif
- #include "minectrl.h"
- Mine::Mine(int y,int x,int MineNum):X(x),Y(y),mine_num(MineNum){
- int i(0);
- mine_state=new char*[Y];
- mine_count=new int* [Y];
- srand((unsigned)time(NULL));
-
- for(;i
- mine_state[i]=new char[X];
- mine_count[i]=new int[X];
- memset(mine_state[i],'#',X*sizeof(char));
- memset(mine_count[i], 0 ,X*sizeof(int) );
- }
- dig_num=0;
- mine_end=mine_win=false;
- Mine_Location=new Mine_coordinate[mine_num];
-
-
- for(i=0;i
- int x(0),y(0);
- GetXY(&x,&y);
- while(mine_count[y][x]==-1)
- GetXY(&x,&y);
- mine_count[y][x]=-1;
- MineCountPP(x,y);
- Mine_Location[i].y=y;
- Mine_Location[i].x=x;
- }
-
- }
- void Mine::GetXY(int *x,int *y){
- *x=(rand()%X);
- *y=(rand()%Y);
- }
- void Mine::MineCountPP(int x,int y){
- int i,j;
- for(i=-1;i<2;i++)
- for(j=-1;j<2;j++)
- if(y+i>-1 && y+i-1 && x+j
- if(mine_count[y+i][x+j]!=-1)
- mine_count[y+i][x+j]++;
- }
- bool Mine::IsInputOk(char &ch,int &x,int &y){
- bool ok=true;
- if(!(cin>>ch>>x>>y) || (ch!='s'&&ch!='d') ){
- ok=false;
- cin.clear();
- }
- while(cin.get()!='/n');
- system("cls");
- cout<" "<" "<
- x--;y--;
- return ok;
- }
- void Mine::Operate(void){
- int x,y;
- char s;
- if( IsInputOk(s,x,y) &&
- -1
- mine_state[y][x]=='#'){
-
- if(s=='s'){
- if(mine_count[y][x]==-1){
- mine_state[y][x]='_';
- Fail();
- mine_end=true;
- }else{
- if(mine_count[y][x]>0)
- mine_state[y][x]='0'+mine_count[y][x];
- else{
- Deal_blank(x,y);
- }
- }
- }
- else{
-
- if(mine_count[y][x]!=-1){
- mine_state[y][x]='X';
- Fail();
- mine_end=true;
- }else{
- mine_state[y][x]=2;
- dig_num++;
- if(dig_num==mine_num){
- mine_end=true;
- mine_win=true;
- }
- }
- }
- }else{
- cout<<"错误输入,重试!"<
- }
- Screen_Out();
- }
- void Mine::Fail(void)
- {
- for(int i(0);i
- if(mine_state[Mine_Location[i].y][Mine_Location[i].x]=='#')
- mine_state[Mine_Location[i].y][Mine_Location[i].x]='O';
- }
- }
- bool Mine::GoOn(void)
- {
- return !mine_end;
- }
- bool Mine::Win(void)
- {
- return mine_win;
- }
- void Mine::Screen_Out(){
- int i,j;
- cout<<" 0|";
- for(i=1;i<=X;i++)
- cout<
-
- cout<
- for(i=0;i<2*X+3;i++)
- cout<<'-';
- puts("");
- for(i=0;i
- cout<"|";
-
- for(j=0;j
- cout<<" "<
- cout<
- }
- if(!mine_end){
- cout<<"剩余地雷:"<"个"<
- cout<<"如果认为(x,y)坐标没有地雷请输入/"s x y/""<
- cout<<"如果认为(x,y)坐标 有地雷请输入/"d x y/""<
- }
-
- }
- void Mine::Deal_blank(int x,int y){
- if(-1'#'){
- if(mine_count[y][x]==0){
- mine_state[y][x]=' ';
- int xShift[]={-1,-1,-1,0,0,1,1,1};
- int yShift[]={-1,0,1,-1,1,-1,0,1};
- for(int i=0;i<8;i++){
- Deal_blank(x+xShift[i],y+yShift[i]);
- }
- }else{
- mine_state[y][x]='0'+mine_count[y][x];
- }
- }
- }
- void Mine::Help(void){
- cout<<"此游戏是扫雷的翻版(还欠缺一些功能,不过可以玩了...)"<
- cout<<"#表示还没有被探索"<
- cout<<(char)2<<"表示此地雷被挖除"<
- cout<<"O表示此地雷没有被发现"<
- cout<<"_表示踩到地雷了,失败"<
- cout<<"X表示此处没有地雷,失败"<
- cout<<"操作方法:"<
- cout<<"如果认为(x,y)坐标没有地雷请输入/"s x y/",如s 3 5"<
- cout<<"如果认为(x,y)坐标 有地雷请输入/"d x y/",如d 6 3"<
- cout<<"回车键继续..."<
- while(cin.get()!='/n');
- }
- Mine::~Mine(void){
- int i(0);
- for(;i
- {
- delete [] mine_state[i];
- delete [] mine_count[i];
- }
- delete [] mine_state;
- delete [] mine_count;
- delete [] Mine_Location;
- }
- void Run(Mine *oMine){
- int x=9,y=9,MineNum=10;
- char ask;
- bool ContinueMine=true;
- while(ContinueMine){
- system("cls");
- oMine=new Mine(y,x,MineNum);
- oMine->Help();
- system("cls");
- oMine->Screen_Out();
- while(oMine->GoOn()){
- oMine->Operate();
- }
- if(oMine->Win())
- cout<"You Win!"<
- else
- cout<"You lose..."<
- delete oMine;
- cout<<"再来?(Y/N)";
- ask=cin.get();
- if(ask!='y' && ask!='Y') ContinueMine=false;
- if(ask=='/n') cin.putback(ask);
- while(cin.get()!='/n') ;
- }
- cout<<"ByeBye..."<
- }
- #include "minectrl.h"
- int main(){
- Mine *oMine=NULL;
- Run(oMine);
- return 0;
- }