2048控制台小游戏

头文件

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
  • #include <stdio.h>——不必多说

  • #include <time.h>——srand(time(NULL))随机数

  • #include <conio.h>——char ch = getch()获取键盘输入

  • #include <stdlib.h>——很奇怪,我之前用库函数的说要加这个,可是刚刚注释掉他却一样可以用。加就对了

全局变量

// 数据--数组
int a[6][6]= {0};	// 棋盘数组,明明是4*4为什么要写成6*6呢,我觉得写大点没坏处,后面检测是否game_over的时候方便点,仅此而已
int max = 2;		// 如果max==2048就代表合成了2048,win,结束游戏
int score = 0;		// 记录当前获得分数,我没有在文件中加入历史最高分这个东西,可以加

函数声明

void draw_interface();			// 画 界面
bool game_over();				// 判断游戏是否结束,与是否胜利
void rand_xy();					// 随机生成点
// 行动逻辑
bool merge_up();		// 上
bool merge_down();		// 下
bool merge_left();		// 左
bool merge_right();		// 右

逐个解释

游戏界面

在这里插入图片描述

void draw_interface()

直接对照图片

// 游戏界面
void draw_interface()
{
	// 先清屏
	system("cls");
	// 打印标题
	printf("----2048控制台小游戏----\n");

	//画表格
	printf("|-----|-----|-----|-----|\n");
	for(int i = 1; i <= 4; i++)
	{
		printf("|");
		for(int j = 1; j <= 4; j++)
		{
			if(a[i][j] != 0)
				printf("%5d|",a[i][j]);
			else
				printf("     |");
		}
		printf("\n");
		printf("|-----|-----|-----|-----|\n");
	}
	printf("score:%d\n",score);
}

随机生成点

void rand_xy();

// 随机生成点
void rand_xy()
{
	int rand_x,rand_y;
    // 4*4的格子里,随机数只能是1-4的范围
	do
	{
		rand_x = rand()%4 + 1;
		rand_y = rand()%4 + 1;
	}
	while(a[rand_x][rand_y]!=0);	// 新生成的点,只能在没有数据的地方,也就是0的地方
	a[rand_x][rand_y] = 2;
}

判断是否游戏结束

bool game_over()

// 判断游戏是否结束,与是否胜利
bool game_over()
{
	for(int i = 1; i <= 4; i++)
		for(int j = 1; j <= 4; j++)
		{
			if(a[i][j] == 0)return false;	// 如果还有位置可以生成数据,那就肯定还没输
			else if(a[i][j] != 0)
			{
                // 如果还有机会合并,就还没输
				if(a[i][j] == a[i+1][j] || a[i][j] == a[i-1][j] || a[i][j] == a[i][j-1] || a[i][j] == a[i][j+1])return false;
			}
		}
    // 没有空的位置,又不能合并了,就输了
	return true;
}

!!!返回TRUE表示输了,FALSE是还没输

合并逻辑

merge

只讲一个方向,别的自行思考修改。

我也是从别人那里看到这两个词,才知道可以这样写。

想法:

左合并时,先让他们向左挤,把空位置都挤到右面去,这一步叫紧凑

然后就从最左边开始判断是否可以和右边的合并

看代码:

