【小游戏】C++打造2048控制台版本

翻了一下以前的代码,发现去年国庆写的2048有点意思,于是搬过来纪念一下

#include<iostream>
#include<cstdio>
#include<time.h>
#include<cstdlib>
#include <conio.h>//kbhit()函数
//宏定义----------------------------------------------------------
#define JUG_empty 1//juge结果
#define JUG_merge 2//juge结果
#define JUG_collision 3//juge结果
#define JUG_nonum 4//juge结果

#define MOV_empty 1//move类型匹配
#define MOV_merge 2//move类型匹配
#define MOV_noaction 3//move类型匹配
#define MOV_auto 4//move类型匹配

//命名空间声明----------------------------------------------------
using namespace std;
//自定义数据类型--------------------------------------------------
enum n_dir {Left,Right,Up,Down};
//方向类型

//函数声明--------------------------------------------------------
int Move(n_dir dir,int move=1);//返回MOV_类型的结果。move表示是否移动
//块移动
int Random(int min,int max);
//取随机整数
void StartScr();
//开始界面
void GameScr();
//游戏界面
void prinum(int);
//按照固定大小打印数字
int Juge(short &num,short &des,short move = MOV_auto);
//块移动
void Welcome();
//欢迎界面
void Padding(int);
//空格填充
//全局变量--------------------------------------------------------
short wide=4,hight=4,//区域大小考虑到可选择性,所以用了变量,默认为4×4区域
		*map;//区域
unsigned grade=0;

