2048小游戏——C++命令行版本

今天下午闲来无事,于是就想练练手做点小玩意,最后决定做一个2048小游戏,并不想涉及GUI的编程,感觉可能会费很多时间,于是只是做了一个简单的命令行版本,采用的编程语言是C++语言。

2048小游戏的原理还是挺简单的,下面就直接贴出代码,主体代码部分都有注释。

/*****************************************
2048小游戏,无聊做着玩一玩,这是C++版本
制作者:UnderSunshine
时间:2017年1月21日
适用操作系统:Windows系统
******************************************/
#include<iostream>
#include<ctime>
#include<stdlib.h>
#include<windows.h>

using namespace	std;
//游戏的三种状态
int GAMEOVER = 0;//游戏失败,失败条件是棋盘被占满,无法继续消除下去,且没有2048
int WIN = 1;//游戏胜利,胜利条件为得到2048
int CONTINUE = 2;//游戏可以继续
//游戏所用的游戏盘大小为4*4
int const ROW = 4;
int const COLUMN = 4;
//初始化4个方向的数字值
int const UP = 1;
int const LEFT = 2;
int const RIGHT = 3;
int const DOWN = 4;

class GAME_2048{
	public:
		int GAME[ROW][COLUMN];//初始化整个游戏盘
		GAME_2048(){//构造函数
			for(int i = 0;i<ROW;i++){
				for(int j = 0;j<COLUMN;j++){
					GAME[i][j] = 0;
				}
			}
			Create_num();
			Create_num();
			Show();
		}
		int Play_Game(int input){
			play(input);
			Create_num();
			Show();
			if(Find_Max()==2048) return WIN;
			//纵向检查
			for(int i=0;i<ROW;i++){
				for(int j=0;j<COLUMN-1;j++){
					if(GAME[i][j]==GAME[i][j+1]||GAME[i][j]==0)
						return CONTINUE;
				}
			}
			for(int k = 0;k<ROW;k++)
				if(GAME[k][COLUMN-1]==0) return CONTINUE;
			//横向检查
			for(int j=0;j<COLUMN;j++){
				for(int i=0;i<ROW-1;i++){
					if(GAME[i][j]==GAME[i+1][j]||GAME[i][j]==0)
						return CONTINUE;
				}
			}
			for(int k = 0;k<COLUMN;k++)
				if(GAME[ROW-1][k]==0) return CONTINUE;
			
			return GAMEOVER;
		}
		
	private:
		void play(int input){
			switch(input){
				case UP:
					//先将同列的上一行中0位置都填满
					for(int i = 0;i<ROW-1;i++){//最后一行不用检查
						for(int j = 0;j<COLUMN;j++){
							if(GAME[i][j]==0){
								for(int k = i+1;k<ROW;k++){//用下一行中第一个非0数字来填补
									if(GAME[k][j]!=0){
										GAME[i][j]=GAME[k][j];
										GAME[k][j]=0;
										break;
									}
								}
							}
						}		
					}
					//将有相同的数字进行相加
					for(int i = 1;i<ROW;i++){
						for(int j = 0;j<COLUMN;j++){
							if(GAME[i][j] == GAME[i-1][j] || GAME[i-1][j]==0){
								GAME[i-1][j] += GAME[i][j];
								GAME[i][j]=0;
							}
						}
					}
					break;
					
				case DOWN:	
					//先将同列的下一行中0位置都填满
					for(int i = ROW-1;i>0;i--){//第一行不用检查
						for(int j = 0;j<COLUMN;j++){
							if(GAME[i][j]==0){
								for(int k = i-1;k>0;k--){//用下一行中第一个非0数字来填补
									if(GAME[k][j]!=0){
										GAME[i][j]=GAME[k][j];
										GAME[k][j]=0;
										break;
									}
								}
							}
						}		
					}
					//将有相同的数字进行相加
					for(int i = ROW-2;i>=0;i--){
						for(int j = 0;j<COLUMN;j++){
							if(GAME[i][j] == GAME[i+1][j] || GAME[i+1][j]==0){
								GAME[i+1][j] += GAME[i][j];
								GAME[i][j]=0;
							}
						}
					}
					break;
					
				case LEFT:
					//先将左边0项都补0,最右边一行无需补充
					for(int j = 0;j<COLUMN-1;j++){
						for(int i = 0;i<ROW;i++){
							if(GAME[i][j] == 0){
								for(int k = j+1;k<COLUMN;k++)
									if(GAME[i][k]!=0){
										GAME[i][j] = GAME[i][k];
										GAME[i][k] = 0;
										break;
									} 
							}
							
						}
					}
					//将有相同的数字进行相加
					for(int j = 1;j<COLUMN;j++){
						for(int i = 0;i<ROW;i++){
							if(GAME[i][j]==GAME[i][j-1] || GAME[i][j-1]==0){
								GAME[i][j-1] += GAME[i][j];
								GAME[i][j] = 0;
							}
						}
					}
					break;
					
				case RIGHT:
					//先将右边0项都补0,最左边一行无需补充
					for(int j = COLUMN-1;j>0;j--){
						for(int i = 0;i<ROW;i++){
							if(GAME[i][j] == 0){
								for(int k = j-1;k>=0;k--)
									if(GAME[i][k]!=0){
										GAME[i][j] = GAME[i][k];
										GAME[i][k] = 0;
										break;
									} 
							}
							
						}
					}
					//将有相同的数字进行相加
					for(int j = COLUMN-2;j>=0;j--){
						for(int i = 0;i<ROW;i++){
							if(GAME[i][j]==GAME[i][j+1] || GAME[i][j+1]==0){
								GAME[i][j+1] += GAME[i][j];
								GAME[i][j] = 0;
							}
						}
					}
					break;
			}
		}
		