bool merge_left()
{
	bool flag=0;
	for(int i = 1; i <= 4; i++)
	{
		// 紧凑
		int j = 1;
		for(int y = 1; y <= 4; y++)
			if(a[i][y] != 0)
			{
				a[i][j] = a[i][y];
				if(j != y)flag = 1;
				j++;
			}
		for(; j <= 4; j++)a[i][j] = 0;		// 剩下的要置0
		// 合并
		int x = 1;
		while(x <= 3)
		{
			if(a[i][x] == 0)break;			// 如果遇到0,代表后面已经没数据了,就break
			else if(a[i][x] == a[i][x+1])	// 如果数据相同就合并,然后把剩下的压过来一格。
			{
				score += a[i][x];			// 合并就得分
				a[i][x] = a[i][x] * 2;
				flag = 1;
				for(int y = x + 1; y <= 3; y++)
					a[i][y] = a[i][y + 1];
				a[i][4] = 0;
				x++;
			}
			else x++;		//如果前后数据不同,就走到下一个
		}
	}
	return flag;
}
bool merge_right()
{
	bool flag=0;
	for(int i = 1; i <= 4; i++)
	{
		// 紧凑
		int j = 4;
		for(int y = 4; y >= 1; y--)
			if(a[i][y] != 0)
			{
				a[i][j] = a[i][y];
				if(j != y)flag = 1;
				j--;
			}
		for(; j >= 1; j--)a[i][j] = 0;
		// 合并
		int x = 4;
		while(x >= 2)
		{
			if(a[i][x] == 0)break;
			else if(a[i][x] == a[i][x - 1])
			{
				score += a[i][x];
				a[i][x] = a[i][x] * 2;
				flag = 1;
				for(int y = x - 1; y >= 2; y--)
					a[i][y] = a[i][y - 1];
				a[i][1] = 0;
				x--;
			}
			else x--;
		}
	}
	return flag;
}
bool merge_up()
{
	bool flag=0;
	for(int i = 1; i <= 4; i++)
	{
		// 紧凑
		int j = 1;
		for(int y = 1; y <= 4; y++)
			if(a[y][i] != 0)
			{
				a[j][i] = a[y][i];
				if(j != y)flag = 1;
				j++;
			}
		for(; j <= 4; j++)a[j][i] = 0;
		// 合并
		int x = 1;
		while(x <= 3)
		{
			if(a[x][i] == 0)break;
			else if(a[x][i] == a[x+1][i])
			{
				score += a[x][i];
				a[x][i] = a[x][i] * 2;
				flag = 1;
				for(int y = x + 1; y <= 3; y++)
					a[y][i] = a[y + 1][i];
				a[4][i] = 0;
				x++;
			}
			else x++;
		}
	}
	return flag;
}
bool merge_down()
{
	bool flag=0;
	for(int i = 1; i <= 4; i++)
	{
		// 紧凑
		int j = 4;
		for(int y = 4; y >= 1; y--)
			if(a[y][i] != 0)
			{
				a[j][i] = a[y][i];
				if(j != y)flag = 1;
				j--;
			}
		for(; j >= 1; j--)a[j][i] = 0;
		// 合并
		int x = 4;
		while(x >= 2)
		{
			if(a[x][i] == 0)break;
			else if(a[x][i] == a[x - 1][i])
			{
				score += a[x][i];
				a[x][i] = a[x][i] * 2;
				flag = 1;
				for(int y = x - 1; y >= 2; y--)
					a[y][i] = a[y - 1][i];
				a[1][i] = 0;
				x--;
			}
			else x--;
		}
	}
	return flag;
}

主函数

很明了吧,初始化搞好后,就循环获取键盘操作,进行合并逻辑和判断生成点,和判断游戏是否结束,对了合并时我会判断是否移动过,是否合并过,一个都没有的,就不生成数据,不重新画图。

int main()
{
	// 初始化随机种子
	srand(time(NULL));

	// 初始化两个数据
	rand_xy();
	rand_xy();
	
    draw_interface();
	char ch1,ch2;
	while (1)
	{
        // 为什么要这么写呢,因为我用的不是WSAD而是上下左右,用这个函数输入上下左右时,会先读取一个?所以,要先吃掉
		if(ch1 = getch())
		{
			if(ch1 == 27)
			{
				printf("强制结束!!!\n");
				return 0;
			}
			ch2 = getch();
			bool flag = 0;
			switch (ch2)
			{
				case 72://上
					flag = merge_up();
					break;
				case 77://右
					flag = merge_right();
					break;
				case 80://下
					flag = merge_down();
					break;
				case 75://左
					flag = merge_left();
					break;
			}
			bool t = game_over();
			if(max == 2048)
			{
				printf("WIN!!!");
				return 0;
			}
			if(t == true)
			{
				printf("GAME OVER!!!");
				return 0;
			}
			if(flag)
			{
				rand_xy();
				draw_interface();
			}
		}
	}
	return 0;
}

完整代码:275行

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <windows.h>