//
int main()
{
	srand((unsigned)time(NULL));//置随机数种子

	//---------------------欢迎界面---------------------
    Welcome();

	//---------------------开始界面---------------------
	StartScr();

	return 0;
}
void prinum(int a)
{
	//这里只考虑最大数字为四位数的所以块大小是1×4的长方形
	int len=0,leftblank,b=a;
	while(b)
	{
		len++;
		b/=10;
	}
	leftblank=(4-len)/2;
	int i;
	for(i=1;i<=leftblank;i++)
		putchar(' ');
	cout<<a;
	for(i=1;i<=4-len-leftblank;i++)
		putchar(' ');
}
int Random(int min,int max)
{
	return rand()%(max-min+1)+min;
}
void StartScr()
{


	//---------------------开始游戏---------------------
	//以下将一维数组二维化:[i][j]=[i*wide+j]
	map = new short [wide*hight];//设置区域大小
	grade=0;//分数归零
	for(int i=0;i<hight;i++)
	{
		for(int j=0;j<wide;j++)
		{
			map[i*wide+j]=-1;//无数的标志
		}
	}
	map[Random(0,wide*hight-1)]=2;//map记录数值
	GameScr();
	delete []map;
}
void GameScr()
{
	int key1,key2,result;
				system("cls");//清屏
			int i=0;
			cout<<"---------";
			prinum(grade);
			cout<<"----------"<<endl;
			for(i=0;i<=wide;i++)
				cout<<"----";
			cout<<"----"<<endl;
			for(i=0;i<wide*hight;i++)
			{
				if(i%wide==0)
					cout<<"|   ";
				if(map[i]==-1)
					cout<<"    ";
				else
					prinum(map[i]);
				if((i+1)%wide==0)
					cout<<"   |"<<endl;//行尾
			}
			for(i=0;i<=wide;i++)
				cout<<"-----";
	while(1)
	{
		if(kbhit())//当键盘被按下
		{
			key1=getch();
			if(key1==224)//方向键
			{
				key2=getch();//键值
				if(key2==72)//上
					result=Move(Up);
				else if(key2==80)//下
					result=Move(Down);
				else if(key2==75)//左
					result=Move(Left);
				else if(key2==77)//右
					result=Move(Right);
			}
			else //数字键
			{
				if(key1=='w'||key1=='W')//上
					result=Move(Up);
				else if(key1=='s'||key1=='S')//下
					result=Move(Down);
				else if(key1=='a'||key1=='A')//左
					result=Move(Left);
				else if(key1=='d'||key1=='D')//右
					result=Move(Right);
			}
			//---------------------刷新显示---------------------
			system("cls");//清屏
			int i=0;
			cout<<"---------";
			prinum(grade);
			cout<<"----------"<<endl;
			for(i=0;i<=wide;i++)
				cout<<"----";
			cout<<"----"<<endl;
			for(i=0;i<wide*hight;i++)
			{
				if(i%wide==0)
					cout<<"|   ";
				if(map[i]==-1)
					cout<<"    ";
				else
					prinum(map[i]);
				if((i+1)%wide==0)
					cout<<"   |"<<endl;//行尾
			}
			for(i=0;i<=wide;i++)
				cout<<"-----";


			if(Move(Up,0)==MOV_noaction && Move(Down,0)==MOV_noaction && Move(Left,0)==MOV_noaction && Move(Right,0)==MOV_noaction)
			{
				//已经不能移动了
				cout<<endl<<"----------GameOver----------"<<endl;
			}


		}
	}
}
int Move(n_dir dir,int move)
{
	int i,j,k,num,des,result,count,moveresult=MOV_noaction;
	short *list;
	if(dir == Up)
	{
		list = new short [hight];//记录合并位置
		for(j=0;j<wide;j++)
		{
			count=0;
			for(i=1;i<hight;i++)//行上移
			{
				if(map[i*wide+j]!=-1)
				{
					num=i;
					des=i-1;
					while(1)//跳过空位置
					{
						result=Juge(map[num*wide+j],map[des*wide+j],MOV_noaction);//返回判断结果
						if(result == JUG_empty)//判断为空位置
						{

								moveresult=MOV_empty;
							if(move)
								Juge(map[num*wide+j],map[des*wide+j]);//移到空位置
							des--;
							num--;
							if(des<0)//目标超界跳出
								break;
							continue;
						}
						else if(result == JUG_merge)//结果为合并
						{
							for(k=0;k<count;k++)
								if(des==list[k])//目标位置已经被合并过了
									goto up_out;

								moveresult=MOV_merge;
							if(move)
							{
								grade+=map[num*wide+j];
								Juge(map[num*wide+j],map[des*wide+j]);//合并
								list[count++]=des;//记录合并位置
							}
							up_out:
							break;
						}
						else
							break;

					}
				}
			}
		}
		delete []list;
	}
	else if(dir == Down)
	{
		list = new short [hight];//记录合并位置
		for(j=0;j<wide;j++)
		{
			count=0;
			for(i=hight-2;i>=0;i--)//行下移
			{
				if(map[i*wide+j]!=-1)
				{
					num=i;
					des=i+1;
					while(1)//跳过空位置
					{
						result=Juge(map[num*wide+j],map[des*wide+j],MOV_noaction);//返回判断结果
						if(result == JUG_empty)//判断为空位置
						{

								moveresult=MOV_empty;
							if(move)
							Juge(map[num*wide+j],map[des*wide+j]);//移到空位置
							des++;
							num++;
							if(des>hight-1)//目标超界跳出
								break;
							continue;
						}
						else if(result == JUG_merge)//结果为合并
						{
							for(k=0;k<count;k++)
								if(des==list[k])//目标位置已经被合并过了
									goto down_out;

								moveresult=MOV_merge;

								if(move)
								{
									grade+=map[num*wide+j];
									Juge(map[num*wide+j],map[des*wide+j]);//合并
									list[count++]=des;//记录合并位置
								}
							down_out:
								break;
						}
						else
							break;

					}
				}
			}
		}
		delete []list;
	}
	else if(dir == Left)
	{
		list = new short [wide];//记录合并位置
		for(i=0;i<hight;i++)
		{
			count=0;
			for(j=1;j<wide;j++)//行左移
			{
				if(map[i*wide+j]!=-1)
				{
					num=j;
					des=j-1;
					while(1)//跳过空位置
					{
						result=Juge(map[i*wide+num],map[i*wide+des],MOV_noaction);//返回判断结果
						if(result == JUG_empty)//判断为空位置
						{
							moveresult=MOV_empty;
							if(move)
								Juge(map[i*wide+num],map[i*wide+des]);//移到空位置
							des--;
							num--;
							if(des<0)//目标超界跳出
								break;
							continue;
						}
						else if(result == JUG_merge)//结果为合并
						{
							for(k=0;k<count;k++)
								if(des==list[k])//目标位置已经被合并过了
									goto left_out;
							moveresult=MOV_merge;
								if(move)
								{
									grade+=map[i*wide+num];
									Juge(map[i*wide+num],map[i*wide+des]);//合并
									list[count++]=des;//记录合并位置
								}
							left_out:
								break;
						}
						else
							break;

					}
				}
			}
		}
		delete []list;
	}
	else if(dir == Right)
	{
		list = new short [wide];//记录合并位置
		for(i=0;i<hight;i++)
		{
			count=0;
			for(j=wide-2;j>=0;j--)//行左移
			{
				if(map[i*wide+j]!=-1)
				{
					num=j;
					des=j+1;
					while(1)//跳过空位置
					{
						result=Juge(map[i*wide+num],map[i*wide+des],MOV_noaction);//返回判断结果
						if(result == JUG_empty)//判断为空位置
						{
							moveresult=MOV_empty;
							if(move)
								Juge(map[i*wide+num],map[i*wide+des]);//移到空位置
							des++;
							num++;
							if(des<0)//目标超界跳出
								break;
							continue;
						}
						else if(result == JUG_merge)//结果为合并
						{
							for(k=0;k<count;k++)
								if(des==list[k])//目标位置已经被合并过了
									goto right_out;
							moveresult=MOV_merge;
								if(move)
								{
									grade+=map[i*wide+num];//加分
									Juge(map[i*wide+num],map[i*wide+des]);//合并
								list[count++]=des;//记录合并位置
								}
							right_out:
								break;
						}
						else
							break;

					}
				}
			}
		}
		delete []list;
	}
	if(move&&moveresult!=MOV_noaction)
	{
		int posi=Random(0,wide*hight-1);
		while(map[posi]!=-1)//保证是空位
			posi=Random(0,wide*hight-1);
		if(Random(1,8)<8)//2的几率:4的几率=8:1
			map[posi]=2;
		else
			map[posi]=4;
	}
	return moveresult;
}

int Juge(short &num,short &des,short move)//num一定不是-1
{

	if(des==-1)//目的地无数
	{
		if(move==MOV_auto||move==MOV_empty)
		{
			des=num;//数值转移
			num=-1;//置空
		}
		return JUG_empty;
	}
	else //目的地有数
	{
		if(num==des)//数值一样
		{
			if(move==MOV_auto||move==MOV_merge)
			{
				des+=num;//合并
				num=-1;//置空
			}
			return JUG_merge;
		}
		else
			return JUG_collision;
	}

}
//
//欢迎界面
//
void Welcome()
{
	Padding(-10);printf("欢迎来到2048!!!\n");
	Padding(-10);printf("上下左右为wsad键或方向键,感受这款经典游戏带来的快感吧!\n");
	system("pause");
}
//
//显示一定数量的空格
//参数1:相对偏移
void Padding(int shift)
{
	int total=20,i;
	total+=shift;
	for(i=0;i<total;i++)
	{
		putchar(' ');
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值