2048-控制台版本

2048控制台版

文章目录

实现效果:

库函数使用:

cpp 复制代码
#include<iostream>
#include<Windows.h>//键盘输入读取
#include<iomanip>//控制格式
#include<ctime>//生成随机数种子

初始化变量

cpp 复制代码
int const ROW = 4;
int const COL = 4;
int game[ROW][COL] = { 0};

int const GAME_CONTINUE = 1;
int const GAME_WIN = 2;
int const GAME_LOSE = 3;

int const UP = 1;
int const DOWN = 2;
int const LEFT = 3;
int const RIGHT = 4;

功能函数实现:

cpp 复制代码
int Judge();//判断游戏状态
bool CreateNumber();//生成下一个数
void Print();//打印初始化界面
void Process(int move);//实现移动效果
int Input();//读取键盘输入
bool is_Empty(int const a);//可不需要,判断某行谋列是否为0

状态判断函数int Judge();

设计思路:除去最后一行,逐行逐列的检查正下方和右方有无可以消去的元素

cpp 复制代码
int Judge() {
	int count = 0;
	for (int i = 0; i < ROW; i++) {
		for (int j = 0; j < COL; j++) {

			if (game[i][j] == 2024)
			{
				return GAME_WIN;
			}

			if (!is_Empty(game[i][j])) {
				count++;
				if (i == ROW - 1) {
					if (j != COL - 1&&(game[i][j]==game[i][j+1])) {
						count--;
					}
				}
				else {
					if (j != COL - 1) {
						if (game[i][j] == game[i][j + 1] || game[i][j] == game[i + 1][j]) {
							count--;
						}
					}
					else continue;
				}
			}
			
		}
	}
	if (count < ROW * COL)return GAME_CONTINUE;
	else return GAME_LOSE;
}

数字生成函数 bool CtreateNumber()

实际思路:rand生成随机数,通过非零情况控制生成2和4的概率

cpp 复制代码
bool CreateNumber() {
	/*int x =0;
	int y = 0;*/
	int x = -1;
	int y = -1;
	int times = 0,max_times=ROW*COL;//max_times防止满表的时候无限循环
	do {
		x = rand() % 4;
		y = rand() % 4;
		times++;
	} while (!is_Empty(game[x][y]) && times <= max_times);//有一个为0就跳出去

	//控制得到2和4的概率
	int value = rand() % 3;
	if (times > max_times) {
		return false;
	}
	else {
		if (value == 0)
			game[x][y] = 4;
		else
			game[x][y] = 2;
		return true;
	}
}

打印游戏界面 void Print()
cpp 复制代码
void Print() {
	system("cls");
	/*cout << setfill('=') << setw(5 * COL)<<'='<<endl ;*/
	cout << setfill('-') << setw(5 * COL) << '-' << endl;
	for (int i = 0; i < ROW; i++) {
		for (int j = 0; j < COL; j++) {
			if (is_Empty(game[i][j])) {
				cout <<'|' << setfill(' ')<<setw(4) << ' ';
			}
			else {
				cout << '|' << setfill(' ')<<setw(4) << game[i][j];
			}
		}
		cout << '|' << endl;
		cout <<setfill('-') << setw(5 * COL) << '-'<<endl ;
	}
}

操作函数void Process()

教训:第一次写的时候写了个count,用来记录上面一行(在UP中)的每一列是否都满足为空或者可以相消,这种操作是错的,因为只要可以相消或者只要有空位,就都应该可以往上走
ps:LEFT和Right的函数实现代码与UP和DOWN类似,把对应的col和row对调一下即可

