c语言实现简易2048游戏

我写的2048每次只能随机生成一个新的2,不能生成4以及其他的数,没有计分系统,只能记录步数。由于是基于控制台的游戏,所以操作起来比较麻烦。

算法思想:每次进行wsad操作的时候都先在各行各列检查可以合并的项,并且合并之,合并完之后在进行紧凑处理。

假如各行各列已经没有可以合并的相邻的项了,那么游戏就结束了。

#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>


//打印函数,打印出游戏界面
//如果是0的话就为空,否则打印出数值
void print(int a[4][4],int count) {
	for (int i = 0; i < 4; i++) {
		printf("  -- ");
	}
	printf("\n");
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 4; j++) {
			if (j == 0) {
				printf("|");
			}
			if (a[i][j] == 0) {
				printf("    |");
			}
			else {
				printf("%3d |", a[i][j]);
			}
		}
		printf("\n");
		for (int h = 0; h < 4; h++) {
			printf("  -- ");
		}
		printf("\n");
	}
	printf("请使用wsad进行游戏\n");
	printf("当前得分为:%d\n", count);
}

//为一开始生成随机的两个坐标
void start(int a[4][4]) {
	srand((unsigned)time(NULL));//用时间作为随机数的种子
	int x, y;
	x = rand() % 4;//x取值为0,1,2,3
	y = rand() % 4;//y取值也为0,1,2,3
	//printf("x=%d,y=%d\n", x, y);
	a[x][y] = 2;//一开始随机的数为2
	x = rand() % 4;
	y = rand() % 4;
	while (a[x][y] == 2) {
		x = rand() % 4;
		y = rand() % 4;
	}
	//printf("x=%d,y=%d\n", x, y);
	a[x][y] = 2;
	return;
}

//每一回合过后都随机生成一个新的2
void fresh(int a[4][4]) {
	srand((unsigned)time(NULL));
	int x, y;
	x = rand() % 4;
	y = rand() % 4;
	while (a[x][y] != 0) {
		x = rand() % 4;
		y = rand() % 4;
	}
	//printf("x=%d,y=%d\n", x, y);
	a[x][y] = 2;
	return;
}

//判断是否游戏结束
//游戏结束的标志就是无论从那个方向都没有可以合成的格子了
//算法就是先从行判断,然后从列判断
//如果游戏结束了就返回0,否则返回1
int is_die(int a[4][4]) {
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 3; j++) {
			if (a[i][j] == a[i][j + 1]) {
				//如果有相等的就是可以合成,游戏还没有结束
				return 1;
			}
			if (a[j][i] == a[j + 1][i]) {
				return 1;
			}
		}
	}
	//走到这一步就说明游戏结束了
	return 0;
}

int can(int a[4][4]) {
	return 1;
}

//主函数,通过输入来进行移动
//进行操作的时候分四种情况
//算法为:先检查有没有可以合并的格子,如果有就合并,然后再紧凑
void run(int a[4][4]) {
	char b;
	scanf_s("%c", &b);
	char c = getchar();
	switch (b) {
	case 'w':
		//上一操作
		for (int j = 0; j < 4; j++) {
			//j代表列
			for (int i = 3; i > 0; i--) {
				if (a[i][j] != 0) {
					//如果这个格子不等于零就检测能否合并
					for (int h = i - 1; h >= 0; h--) {
						if (a[h][j] != 0) {
							if (a[h][j] == a[i][j]) {
								//相等的话就合并,然后并到hj的格子里
								a[h][j] *= 2;
								a[i][j] = 0;
								//之后要忽略掉已经合并的格子
								i = h; //这里要特别注意一下,不知道是不是到了外层循环结束了之后自动给他减一
								break;
							}
							else {
								break;
							}
						}
					}
				}
			}
		}
			//这里要进行紧凑操作,逐行扫描
		for (int j = 0; j < 4; j++) {
			for (int k = 0; k < 3; k++) {
				//找到一个为0的格子之后把不为0的最近的格子值赋值上来,然后被赋值的格子变0
				//一直检查完为止,最后一行是不用检查的,因为最后一行为0也没有格子可以上移
				if (a[k][j] == 0) {
					//找最近的不为0的格子
					for (int l = k + 1; l < 4; l++) {
						if (a[l][j] != 0) {
							a[k][j] = a[l][j];
							a[l][j] = 0;
							break;
						}
					}
				}
			}
		}
		break;
	case 's':
		//下移操作,与上移操作行检查顺序相反,其他都一样
		for (int j = 0; j < 4; j++) {
			for (int i = 0; i < 3; i++) {
				if (a[i][j] != 0) {
					for (int h = i + 1; h <= 3; h++) {
						if (a[h][j] != 0) {
							if (a[h][j] == a[i][j]) {
								//可以合并
								a[h][j] *= 2;
								a[i][j] = 0;
								i = h;
								break;
							}
							else {
								break;
							}
						}
					}
				}
			}
		}
		//进行紧凑处理
		for (int j = 0; j < 4; j++) {
			for (int i = 3; i > 0; i--) {
				if (a[i][j] == 0) {
					for (int k = i - 1; k >= 0; k--) {
						if (a[k][j] != 0) {
							a[i][j] = a[k][j];
							a[k][j] = 0;
							break;
						}
					}
				}
			}
		}
		break;
	case 'a':
		//左移操作
		for (int i = 0; i < 4; i++) {
			for (int j = 3; j > 0; j--) {
				if (a[i][j] != 0) {
					for (int k = j - 1; k >= 0; k--) {
						if (a[i][k] != 0) {
							//要找第一个不等于0的格子
							if (a[i][k] == a[i][j]) {
								a[i][k] *= 2;
								a[i][j] = 0;
								j = k;
								break;
							}
							else {
								break;
							}
						}
					}
				}
			}
		}
		//进行紧凑处理
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 3; j++) {
				if (a[i][j] == 0) {
					for (int k = j + 1; k < 4; k++) {
						if (a[i][k] != 0) {
							a[i][j] = a[i][k];
							a[i][k] = 0;
							break;
						}
					}
				}
			}
		}
		break;
	case 'd':
		//右移操作
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 3; j++) {
				if (a[i][j] != 0) {
					for (int k = j + 1; k < 4; k++) {
						if (a[i][k] != 0) {
							if (a[i][k] == a[i][j]) {
								a[i][k] *= 2;
								a[i][j] = 0;
								j = k;
								break;
							}
							else {
								break;
							}
						}
					}
				}
			}
		}
		//进行紧凑处理
		for (int i = 0; i < 4; i++) {
			for (int j = 3; j > 0; j--) {
				if (a[i][j] == 0) {
					for (int k = j - 1; k >= 0; k--) {
						if (a[i][k] != 0) {
							a[i][j] = a[i][k];
							a[i][k] = 0;
							break;
						}
					}
				}
			}
		}
	default:
		break;
	}
}

int main()
{
	int a[4][4] = {0};
	int count=0;//记录游戏步数
	start(a);
	print(a,count);
	run(a);
	count++;
	system("cls");
	fresh(a);
	print(a, count);
	Sleep(50);
	while (1) {
		if (is_die(a) == 1) {
			//游戏还可以继续进行
			run(a);
			fresh(a);
			system("cls");
			count++;
			print(a, count);
			Sleep(5);
		}
		else {
			system("cls");
			printf("游戏结束,最终得分为:%d\n", count);
		}
	}
    return 0;
}

运行结果:

猜你喜欢

转载自blog.csdn.net/haohulala/article/details/81150443