int a[6][6]= {0};	// 棋盘数组,明明是4*4为什么要写成6*6呢,我觉得写大点没坏处,后面检测是否game_over的时候方便点,仅此而已
int max = 2;		// 如果max==2048就代表合成了2048,win,结束游戏
int score = 0;		// 记录当前获得分数,我没有在文件中加入历史最高分这个东西,可以加

void draw_interface();			// 画 界面
bool game_over();				// 判断游戏是否结束,与是否胜利
void rand_xy();					// 随机生成点
// 行动逻辑
bool merge_up();		// 上
bool merge_down();		// 下
bool merge_left();		// 左
bool merge_right();		// 右

int main()
{
	// 初始化随机种子
	srand(time(NULL));

	// 初始化两个数据
	rand_xy();
	rand_xy();
	
    draw_interface();
	char ch1,ch2;
	while (1)
	{
        // 为什么要这么写呢,因为我用的不是WSAD而是上下左右,用这个函数输入上下左右时,会先读取一个?所以,要先吃掉
		if(ch1 = getch())
		{
			if(ch1 == 27)
			{
				printf("强制结束!!!\n");
				return 0;
			}
			ch2 = getch();
			bool flag = 0;
			switch (ch2)
			{
				case 72://上
					flag = merge_up();
					break;
				case 77://右
					flag = merge_right();
					break;
				case 80://下
					flag = merge_down();
					break;
				case 75://左
					flag = merge_left();
					break;
			}
			bool t = game_over();
			if(max == 2048)
			{
				printf("WIN!!!");
				return 0;
			}
			if(t == true)
			{
				printf("GAME OVER!!!");
				return 0;
			}
			if(flag)
			{
				rand_xy();
				draw_interface();
			}
		}
	}
	return 0;
}

// 游戏界面
void draw_interface()
{
	// 先清屏
	system("cls");
	// 打印标题
	printf("----2048控制台小游戏----\n");

	//画表格
	printf("|-----|-----|-----|-----|\n");
	for(int i = 1; i <= 4; i++)
	{
		printf("|");
		for(int j = 1; j <= 4; j++)
		{
			if(a[i][j] != 0)
				printf("%5d|",a[i][j]);
			else
				printf("     |");
		}
		printf("\n");
		printf("|-----|-----|-----|-----|\n");
	}
	printf("score:%d\n",score);
}

// 随机生成点
void rand_xy()
{
	int rand_x,rand_y;
    // 4*4的格子里,随机数只能是1-4的范围
	do
	{
		rand_x = rand()%4 + 1;
		rand_y = rand()%4 + 1;
	}
	while(a[rand_x][rand_y]!=0);	// 新生成的点,只能在没有数据的地方,也就是0的地方
	a[rand_x][rand_y] = 2;
}

// 判断游戏是否结束,与是否胜利
bool game_over()
{
	for(int i = 1; i <= 4; i++)
		for(int j = 1; j <= 4; j++)
		{
			if(a[i][j] == 0)return false;	// 如果还有位置可以生成数据,那就肯定还没输
			else if(a[i][j] != 0)
			{
                // 如果还有机会合并,就还没输
				if(a[i][j] == a[i+1][j] || a[i][j] == a[i-1][j] || a[i][j] == a[i][j-1] || a[i][j] == a[i][j+1])return false;
			}
		}
    // 没有空的位置,又不能合并了,就输了
	return true;
}

