1. 程式人生 > >C++小遊戲之2048

C++小遊戲之2048

#include<iostream>
#include<ctime>
using namespace std;
int map[4][4] = { 0 };		//因為2048是一個4X4的小方塊集合,所以定義一個二維陣列與之對應
void print();				//列印數組裡的數字
int random_num();			//產生隨機數字4和2,產生機率為1:9
void random_place();			//在為數值為0的區域隨機產生數字
void moveUp();			//向上移動
void moveDown();		//向下移動
void moveLeft();		//向左移動
void moveRight();		//向右移動

void main() {
	char ch;
	random_place();	//開始時,隨機兩個位置產生2或4
	random_place();
	while (1) {
		system("cls");
		print();
		cin >> ch;
		switch (ch) {
		case 'w':moveUp(); break;
		case 's':moveDown(); break;
		case 'a':moveLeft(); break;
		case 'd':moveRight(); break;
		case 'p':exit(0); break;
		default:cout << "輸入錯誤,請重新輸入!" << endl; break;
		}
	}
	system("pause");
}
void print() {
	cout << "************************************************" << endl;
	cout << "*     " << map[0][0] << "       	 " << map[0][1] << "           " << map[0][2] << "      	  " << map[0][3] << "    *" << endl;
	cout << "************************************************" << endl;
	cout << "*     " << map[1][0] << "       	 " << map[1][1] << "           " << map[1][2] << "      	  " << map[1][3] << "    *" << endl;
	cout << "************************************************" << endl;
	cout << "*     " << map[2][0] << "       	 " << map[2][1] << "           " << map[2][2] << "      	  " << map[2][3] << "    *" << endl;
	cout << "************************************************" << endl;
	cout << "*     " << map[3][0] << "       	 " << map[3][1] << "           " << map[3][2] << "      	  " << map[3][3] << "    *" << endl;
	cout << "************************************************" << endl;
	cout << "操作詳情:(輸入後,按回車鍵結束)" << endl;
	cout << "w :	向上移動		s :		向下移動" << endl;
	cout << "a :	向左移動		s :		向右移動" << endl;
	cout << "p :	退出" << endl;
}
int random_num() {
	srand((unsigned int)time(NULL));	//隨機數
	int num = rand() % 10;
	return num < 1 ? 4 : 2;
}

void random_place() {
	int row, col;
	row = rand() % 4;
	col = rand() % 4;
	while (map[row][col] != 0) {
		row = rand() % 4;
		col = rand() % 4;
	}
	map[row][col] = random_num();
}