cpp 复制代码
void Process(int move) {

	if (move == UP) {
		for (int row = 1; row < ROW; ++row) {
			for (int crow = row; crow >= 1; --crow) {
				for (int col = 0; col < COL; col++) {
					if (is_Empty(game[crow - 1][col])) {
						game[crow - 1][col] = game[crow][col];
						game[crow][col] = 0;
					}
					if (game[crow - 1][col] == game[crow][col]) {
						game[crow - 1][col] *= 2;
						game[crow][col] = 0;
					}
				}
			}
		}
	}

    if (move == DOWN) {
	//注意ROW-2指的是倒数第二排
	int count = 0;
	for (int row = ROW-2; row>=0; --row) {
		//crow<ROW-1
		for (int crow = row; crow < ROW-1; ++crow) {
			for (int col = 0; col < COL; col++) {
				if (is_Empty(game[crow + 1][col])) {
					game[crow + 1][col] = game[crow][col];
					game[crow][col] = 0;
				}
				else if(game[crow+1][col]==game[crow][col])
				{
					game[crow + 1][col] *= 2;
					game[crow][col] = 0;
				}
			}
		}
	}
}
}

键盘输入函数int Input()

说明:sleep函数是为了减少误触,降低敏感性

cpp 复制代码
int Input() {
	int directionUP = 0;
	int directionDOWN =0;
	int directionLeft = 0;
	int directionRight = 0;
	int direction = 0;

	while (true) {

		 directionUP = GetAsyncKeyState(VK_UP);
		 directionDOWN = GetAsyncKeyState(VK_DOWN);
		 directionLeft = GetAsyncKeyState(VK_LEFT);
	     directionRight = GetAsyncKeyState(VK_RIGHT);
		
		if (directionUP) {
			/*cout << "UP" << endl;*/
			direction= UP;
			break;
		}

		if (directionDOWN) {
			/*cout << "DOWN" << endl;*/
			direction= DOWN;
			break;
		}

		if (directionLeft) {
			
			/*cout << "LEFT"  << endl;*/
			direction= LEFT;
			break;
		}

		if (directionRight) {
			
			/*cout << "RIGHT" << endl;*/
			direction= RIGHT;
			break;
		}
		
		Sleep(100);
	}
	return direction;
}

主函数

cpp 复制代码
int main() {
	srand((unsigned int)time(0));
	CreateNumber();
	Print();
	while (true) {
		int gameState = Judge();
		int direction = Input();

		if ((direction)&&(gameState == GAME_CONTINUE)) {
			/*CreateNumber();
			Print();
			Process(direction);*/
			Process(direction);
			CreateNumber();
			Print();
			Sleep(100);//防止太敏感
		}

		else if (gameState == GAME_WIN) {
			Print();
			cout << "You Win" << endl;
			break;
		}

		else if (gameState == GAME_LOSE) {
			Print();
			cout << "Sorry,You Lose" << endl;
			break;
		}
	}
	return 0;
}

彩蛋:

如果时间足够,会再出有前端版本的实现代码!

相关推荐
知识分享小能手21 小时前
uni-app 入门学习教程,从入门到精通,uni-app基础扩展 —— 详细知识点与案例(3)
vue.js·学习·ui·微信小程序·小程序·uni-app·编程
●VON1 天前
重生之我在大学自学鸿蒙开发第九天-《分布式流转》
学习·华为·云原生·harmonyos·鸿蒙
无妄无望1 天前
docker学习(4)容器的生命周期与资源控制
java·学习·docker
Larry_Yanan1 天前
QML学习笔记(四十二)QML的MessageDialog
c++·笔记·qt·学习·ui
R-G-B1 天前
【35】MFC入门到精通——MFC运行 不显示对话框 MFC界面不显示
c++·mfc·mfc运行 不显界面·mfc界面不显示
能不能别报错1 天前
K8s学习笔记(十九) K8s资源限制
笔记·学习·kubernetes
Madison-No71 天前
【C++】探秘vector的底层实现
java·c++·算法
晚风残1 天前
【C++ Primer】第十二章:动态内存管理
开发语言·c++·c++ primer
十安_数学好题速析1 天前
倍数关系:最多能选出多少个数
笔记·学习·高考
vue学习1 天前
docker 学习dockerfile 构建 Nginx 镜像-部署 nginx 静态网
java·学习·docker