bool merge_left()
{
	bool flag=0;
	for(int i = 1; i <= 4; i++)
	{
		// 紧凑
		int j = 1;
		for(int y = 1; y <= 4; y++)
			if(a[i][y] != 0)
			{
				a[i][j] = a[i][y];
				if(j != y)flag = 1;
				j++;
			}
		for(; j <= 4; j++)a[i][j] = 0;		// 剩下的要置0
		// 合并
		int x = 1;
		while(x <= 3)
		{
			if(a[i][x] == 0)break;			// 如果遇到0,代表后面已经没数据了,就break
			else if(a[i][x] == a[i][x+1])	// 如果数据相同就合并,然后把剩下的压过来一格。
			{
				score += a[i][x];			// 合并就得分
				a[i][x] = a[i][x] * 2;
				flag = 1;
				for(int y = x + 1; y <= 3; y++)
					a[i][y] = a[i][y + 1];
				a[i][4] = 0;
				x++;
			}
			else x++;		//如果前后数据不同,就走到下一个
		}
	}
	return flag;
}
bool merge_right()
{
	bool flag=0;
	for(int i = 1; i <= 4; i++)
	{
		// 紧凑
		int j = 4;
		for(int y = 4; y >= 1; y--)
			if(a[i][y] != 0)
			{
				a[i][j] = a[i][y];
				if(j != y)flag = 1;
				j--;
			}
		for(; j >= 1; j--)a[i][j] = 0;
		// 合并
		int x = 4;
		while(x >= 2)
		{
			if(a[i][x] == 0)break;
			else if(a[i][x] == a[i][x - 1])
			{
				score += a[i][x];
				a[i][x] = a[i][x] * 2;
				flag = 1;
				for(int y = x - 1; y >= 2; y--)
					a[i][y] = a[i][y - 1];
				a[i][1] = 0;
				x--;
			}
			else x--;
		}
	}
	return flag;
}
bool merge_up()
{
	bool flag=0;
	for(int i = 1; i <= 4; i++)
	{
		// 紧凑
		int j = 1;
		for(int y = 1; y <= 4; y++)
			if(a[y][i] != 0)
			{
				a[j][i] = a[y][i];
				if(j != y)flag = 1;
				j++;
			}
		for(; j <= 4; j++)a[j][i] = 0;
		// 合并
		int x = 1;
		while(x <= 3)
		{
			if(a[x][i] == 0)break;
			else if(a[x][i] == a[x+1][i])
			{
				score += a[x][i];
				a[x][i] = a[x][i] * 2;
				flag = 1;
				for(int y = x + 1; y <= 3; y++)
					a[y][i] = a[y + 1][i];
				a[4][i] = 0;
				x++;
			}
			else x++;
		}
	}
	return flag;
}
bool merge_down()
{
	bool flag=0;
	for(int i = 1; i <= 4; i++)
	{
		// 紧凑
		int j = 4;
		for(int y = 4; y >= 1; y--)
			if(a[y][i] != 0)
			{
				a[j][i] = a[y][i];
				if(j != y)flag = 1;
				j--;
			}
		for(; j >= 1; j--)a[j][i] = 0;
		// 合并
		int x = 4;
		while(x >= 2)
		{
			if(a[x][i] == 0)break;
			else if(a[x][i] == a[x - 1][i])
			{
				score += a[x][i];
				a[x][i] = a[x][i] * 2;
				flag = 1;
				for(int y = x - 1; y >= 2; y--)
					a[y][i] = a[y - 1][i];
				a[1][i] = 0;
				x--;
			}
			else x--;
		}
	}
	return flag;
}

以上就是雏形

加上文件操作+颜色+开始界面和存档界面

添加头文件

  • #include <windows.h>——SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), col);

    修改局部背景色,具体可以看下面的网址,然后这个数组是我从别人的代码里抄的,因为颜色这样设置感觉比较好看,懒得自己设置了。

//https://blog.csdn.net/Fdog_/article/details/103764196
//SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 144);
int color_[]= {240,144,160,176,192,208,224,16,32,48,64,80};

增加函数声明

void draw_interface_color();	// 画 界面 颜色版
void Start_the_screen();		// 开始界面
void save();					// 存档

添加全局变量

int color_[]= {240,144,160,176,192,208,224,16,32,48,64,80};		//这就是2,4,8...各自对应不同的颜色,非必须,往下看有两种界面

在这里插入图片描述

函数

存档

存档的结构是第一行,有一个数字,为0代表没有存档,为1代表有存档。

后面就是个4*4的数字矩阵

// 存档
void save()
{
	printf("--是否保存此次游戏--\n");
	printf("--      1.否      --\n");
	printf("--      2.是      --\n");
	printf("请输入你的选择: ");
	char ch;
	do
	{
		ch = getchar();
	}
	while(ch!='1'&&ch!='2');
	FILE *fp = fopen("./存档/archive.txt","w");
	if(fp == NULL)perror ("Error opening file");
	else
	{
		if(ch == '1')
		{
			fprintf(fp,"0");
		}
		else
		{
			fprintf(fp,"1\n");
			for(int i = 1; i <= 4; i++)
			{
				for(int j = 1; j <= 4; j++)
					fprintf(fp,"%5d",a[i][j]);
				fprintf(fp,"\n");
			}
		}
		fclose(fp);
	}
}