void moveUp() {			//進行緊湊將數字上移,相加,再一次進行緊湊
	int flag, temp;
	//進行緊湊(偶數上移,數字0下移)	
	/*思路是:對同列不同行的數字進行迴圈,當遇到第一個不為0的數字的時候,將該值的行數值賦給flag.在對flag進行回溯,目的是把非零數字上移*/
	for (int col = 0; col < 4; col++) {		
		for (int row = 0; row < 4; row++) {		
			if (map[row][col] != 0) {
				flag = row;
				while (flag != 0 && map[flag - 1][col] == 0) {			//第一項避免flag-1越界,第二項是當前一位置為零是才置換,否則不換
					temp = map[flag - 1][col];
					map[flag - 1][col] = map[flag][col];
					map[flag][col] = temp;
					flag--;
				}
			}
		}
	}
	for (int col = 0; col < 4; col++) {		//判斷當前數字與下一行同列的數字是否相等。如果相等該數字變為自身的兩倍,相鄰數字置為0
		for (int row = 0; row < 3; row++) {
			if (map[row][col] == map[row + 1][col]) {
				map[row][col] *= 2;
				map[row + 1][col] = 0;
			}
		}
	}
	for (int col = 0; col < 4; col++) {		//再一次進行緊湊(偶數上移,數字0下移)	
		for (int row = 0; row < 4; row++) {
			if (map[row][col] != 0) {
				flag = row;
				while (flag != 0 && map[flag - 1][col] == 0) {
					temp = map[flag - 1][col];
					map[flag - 1][col] = map[flag][col];
					map[flag][col] = temp;
					flag--;
				}
			}
		}
	}
	random_place();
}
void moveDown() {
	int flag, temp;
	//進行緊湊(偶數下移,數字0上移)	
	for (int col = 0; col < 4; col++) {
		for (int row = 3; row >= 0; row--) {
			if (map[row][col] != 0) {
				flag = row;
				while (flag != 3 && map[flag + 1][col] == 0) {			//第一項避免flag+1越界,第二項是當後一位置為零是才置換,否則不換
					temp = map[flag + 1][col];
					map[flag + 1][col] = map[flag][col];
					map[flag][col] = temp;
					flag++;
				}
			}
		}
	}
	for (int col = 0; col < 4; col++) {		
		for (int row = 3; row > 0; row--) {
			if (map[row][col] == map[row - 1][col]) {
				map[row][col] *= 2;
				map[row - 1][col] = 0;
			}
		}
	}
	for (int col = 0; col < 4; col++) {				//再一次進行緊湊(偶數下移,數字0上移)	
		for (int row = 3; row >= 0; row--) {
			if (map[row][col] != 0) {
				flag = row;
				while (flag != 3 && map[flag + 1][col] == 0) {			
					temp = map[flag + 1][col];
					map[flag + 1][col] = map[flag][col];
					map[flag][col] = temp;
					flag++;
				}
			}
		}
	}
	random_place();
}
void moveLeft() {
	int flag, temp;
	//進行緊湊(偶數左移,數字0右移)	
	for (int row = 0; row < 4; row++) {
		for (int col = 0; col < 4; col++) {
			if (map[row][col] != 0) {
				flag = col;
				while (flag != 0 && map[row][flag-1] == 0) {			//第一項避免flag-1越界,第二項是當前一位置為零是才置換,否則不換
					temp = map[row][flag - 1];
					map[row][flag - 1] = map[row][flag];
					map[row][flag] = temp;
					flag--;
				}
			}
		}
	}
	for (int row = 0; row < 4; row++) {		//判斷當前數字與下一列同行的數字是否相等。如果相等該數字變為自身的兩倍,相鄰數字置為0
		for (int col = 0; col < 3; col++) {
			if (map[row][col] == map[row][col+1]) {
				map[row][col] *= 2;
				map[row][col+1] = 0;
			}
		}
	}
	for (int row = 0; row < 4; row++) {		//再一次進行緊湊(偶數左移,數字0右移)	
		for (int col = 0; col < 4; col++) {
			if (map[row][col] != 0) {
				flag = col;
				while (flag != 0 && map[row][flag-1] == 0) {		
					temp = map[row][flag - 1];
					map[row][flag - 1] = map[row][flag];
					map[row][flag] = temp;
					flag--;
				}
			}
		}
	}
	random_place();
}
void moveRight() {
	int flag, temp;
	//進行緊湊(偶數右移,數字0左移)	
	for (int row = 0; row < 4; row++) {
		for (int col = 3; col >= 0; col--) {
			if (map[row][col] != 0) {
				flag = col;
				while (flag != 3 && map[row][flag+1] == 0) {			//第一項避免flag+1越界,第二項是當後一位置為零是才置換,否則不換
					temp = map[row][flag + 1];
					map[row][flag + 1] = map[row][flag];
					map[row][flag] = temp;
					flag++;
				}
			}
		}
	}
	for (int row = 0; row < 4; row++) {		
		for (int col = 3; col > 0; col--) {
			if (map[row][col] == map[row][col - 1]) {
				map[row][col] *= 2;
				map[row][col - 1] = 0;
			}
		}
	}
	for (int row = 0; row < 4; row++) {		//再一次進行緊湊(偶數右移,數字0左移)	
		for (int col = 3; col >= 0; col--) {
			if (map[row][col] != 0) {
				flag = col;
				while (flag != 3 && map[row][flag+1] == 0) {			
					temp = map[row][flag + 1];
					map[row][flag + 1] = map[row][flag];
					map[row][flag] = temp;
					flag++;
				}
			}
		}
	}
	random_place();
}