一直想写2048这个游戏,前几天看到了这篇博文,给了我很大的启示,也学习到了很多。
1、使用conio.h里的_getch()来读取方向键;
2、system()这个函数的妙用,以前一直看到别人用system("pause")来暂停程序,从来没有深究过,原来system这个函数就是可以向CMD里发送指令啊;
3、srand()的使用,大家可以百度一下srand和rand()的区别。
不过他的游戏规则是偏Threes!的,和我一开始玩的2048有很大不同,主要区别在于2048每次移动都是一次到底,而Threes!是每次只移动一格。
于是我就试着在他的基础上自己写了一个,现在分享给大家。
主要修改了移动的函数,和增加随机数的函数。
4.11日更新了字体颜色,现在每种数字可以显示不同的颜色了
/*By Cr*/
#include<iostream>
#include<iomanip>
#include<stdlib.h>
#include<time.h>
#include<conio.h> //为了读取方向键
#include<windows.h>
#include<vector>
#define BACKGROUND_WHITE BACKGROUND_RED|BACKGROUND_BLUE|BACKGROUND_GREEN|BACKGROUND_INTENSITY
using namespace std;
class Point{
private:
int x;
int y;
public:
Point(int x1,int y1)
{
x = x1;
y = y1;
}
int getx(){
return x;
}
int gety(){
return y;
}
};
int pane[4][4]; //棋盘
int N=1; //2的n次方
void addrandomnumber()
{
vector <Point*> *emptyPoint = new vector<Point*>();
/*
先把所有为零的位置存起来
*/
for(int x = 0;x<4;x++)
for(int y = 0; y<4;y++)
if(pane[x][y]<=0) emptyPoint->push_back(new Point(x,y));
/*
再随机取出一个位置,并将2或者4随机存入其中,
*/
if(emptyPoint->size()>0)
{
srand((unsigned)time( NULL ));
Point *p = *(emptyPoint->begin()+rand()%emptyPoint->size());
pane[p->getx()][p->gety()] = rand()/(double)(RAND_MAX)>0.1?2:4;
//cout<<emptyPoint->size()<<endl;
}
delete emptyPoint;
}
void SetColor(int a)
{
HANDLE outPutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
switch(a)
{
case 2:
SetConsoleTextAttribute(outPutHandle,FOREGROUND_BLUE|BACKGROUND_WHITE);
break;
case 4:
SetConsoleTextAttribute(outPutHandle,FOREGROUND_BLUE|BACKGROUND_WHITE);
break;
case 8:
SetConsoleTextAttribute(outPutHandle,FOREGROUND_BLUE|FOREGROUND_INTENSITY|BACKGROUND_WHITE);
break;
case 16:
SetConsoleTextAttribute(outPutHandle,FOREGROUND_BLUE|FOREGROUND_INTENSITY|BACKGROUND_WHITE);
break;
case 32:
SetConsoleTextAttribute(outPutHandle,FOREGROUND_GREEN|BACKGROUND_WHITE);
break;
case 64:
SetConsoleTextAttribute(outPutHandle,FOREGROUND_GREEN|BACKGROUND_WHITE);
break;
case 128:
SetConsoleTextAttribute(outPutHandle,FOREGROUND_GREEN|FOREGROUND_INTENSITY|BACKGROUND_WHITE);
break;
case 256:
SetConsoleTextAttribute(outPutHandle,FOREGROUND_GREEN|FOREGROUND_INTENSITY|BACKGROUND_WHITE);
break;
case 512:
SetConsoleTextAttribute(outPutHandle,FOREGROUND_RED|BACKGROUND_WHITE);
break;
case 1024:
SetConsoleTextAttribute(outPutHandle,FOREGROUND_RED|BACKGROUND_WHITE);
break;
case 2048:
SetConsoleTextAttribute(outPutHandle,FOREGROUND_RED|FOREGROUND_INTENSITY|BACKGROUND_WHITE);
break;
default:
SetConsoleTextAttribute(outPutHandle,FOREGROUND_BLUE|BACKGROUND_WHITE);
break;
}
cout<<setw(4)<<a;
}
void showpane() //显示棋盘
{
cout<<setw(46)<<"X2048 by CR"<<endl;
cout<<setw(50)<<" |-----------------------|"<<endl;
for(int i=0;i<=3;i++)
{
cout<<setw(24)<<"";
for(int j=0;j<=3;j++)
{
//SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED);
cout<<setw(2)<<"|";
SetColor(pane[i][j]);
if(j==3)
{
cout<<setw(2)<<"|"<<endl;
cout<<setw(50)<<" |-----------------------|"<<endl;
}
}
}
}
void newgame() //开始游戏
{
N=1;
for(int i=0;i<=3;i++) //初始化棋盘
for(int j=0;j<=3;j++)
pane[i][j]=0;
addrandomnumber();
addrandomnumber();
showpane();
}
void upmove() //上移
{
bool merge = false;
for(int y=0;y<4;y++)
{
for(int x=0;x<4;x++)
{
for(int x1=x+1;x1<4;x1++)
{
if(pane[x1][y]>0)
{
if(pane[x][y]<=0){
pane[x][y] = pane[x1][y];
pane[x1][y] = 0;
x--;
merge = true;
}
else if(pane[x][y]==pane[x1][y])
{
pane[x][y] = pane[x][y]*2;
pane[x1][y] = 0;
merge = true;
}
break;
}
}
}
}
if(merge == true)
{
addrandomnumber();
}
}
void downmove() //下移
{
bool merge = false;
for(int y=0;y<4;y++)
{
for(int x=3;x>=0;x--)
{
for(int x1=x-1;x1>=0;x1--)
{
if(pane[x1][y]>0)
{
if(pane[x][y]<=0){
pane[x][y] = pane[x1][y];
pane[x1][y] = 0;
x++;
merge = true;
}
else if(pane[x][y]==pane[x1][y])
{
pane[x][y] = pane[x][y]*2;
pane[x1][y] = 0;
merge = true;
}
break;
}
}
}
}
if(merge == true)
{
addrandomnumber();
}
}
void leftmove() //左移
{
bool merge = false;
for(int x=0;x<4;x++)
{
for(int y=0;y<4;y++)
{
for(int y1=y+1;y1<4;y1++)
{
if(pane[x][y1]>0)
{
if(pane[x][y]<=0){
pane[x][y] = pane[x][y1];
pane[x][y1] = 0;
y--;
merge = true;
}
else if(pane[x][y]==pane[x][y1])
{
pane[x][y] = pane[x][y]*2;
pane[x][y1] = 0;
merge = true;
}
break;
}
}
}
}
if(merge == true)
{
addrandomnumber();
}
}
void rightmove() //右移
{
bool merge = false;
for(int x=0;x<4;x++)
{
for(int y=3;y>=0;y--)
{
for(int y1=y-1;y1>=0;y1--)
{
if(pane[x][y1]>0)
{
if(pane[x][y]<=0){
pane[x][y] = pane[x][y1];
pane[x][y1] = 0;
y++;
merge = true;
}
else if(pane[x][y]==pane[x][y1])
{
pane[x][y] = pane[x][y]*2;
pane[x][y1] = 0;
merge = true;
}
break;
}
}
}
}
if(merge == true)
{
addrandomnumber();
}
}
int panemax() //棋盘最大数
{
int max=pane[0][0];
for(int i=0;i<=3;i++)
for(int j=0;j<=3;j++)
if(pane[i][j]>max)
max=pane[i][j];
return max;
}
int ifwin() //判断是否胜利
{
int flag=0;
if(panemax()==2048)
{
cout<<setw(45)<<"You Win!"<<endl;
flag=1;
}
return flag;
}
int ifGameOver() //判断是否游戏结束
{
int flag=1;
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
if (pane[x][y]==0||
(x>0&&pane[x][y]==pane[x-1][y])||
(x<4-1&&pane[x][y]==pane[x+1][y])||
(y>0&&pane[x][y]==pane[x][y-1])||
(y<4-1&&pane[x][y]==pane[x][y+1])) {
flag = 0;
return flag;
}
}
}
return flag;
}
int GetDirection() //读取方向
{
int ret = 0;
do
{
int ch = _getch();
if(isascii(ch))
continue;
ch = _getch();
switch(ch)
{
case 72:
ret = 2; // top
break;
case 75:
ret = 1; // left
break;
case 77:
ret = 3; // right
break;
case 80:
ret = 4; // down
break;
default:
break;
}
} while (ret == 0);
return ret;
}
int main() //主函数
{
system("color f9");
int makesure=1;
while(makesure)
{
system("cls");
newgame();
//showpane();
while(ifwin()+ifGameOver()==0)
{
int c=GetDirection();
switch(c)
{
case 2:
upmove();
//addrandomnumber();
system("cls");
showpane();
break;
case 4:
downmove();
//addrandomnumber();
system("cls");
showpane();
break;
case 1:
leftmove();
//addrandomnumber();
system("cls");
showpane();
break;
case 3:
rightmove();
//addrandomnumber();
system("cls");
showpane();
break;
default:
break;
}
}
cout<<setw(43)<<"你的最后成绩为:"<<panemax()<<endl;
cout<<setw(60)<<"若要重新开始游戏请输入1,若要结束请输入0。"<<endl;
cin>>makesure;
while(makesure!=1&&makesure!=0)
{
cout<<"输入不正确,请重新输入!"<<endl;
cin>>makesure;
}
}
cout<<"再见!"<<endl;
return 0;
}