游戏界面–颜色版

设置好颜色再输出,换行时记得也要修改。

// 游戏界面 颜色
void draw_interface_color()
{
	// 先清屏
	system("cls");
	// 打印标题
	printf("--2048控制台小游戏--\n");
	for(int i = 1; i <= 4; i++)
	{
		for(int j = 1; j <= 4; j++)
		{
			int col;
			switch(a[i][j])
			{
				case 0:
					col = color_[0];
					break;
				case 2:
					col = color_[1];
					break;
				case 4:
					col = color_[2];
					break;
				case 8:
					col = color_[3];
					break;
				case 16:
					col = color_[4];
					break;
				case 32:
					col = color_[5];
					break;
				case 64:
					col = color_[6];
					break;
				case 128:
					col = color_[7];
					break;
				case 256:
					col = color_[8];
					break;
				case 512:
					col = color_[9];
					break;
				case 1024:
					col = color_[10];
					break;
				case 2048:
					col = color_[11];
					break;
			}
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), col);
			printf("%5d",a[i][j]);
		}
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
		printf("\n");
	}
	printf("score:%d\n",score);
}

开始界面

存档要以直接替换a[i][j]就好了

// 开始界面
void Start_the_screen()
{
	printf("--2048控制台小游戏--\n");
	printf("--    1.新游戏    --\n");
	printf("--    2.继续游戏  --\n");
	printf("请输入你的选择: ");
	char ch;
	do
	{
		ch = getchar();
	}
	while(ch!='1'&&ch!='2');
	if(ch == '2')
	{
		FILE *fp = fopen("./存档/archive.txt","r");
		if(fp == NULL)perror ("Error opening file");
		else
		{
			int t;
			fscanf(fp,"%d",&t);
			if(t == 0)
			{
				printf("没有存档,开启新游戏");
				getchar();
				getchar();
			}
			else{
				for(int i = 1; i <= 4; i++)
					for(int j = 1; j <= 4; j++)
						fscanf(fp,"%d",&a[i][j]);	
			}
			fclose(fp);
		}
	}
}

颜色版本最终代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <windows.h>


int a[6][6]= {0};	// 棋盘数组,明明是4*4为什么要写成6*6呢,我觉得写大点没坏处,后面检测是否game_over的时候方便点,仅此而已
int max = 2;		// 如果max==2048就代表合成了2048,win,结束游戏
int score = 0;		// 记录当前获得分数,我没有在文件中加入历史最高分这个东西,可以加
int color_[]= {240,144,160,176,192,208,224,16,32,48,64,80};

void draw_interface();			// 画 界面
bool game_over();				// 判断游戏是否结束,与是否胜利
void rand_xy();					// 随机生成点
// 行动逻辑
bool merge_up();		// 上
bool merge_down();		// 下
bool merge_left();		// 左
bool merge_right();		// 右

void draw_interface_color();	// 画 界面 颜色版
void Start_the_screen();		// 开始界面
void save();					// 存档

int main()
{
	// 初始化随机种子
	srand(time(NULL));

	// 初始化两个数据
	rand_xy();
	rand_xy();
	
    //draw_interface();
	Start_the_screen();
	draw_interface_color();
	char ch1,ch2;
	while (1)
	{
        // 为什么要这么写呢,因为我用的不是WSAD而是上下左右,用这个函数输入上下左右时,会先读取一个?所以,要先吃掉
		if(ch1 = getch())
		{
			if(ch1 == 27)
			{
				printf("强制结束!!!\n");
				save();
				return 0;
			}
			ch2 = getch();
			bool flag = 0;
			switch (ch2)
			{
				case 72://上
					flag = merge_up();
					break;
				case 77://右
					flag = merge_right();
					break;
				case 80://下
					flag = merge_down();
					break;
				case 75://左
					flag = merge_left();
					break;
			}
			bool t = game_over();
			if(max == 2048)
			{
				printf("WIN!!!");
				return 0;
			}
			if(t == true)
			{
				printf("GAME OVER!!!");
				return 0;
			}
			if(flag)
			{
				rand_xy();
				//draw_interface();
				draw_interface_color();
			}
		}
	}
	return 0;
}

