2048 C++源代碼 By CR

一直想寫2048這個遊戲,前幾天看到了這篇博文,給了我很大的啓示,也學習到了不少。ios

一、使用conio.h裏的_getch()來讀取方向鍵;windows

二、system()這個函數的妙用,之前一直看到別人用system("pause")來暫停程序,歷來沒有深究過,原來system這個函數就是能夠向CMD裏發送指令啊;dom

三、srand()的使用,你們能夠百度一下srand和rand()的區別。函數

不過他的遊戲規則是偏Threes!的,和我一開始玩的2048有很大不一樣,主要區別在於2048每次移動都是一次到底,而Threes!是每次只移動一格。學習

因而我就試着在他的基礎上本身寫了一個,如今分享給你們。字體

主要修改了移動的函數,和增長隨機數的函數。spa


4.11日更新了字體顏色,如今每種數字能夠顯示不一樣的顏色了.net

/*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;
}
相關文章
相關標籤/搜索