		//搜索当前的最大值,看是否已经获得2048
		int Find_Max(){
			int max = 0;
			for(int i = 0;i<ROW;i++){
				for(int j = 0;j<COLUMN;j++){
					if(max<GAME[i][j]) max = GAME[i][j];
				}
			}
			return max;
		}
		
		//显示棋盘界面,以便了解游戏情况
		void Show(){
			system("cls");  
			cout << "*****************  2048小游戏  ******************" << endl<<endl;  
			for (int i = 0; i < ROW; ++i)  
			{  
				cout << "---------------------------------"<< endl;  
				for (int j = 0; j < COLUMN; ++j)  
				{  
					if (GAME[i][j] == 0)  
					{  
						cout <<"|   \t";  
					}  
					else   
					{  
						cout <<"|   " << GAME[i][j] << "\t";  
					}  
				}  
				cout << "|" << endl;  
			}  
			cout << "---------------------------------"<< endl;
			
		}
		//4/5的概率生成2,1/5的概率生成4
		int random(){
			srand(unsigned(time(0)));
			if(rand()%10+1<8)
				return 2;
			else return 4;
		}
		
		//随机选择一个位置放置新数字2或4
		bool Create_num(){
			int _2_or_4 = random();
			int x = rand()%ROW;
			int y = rand()%COLUMN;
			//总的可以寻找的次数
			int TOTAL_POSITION = ROW*COLUMN;
			//记录寻找的位置的次数
			int POSITION = 0;
			//寻找插入新数字的位置
			while(GAME[x][y] != 0 && POSITION<=TOTAL_POSITION){
				++y;
				if(y >= COLUMN){
					y=0;
					++x;
					if(x >= ROW)
						x = 0;
				}
				POSITION++;
			}
			//证明已经满了,无法插入新数字
			if(POSITION>=TOTAL_POSITION) return false;
			//插入新数字
			else GAME[x][y] = _2_or_4;
			return true;
		}
		
};


int main(){
	int s = CONTINUE;
	int input;
	GAME_2048 game;
	char c;
	bool flag_check = false;//检查是否输入错误的指令
	while(s == CONTINUE){
		cin>>c;
		switch(c){
			case 'w': input = UP;break;
			case 's': input = DOWN;break;
			case 'a': input = LEFT;break;
			case 'd': input = RIGHT;break;
			default : cout<<"请输入正确的方向,分别为w(UP),DOWN(s),LEFT(a),RIGHT(d)"<<endl;flag_check = true;break;//检查是否输入错误的指令
		}
		if(flag_check){
			flag_check = false;
			continue;
		}
		s = game.Play_Game(input);
	}
	if(s == WIN)
		cout<<"恭喜你,游戏胜利";
	else
		cout<<"很遗憾,游戏失败";
	return 1;
}

运行结果如下:

输入w表示向上


向上指令输出后的结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值