// 游戏界面
void draw_interface()
{
	// 先清屏
	system("cls");
	// 打印标题
	printf("----2048控制台小游戏----\n");

	//画表格
	printf("|-----|-----|-----|-----|\n");
	for(int i = 1; i <= 4; i++)
	{
		printf("|");
		for(int j = 1; j <= 4; j++)
		{
			if(a[i][j] != 0)
				printf("%5d|",a[i][j]);
			else
				printf("     |");
		}
		printf("\n");
		printf("|-----|-----|-----|-----|\n");
	}
	printf("score:%d\n",score);
}

// 随机生成点
void rand_xy()
{
	int rand_x,rand_y;
    // 4*4的格子里,随机数只能是1-4的范围
	do
	{
		rand_x = rand()%4 + 1;
		rand_y = rand()%4 + 1;
	}
	while(a[rand_x][rand_y]!=0);	// 新生成的点,只能在没有数据的地方,也就是0的地方
	a[rand_x][rand_y] = 2;
}

// 判断游戏是否结束,与是否胜利
bool game_over()
{
	for(int i = 1; i <= 4; i++)
		for(int j = 1; j <= 4; j++)
		{
			if(a[i][j] == 0)return false;	// 如果还有位置可以生成数据,那就肯定还没输
			else if(a[i][j] != 0)
			{
                // 如果还有机会合并,就还没输
				if(a[i][j] == a[i+1][j] || a[i][j] == a[i-1][j] || a[i][j] == a[i][j-1] || a[i][j] == a[i][j+1])return false;
			}
		}
    // 没有空的位置,又不能合并了,就输了
	return true;
}

bool merge_left()
{
	bool flag=0;
	for(int i = 1; i <= 4; i++)
	{
		// 紧凑
		int j = 1;
		for(int y = 1; y <= 4; y++)
			if(a[i][y] != 0)
			{
				a[i][j] = a[i][y];
				if(j != y)flag = 1;
				j++;
			}
		for(; j <= 4; j++)a[i][j] = 0;		// 剩下的要置0
		// 合并
		int x = 1;
		while(x <= 3)
		{
			if(a[i][x] == 0)break;			// 如果遇到0,代表后面已经没数据了,就break
			else if(a[i][x] == a[i][x+1])	// 如果数据相同就合并,然后把剩下的压过来一格。
			{
				score += a[i][x];			// 合并就得分
				a[i][x] = a[i][x] * 2;
				flag = 1;
				for(int y = x + 1; y <= 3; y++)
					a[i][y] = a[i][y + 1];
				a[i][4] = 0;
				x++;
			}
			else x++;		//如果前后数据不同,就走到下一个
		}
	}
	return flag;
}
bool merge_right()
{
	bool flag=0;
	for(int i = 1; i <= 4; i++)
	{
		// 紧凑
		int j = 4;
		for(int y = 4; y >= 1; y--)
			if(a[i][y] != 0)
			{
				a[i][j] = a[i][y];
				if(j != y)flag = 1;
				j--;
			}
		for(; j >= 1; j--)a[i][j] = 0;
		// 合并
		int x = 4;
		while(x >= 2)
		{
			if(a[i][x] == 0)break;
			else if(a[i][x] == a[i][x - 1])
			{
				score += a[i][x];
				a[i][x] = a[i][x] * 2;
				flag = 1;
				for(int y = x - 1; y >= 2; y--)
					a[i][y] = a[i][y - 1];
				a[i][1] = 0;
				x--;
			}
			else x--;
		}
	}
	return flag;
}
bool merge_up()
{
	bool flag=0;
	for(int i = 1; i <= 4; i++)
	{
		// 紧凑
		int j = 1;
		for(int y = 1; y <= 4; y++)
			if(a[y][i] != 0)
			{
				a[j][i] = a[y][i];
				if(j != y)flag = 1;
				j++;
			}
		for(; j <= 4; j++)a[j][i] = 0;
		// 合并
		int x = 1;
		while(x <= 3)
		{
			if(a[x][i] == 0)break;
			else if(a[x][i] == a[x+1][i])
			{
				score += a[x][i];
				a[x][i] = a[x][i] * 2;
				flag = 1;
				for(int y = x + 1; y <= 3; y++)
					a[y][i] = a[y + 1][i];
				a[4][i] = 0;
				x++;
			}
			else x++;
		}
	}
	return flag;
}
bool merge_down()
{
	bool flag=0;
	for(int i = 1; i <= 4; i++)
	{
		// 紧凑
		int j = 4;
		for(int y = 4; y >= 1; y--)
			if(a[y][i] != 0)
			{
				a[j][i] = a[y][i];
				if(j != y)flag = 1;
				j--;
			}
		for(; j >= 1; j--)a[j][i] = 0;
		// 合并
		int x = 4;
		while(x >= 2)
		{
			if(a[x][i] == 0)break;
			else if(a[x][i] == a[x - 1][i])
			{
				score += a[x][i];
				a[x][i] = a[x][i] * 2;
				flag = 1;
				for(int y = x - 1; y >= 2; y--)
					a[y][i] = a[y - 1][i];
				a[1][i] = 0;
				x--;
			}
			else x--;
		}
	}
	return flag;
}


