用C++ 写控制台版本2048小游戏(不闪烁)

2048 游戏思路

游戏逻辑

  • 游戏类结构设计
class Game
{

public:
	int Scroe = 0;//初始分数 
	bool ADD = false;//是否添加棋子
	int BoardList[4][4] = { 0 };
	string Tips;

	Game();
	void Print(); //打印棋盘
	bool Input();//获取输入
	bool AddBoard();//添加棋子
	void Up();//上下左右按键事件,都类似,以左按键为母版
	void Down();
	void Right();
	void Left();
	void Restart();//复位
	void RUN();
	void Delay(int msec);
	bool WIN();//判断是否赢了
	bool LOSE();//判断是否输了
};
  • 首先一个,棋盘,N×N,就选4×4
  • 有数字的显示数字,没有数字用0表示,便于后续实现(可以用空位“ ”)表示, 不过在C++里,存储空位信息又要用别结构,list或者array,vector等,感觉不如用0来的实在,python的话就用列表就很方便了。
  • 打印棋盘后,首先随机选取两个位置,添加2 或4.,后续按键后也要添加一个2或者4,于是专门写一个函数bool AddBoard();//添加棋子
  • (核心)然后按键,进行移动。
    • 四个方向,其实都是相通的,左移的逻辑比较好想,以左移为模板实现
    • 例如4 0 2 0 和 4 2 2 4 ,分为三步:1、4 0 2 0 ->4 2 0 0 4
      4 2 2 4 ->4 2 2 4,也就是把0的位置移动,把非0元素移动到左边并且相邻。
for (size_t t = 0; t < size(this->BoardList); t++)
		{
			for (size_t i = 0; i < size(this->BoardList[t]) - 1; i++)
			{
				// 0 2 0 2 ->2 0 2 0
				if (this->BoardList[j][i] == 0)
				{
					// 发生了移动,添加棋子标志位置真
					if (this->BoardList[j][i + 1]!=0)
					{
						this->ADD = true;
					}
					auto temp = this->BoardList[j][i];
					this->BoardList[j][i] = this->BoardList[j][i + 1];
					this->BoardList[j][i + 1] = temp;
				}
			}
		}

注意,这是移动一行的代码,最坏的情况0 0 0 2 ,要移动三次(N-1)才能变成2 0 0 0 ,所以我用了四次(N)。

  • 然后,合并同项,
for (size_t i = 0; i < size(this->BoardList[j]) - 1; i++)
		{
			// 2 2 2 2 ->4 0 2 2 ->4 0 4 0 
			// 2 2 2 0 -> 4 0 2 0 
			if (this->BoardList[j][i]== this->BoardList[j][i+1])
			{
				// 发生了合并,添加棋子标志位置真
				if (this->BoardList[j][i]!=0)
				{
					this->ADD = true;
				}
				this->BoardList[j][i] = this->BoardList[j][i] * 2;
				this->Scroe = this->BoardList[j][i] + this->Scroe;
				this->BoardList[j][i + 1] = 0;
			}
		}
  • 合并后 4 2 2 4 -》4 4 0 4 ,又出现了0,所以再来一次,移动0元素到右边。代码不在赘述。
  • 核心设计好了,其他的就容易, 后面就是判断输赢
    • 数组中出现2048,就赢了,很简单,遍历数组就ok。
bool Game::WIN()
{
	for (size_t i = 0; i < size(this->BoardList); i++)
	{
		for (size_t j = 0; j < size(this->BoardList[0]); j++)
		{
			//出现2048,即为赢
			if (this->BoardList[i][j]==2048)
			{
				&this->Tips.assign("YOU WIN !!!");
				return true;
			}
			else
			{
				return false;
			}
		}
	}
	return false;
}
  • 如果棋盘满了,数组中没有0元素了,而且任意位置都和相邻元素不相等了,就输了。

最后是显示运行

  • 用while语句死循环,不断刷新

用到的组件

  • 获取输入组件,可以用cin 获取,但是每次必须输入回车确定,这里用的_getch()函数,不用回车
  • 当然也带来了一个问题,用cin的话,回车后刷新屏幕,但是用_getch(),自动刷新屏幕,有一个屏闪问题,当然后来用双缓冲解决了。
  • 控制台组件,这只控制台的颜色字体等。
  • 最后加入了程序图标

效果展示

2048

  • 不闪屏
    效果,不闪屏
    完整代码:https://github.com/luqiankun/2048
    另附python版本2048:https://github.com/luqiankun/Python2048
    欢迎大家交流指正。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值