宝石迷阵 c++.docx
- 文档编号:26666068
- 上传时间:2023-06-21
- 格式:DOCX
- 页数:16
- 大小:19.41KB
宝石迷阵 c++.docx
《宝石迷阵 c++.docx》由会员分享,可在线阅读,更多相关《宝石迷阵 c++.docx(16页珍藏版)》请在冰豆网上搜索。
宝石迷阵c++
#include
#include
#include
#include
#include
usingnamespacestd;
//设置控制台输出的文本颜色
voidsetColor(intcolor)//参数为int类型,0-4分别代表红绿蓝紫黄,5为白色
{
HANDLEhOut;
hOut=GetStdHandle(STD_OUTPUT_HANDLE);//获取标准输出流句柄
if(hOut==0)//获取句柄失败函数返回
return;
if(color==0)//设置文本为红色
{
SetConsoleTextAttribute(hOut,
FOREGROUND_RED|
FOREGROUND_INTENSITY);
}
elseif(color==1)//绿色
{
SetConsoleTextAttribute(hOut,
FOREGROUND_GREEN|
FOREGROUND_INTENSITY);
}
elseif(color==2)//蓝色
{
SetConsoleTextAttribute(hOut,
FOREGROUND_BLUE|
FOREGROUND_INTENSITY);
}
elseif(color==3)//紫色
{
SetConsoleTextAttribute(hOut,
FOREGROUND_BLUE|
FOREGROUND_RED|
FOREGROUND_INTENSITY);
}
elseif(color==4)//黄色
{
SetConsoleTextAttribute(hOut,
FOREGROUND_RED|
FOREGROUND_GREEN|
FOREGROUND_INTENSITY);
}
elseif(color==5)//白色,这个是默认的颜色
{
SetConsoleTextAttribute(hOut,
FOREGROUND_RED|
FOREGROUND_GREEN|
FOREGROUND_BLUE|
FOREGROUND_INTENSITY);
}
/*
游戏类定义。
整体思路为:
用一个int类型10*10数组来代表整个游戏地图信息。
其元素取值范围为0到4
分别代表红绿蓝紫五中颜色的宝石。
值为-1则代表此处的宝石消失了。
drop()函数提供因为一些宝石消失而使其上方宝石依次下降的功能
supply()函数提供经过下降以后的宝石地图中,补充最上方值为-1的位置的宝石
disappear()函数将连续的超过3个一起的同种颜色宝石消除功能。
消除了一部分宝石后,需要下降宝石和补充宝石。
move(int,int,Dir)提供按照指定方向移动指定位置宝石功能
initGame()函数初始化游戏地图
print()函数打印游戏地图到屏幕
执行游戏步骤时,首先调用move函数移动一个位置,然后调用disappear函数消除可能因为位置移动而产生的
连续宝石。
重复上述步骤,即是游戏过程。
*/
classCGame
{
public:
enumDir{W,S,A,D,N};//枚举类型,表示移动方向上下左右,N代表错误方向
public:
CGame(){initGame();}//在构造函数中直接初始化一个游戏
voidinitGame();//初始化游戏
voidprint()const;//打印地图
voiddrop();//宝石下降
voidsupply();//补充宝石
voiddisappear();//消除宝石
boolmove(intx,inty,Dird);//移动宝石
boolRun();
private:
intarr[10][10];//地图信息二维数组
staticconstchar*Color[5];//静态常量字符串数组,为五种宝石在屏幕显示的图形
staticintscore;//静态成员变量,保存分数,每消除一个宝石得10分
};
constchar*CGame:
:
Color[5]={"■","□","☆","★","◎"};
intCGame:
:
score=0;//初始化分数为0
voidCGame:
:
initGame()
{
for(inti=0;i!
=10;++i)
for(intj=0;j!
=10;++j)
arr[i][j]=rand()%5;//将所有元素随机赋值为0-4
disappear();//消除连续宝石
score=0;//初始化游戏时将分数设置为0
}
//在屏幕打印一个宝石地图的表格
voidCGame:
:
print()const
{
//首先打印列标号0-9
cout<<"";
for(inti=0;i!
=10;++i)
cout< cout< //打印表格第一行 cout<<""; cout<<"┌"; for(inti=0;i! =10;++i) { if(i! =9) cout<<"─┬"; else cout<<"─┐"; } cout< //打印五种宝石 for(inti=0;i! =10;++i) { cout< for(intj=0;j! =10;++j) { if(arr[i][j]! =-1) { setColor(arr[i][j]);//设置输出文本的颜色为某种宝石的颜色 cout< setColor(5);//颜色设置回默认的白色 cout<<"│";//表格的边框 } else { cout<<"│"; } } cout< //打印表格中行分割线 if(i! =9) { cout<<"├"; for(inti=0;i! =10;++i) { if(i! =9) cout<<"─┼"; else cout<<"─┤"; } cout< } } //打印表格最后一行 cout<<""; cout<<"└"; for(inti=0;i! =10;++i) { if(i! =9) cout<<"─┴"; else cout<<"─┘"; } //显示得分 cout<<"\t\t"<<"当前得分: "; setColor(0);//以红色显示分数 cout< setColor(5);//恢复白色 } /* drop函数执行因为宝石的消除而空出位置,从而将其上方依次降落 函数对地图二维数组按照列来循环,依次处理一列 每一列10个元素,通过一个临时的有10个元素的一维数组,保存下这一列中所有不为-1的元素 并计算不为-1的元素的个数pos。 如果最终pos小于10,代表本列中存在-1的元素,即存在被消除的宝石 而被消除的宝石个数为10-pos个。 那么这一列经过下降后,前面10-pos个元素应该为-1,后面的 元素应该是前面保存到临时数组中不为-1的元素。 */ voidCGame: : drop() { intb[10]={0};//临时数组用来存放某一列中所有值不为-1的元素 for(intcol=0;col! =10;++col)//对二维数组按照列来遍历 { intpos=0;//pos最终将是这一列中值不为-1的元素个数 for(inti=0;i! =10;++i) { if(arr[i][col]! =-1)//保存下不为-1的元素 b[pos++]=arr[i][col]; } if(pos<10)//如果最终pos小于10,代表本列中存在-1的元素,即存在被消除的宝石 {//而被消除的宝石个数为10-pos个 for(inti=0;i! =10-pos;++i)//将这一列的前10-pos个元素设置为-1 arr[i][col]=-1; for(inti=0;i! =pos;++i)//从b中将保存的不为-1的值依次保存回二维数组列中 arr[10-pos+i][col]=b[i]; } } } /* supply函数补充因为消除宝石而空余的位置。 首先注意到,补充宝石应该是在宝石下降以后才执行的步骤。 经过宝石下降以后,假如某一列需要进行宝石的补充,那么显然要补充的位置都应该在某一列的前部。 在这个思路下,对二维数组按照列来遍历循环 对于每一列,从0行开始到9行结束,假如这一行的值是-1,则代表需要补充,那么给其赋值0-4的随机数 假如某一行不为0,那么显然它后面的元素也不会为-1,可直接break跳出行的循环而进行下一列的循环。 */ voidCGame: : supply() { for(intcol=0;col! =10;++col)//对每一列 { for(introw=0;row! =10;++row)//没每一行 { if(arr[row][col]! =-1)//如果这一行的值不是-1,直接跳出内层循环 break; else//如果值为-1,那么给它一个0-4的随机数补充宝石 arr[row][col]=rand()%5; } } } /* move函数移动一个宝石。 其参数为宝石原始的坐标位置以及移动的方向。 方向使用类中定义的枚举类型来代表 首先可以确认的是,对第一行的宝石执行上移、对最后一行的宝石执行下移,对最左列的宝石执行左移 以及对最右列的宝石右移都是无效的操作。 而对宝石的移动,实际上就是交换宝石与其相邻一个位置的宝石 */ boolCGame: : move(intx,inty,Dird) { if((0==x&&d==W)||(0==y&&d==A)//这些是无效的移动,函数返回false ||(9==x&&d==S)||(9==y&&d==D)) returnfalse; if(x<0||x>=10||y<0||y>=10)//假如输入的坐标位置超过数组范围,函数返回false returnfalse; intx1,y1;//x1y1代表在宝石移动方向上的相邻坐标 if(d==W)//如果向上移动 { x1=x-1; y1=y; } elseif(d==S)//向下移动 { x1=x+1; y1=y; } elseif(d==A)//向左移动 { x1=x; y1=y-1; } elseif(d==D)//向右移动 { x1=x; y1=y+1; } else//方向错误 returnfalse; //交换两个宝石的值 intt=arr[x][y]; arr[x][y]=arr[x1][y1]; arr[x1][y1]=t; returntrue; } /* disappear函数消除连续的宝石 整体思路为,从数组底部开始向上遍历整个数组,如果某一个位置值不是-1,即这个位置存在宝石 那么计算出这个宝石上下左右四个方向上连续的同颜色的宝石数目 如果其上方和下方的同颜色宝石数目之和大于等于2,就是说明这个列位置上有连续的3颗以上同颜色宝石 如果其左方和右方的同颜色宝石数目之和大于等于2,就是说明这个行位置上有连续的3颗以上同颜色宝石 只要有以上两种情况中任何一种,那么就需要消除这些连续的宝石 消除的方法就是将整个连续范围内的宝石值设置为-1 消除完这些宝石之后,需要调用drop函数使上方的宝石下降,然后需要补充宝石 补充之后则需要从新调用disappear函数进行宝石消除 重复整个过程,指定整个地图中不存在能够消除的宝石为止 */ voidCGame: : disappear() { for(inti=9;i>=0;--i)//对数组从最后一行往上遍历 { for(intj=0;j! =10;++j) { if(arr[i][j]! =-1)//如果这个位置的宝石不是-1 { //依次计算其上下左右方向上连续的同颜色的宝石数目 intup=0,down=0,left=0,right=0; for(intk=i+1;k<10;++k)//计算arr[i][j]下方相同颜色宝石个数 { if(arr[k][j]! =arr[i][j])//颜色不同的时候结束计数 break; ++down; } for(intk=i-1;k>=0;--k)//计算arr[i][j]上方相同颜色宝石个数 { if(arr[k][j]! =arr[i][j]) break; ++up; } for(intk=j-1;k>=0;--k)//计算arr[i][j]左方相同颜色宝石个数 { if(arr[i][k]! =arr[i][j]) break; ++left; } for(intk=j+1;k<10;++k)//计算arr[i][j]右方相同颜色宝石个数 { if(arr[i][k]! =arr[i][j]) break; ++right; } if(up+down>=2||left+right>=2)//假如列或者行上连续的宝石超过3个 {//(这里要算上宝石本身,所以上下或左右之和大于等于2即进行消除) if(up+down>=2)//如果是上下方向有连续3个以上宝石 { for(intx=i-up;x<=i+down;++x)//在二维数组列上将相应的宝石设置为-1 arr[x][j]=-1; score+=(up+down+1)*10;//根据消除的宝石数目计算分数 } if(left+right>=2)//如果是左右方向有连续3个以上宝石 { for(inty=j-left;y<=j+right;++y)//在二维数组列上将相应的宝石设置为-1 arr[i][y]=-1; score+=(left+right+1)*10;//根据消除的宝石数目计算分数 } if(up+down>=2&&left+right>=2)//这时计算的分数多了10分,减去10 score-=10; drop();//消除宝石后下降宝石 supply();//下降宝石后补充宝石 disappear();//递归调用函数本身,继续去消除宝石 }//当整个地图没有可以消除的连续宝石递归结束 } } } } boolCGame: : Run() { system("cls");//清空屏幕 print();//打印当前地图信息 cout<<"请选择操作(W-上移S-下移A-左移D-右移Q-退出): "; intx=0,y=0; charc; CGame: : Dird;//标记要移动的方向 cin>>c; if('Q'==c||'q'==c)//如果输入Q函数返回fals returnfalse; elseif('W'==c||'w'==c)//输入其他字符确定移动方向 d=CGame: : W; elseif('S'==c||'s'==c) d=CGame: : S; elseif('A'==c||'a'==c) d=CGame: : A; elseif('D'==c||'d'==c) d=CGame: : D; else d=CGame: : N; cout<<"请输入要移动的位置坐标X和Y: "; cin>>x>>y; while(! cin)//如果输入流出错,即在输入坐标的时候输入了错误的数据 { cin.clear();//清楚输入流的错误状态 cin.sync();//清空输入流缓冲区 cout<<"请输入要移动的位置坐标X和Y: "; cin>>x>>y; } if(move(x,y,d))//如果是有效移动 { system("cls");//清空屏幕 print();//显示移动后的地图 Sleep(1000);//程序停顿等待1000毫秒,也就是1秒 disappear();//消除宝石 } else { cout<<"移动是无效的,移动失败"; Sleep(1000);//停顿1000毫秒 } returntrue; } intmain() { srand(static_cast CGamegame; while(game.Run());//Run返回值为false表示退出游戏,为true表示正在游戏 return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 宝石迷阵 c+ 宝石 迷阵