// 存档
void save()
{
	printf("--是否保存此次游戏--\n");
	printf("--      1.否      --\n");
	printf("--      2.是      --\n");
	printf("请输入你的选择: ");
	char ch;
	do
	{
		ch = getchar();
	}
	while(ch!='1'&&ch!='2');
	FILE *fp = fopen("./存档/archive.txt","w");
	if(fp == NULL)perror ("Error opening file");
	else
	{
		if(ch == '1')
		{
			fprintf(fp,"0");
		}
		else
		{
			fprintf(fp,"1\n");
			for(int i = 1; i <= 4; i++)
			{
				for(int j = 1; j <= 4; j++)
					fprintf(fp,"%5d",a[i][j]);
				fprintf(fp,"\n");
			}
		}
		fclose(fp);
	}
}

// 游戏界面 颜色
void draw_interface_color()
{
	// 先清屏
	system("cls");
	// 打印标题
	printf("--2048控制台小游戏--\n");
	for(int i = 1; i <= 4; i++)
	{
		for(int j = 1; j <= 4; j++)
		{
			int col;
			switch(a[i][j])
			{
				case 0:
					col = color_[0];
					break;
				case 2:
					col = color_[1];
					break;
				case 4:
					col = color_[2];
					break;
				case 8:
					col = color_[3];
					break;
				case 16:
					col = color_[4];
					break;
				case 32:
					col = color_[5];
					break;
				case 64:
					col = color_[6];
					break;
				case 128:
					col = color_[7];
					break;
				case 256:
					col = color_[8];
					break;
				case 512:
					col = color_[9];
					break;
				case 1024:
					col = color_[10];
					break;
				case 2048:
					col = color_[11];
					break;
			}
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), col);
			printf("%5d",a[i][j]);
		}
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
		printf("\n");
	}
	printf("score:%d\n",score);
}

// 开始界面
void Start_the_screen()
{
	printf("--2048控制台小游戏--\n");
	printf("--    1.新游戏    --\n");
	printf("--    2.继续游戏  --\n");
	printf("请输入你的选择: ");
	char ch;
	do
	{
		ch = getchar();
	}
	while(ch!='1'&&ch!='2');
	if(ch == '2')
	{
		FILE *fp = fopen("./存档/archive.txt","r");
		if(fp == NULL)perror ("Error opening file");
		else
		{
			int t;
			fscanf(fp,"%d",&t);
			if(t == 0)
			{
				printf("没有存档,开启新游戏");
				getchar();
				getchar();
			}
			else{
				for(int i = 1; i <= 4; i++)
					for(int j = 1; j <= 4; j++)
						fscanf(fp,"%d",&a[i][j]);	
			}
			fclose(fp);
		}
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值