C语言实现2048游戏


2048游戏在很长一段时间内是一款很火的小游戏。
游戏要求:

  • 最开始两个随机数
  • 每次生成一个随机数2或者4,生成4的概率是1/10
  • 键盘上下左右键控制游戏的走向
  • 当出现2048数字时,玩家获胜

打印界面

	 //打印
	void GamePrint(int row, int col)
	{
		printf("SCORE = %d", score);
		SetCurPos(0, 2);
		int i = 0;
		for (i = 0; i < row; i++)
		{
			for (int k = 0; k < 4; k++)
			{
				printf(" ");
				for (int j = 0; j < 4; j++)
				{
					printf("-");
				}
			}
			printf("\n");
			for (int k = 0; k < 4; k++)
			{
				printf("|");
				if (arr[i][k])
				{
					printf("%4d", arr[i][k]);
				}
				else
				{
					for (int j = 0; j < 4; j++)
					{
						printf(" ");
					}
				}
	
			}
			printf("|\n");
			if (i == row - 1)
			{
				for (int k = 0; k < 4; k++)
				{
					printf(" ");
					for (int j = 0; j < 4; j++)
					{
						printf("-");
					}
				}
				printf("\n");
			}
		}
		SetCurPos(0, 12);
		printf("上下左右表示方向\n");
	}

生成随机数

要求生成4的概率为1/10,
生成一个10以内的数字(或者将生成的数字对10取余)
     判断其是否为4
        如果是4就生成4,
        如果不是4,就生成2

	void RandNum(int row, int col) //生成随机数
	{
		int x = 0;
		int y = 0;
		do
		{
			x = rand() % 4;
			y = rand() % 4;
		} while (arr[x][y]);
		arr[x][y] = (rand() % 10 ? 2 : 4);
	}

是否获胜

	int IfWin(int row, int col)
	{
		for (int i = 0; i < row; i++)
		{
			for (int j = 0; j < col; j++)
			{
				if (arr[i][j] == 2048)
				{
					return 1; //表示赢了
				}
				if (arr[i][j] == 0)
				{
					return 0; //表示继续游戏
				}
			}
		}
		return -1;//输了
	}

移动

移动这部分就是这个游戏的核心。
以右移为例,我们把二维数组抽象成一个4*4的方块,值为0的是空方块,其余的是数字方块。我们只抽取出来一行来做实例(其余行就可以通过循环以同样的方式来做)。一行就可以用一个一维数组来表示b[j]运用两个下标来遍历这个以为数组,k,j;j永远在k的后面,k表示当前比较项,j表示下一个不为0的元素;可以分为以下三种情况:
移动: b[k] == 0;b[j]之前的全是空格子,就要让b[j]移动到b[k]的位置处,然后K++,继续向后走
在这里插入图片描述
合并: b[k] == b[j];就要让b[k] = 2 * b[k] ;然后k++
在这里插入图片描述
碰撞: b[k] != b[j];此时就要分两种情况:
          k + 1 != j;表示两者没有靠在一起,b[k+1] = b[j]; b[j] = 0; k++;
          k + 1 == j;表示两者原本就靠在一起,不用管
在这里插入图片描述

	int j = 1;
	int k = 0;
	for (; j < 4; j++) 
	{  
		//找出k第一个不为0的块,之后分为三种情况
		if (b[j] > 0) 
		{
			//移动
			 if (b[k] == 0) 
			{ 
				b[k] = b[j];
	            b[j] = 0;
			}
			 //合并
			else if (b[k] == b[j])
			{
				b[k] = 2 * b[k];
				b[j] = 0;
				k = k + 1;
			}
			 //碰撞
			else
			{ 
				b[k + 1] = b[j];
				if (j != k + 1) 
				{ 
					b[j] = 0;
				}
				k = k + 1;
			}
		}
	}

游戏代码:

	#include <stdlib.h>
	#include <time.h>
	#include <stdio.h>
	#include <Windows.h>
	#include <conio.h>
	
	#define ROW 4
	#define COL 4
	//定义全局变量的好处:在函数之间不用传参
	//              缺点:只能完成一次游戏,要想继续玩就必须将数组重置为全0;
	int arr[ROW][COL] = { 0 };
	int score = 0;
	
	//设置光标的句柄,通俗的说,就是设置光标的位置
	void SetCurPos(int x, int y)
	{
		HANDLE hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
		COORD coord = { x, y };
		SetConsoleCursorPosition(hStdOutput, coord);
	}
	//隐藏光标
	void ViewInit(int width, int height)
	{
		HANDLE hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
		CONSOLE_CURSOR_INFO info;
		GetConsoleCursorInfo(hStdOutput, &info);
		info.bVisible = 0;
		SetConsoleCursorInfo(hStdOutput, &info);
	}
	
	 //打印
	void GamePrint(int row, int col)
	{
		printf("SCORE = %d", score);
		SetCurPos(0, 2);
		int i = 0;
		for (i = 0; i < row; i++)
		{
			for (int k = 0; k < 4; k++)
			{
				printf(" ");
				for (int j = 0; j < 4; j++)
				{
					printf("-");
				}
			}
			printf("\n");
			for (int k = 0; k < 4; k++)
			{
				printf("|");
				if (arr[i][k])
				{
					printf("%4d", arr[i][k]);
				}
				else
				{
					for (int j = 0; j < 4; j++)
					{
						printf(" ");
					}
				}
	
			}
			printf("|\n");
			if (i == row - 1)
			{
				for (int k = 0; k < 4; k++)
				{
					printf(" ");
					for (int j = 0; j < 4; j++)
					{
						printf("-");
					}
				}
				printf("\n");
			}
		}
		SetCurPos(0, 12);
		printf("上下左右表示方向\n");
	}
	//生成随机数
	void RandNum(int row, int col) //生成随机数
	{
		int x = 0;
		int y = 0;
		do
		{
			x = rand() % 4;
			y = rand() % 4;
		} while (arr[x][y]);
		arr[x][y] = (rand() % 10 ? 2 : 4);
	}
	//判断是否获胜
	int IfWin(int row, int col)
	{
		for (int i = 0; i < row; i++)
		{
			for (int j = 0; j < col; j++)
			{
				if (arr[i][j] == 2048)
				{
					return 1; //表示赢了
				}
				if (arr[i][j] == 0)
				{
					return 0; //表示继续游戏
				}
			}
		}
		return -1;//输了
	}
	//向左移
	void MoveLeft()
	{
		for (int i = 0; i < ROW; i++)
		{
			int j = 1; 
			int k = 0;
			for (; j < 4; j++)
			{
				if (arr[i][j] > 0)
				{
					if (arr[i][k] == 0)
					{
						arr[i][k] = arr[i][j];
						arr[i][j] = 0;
					}
					else if(arr[i][k] == arr[i][j])
					{
						arr[i][k] = 2 * arr[i][k];
						score += arr[i][k];
						arr[i][j] = 0;
						k++;
					}
					else
					{
						arr[i][++k] = arr[i][j];
						if (j != k)
						{
							arr[i][j] = 0;
						}
					}
				}
			}
		}
	}
	//向右移
	void MoveRight()
	{
		for (int i = 0; i < ROW; i++)
		{
			int j = 2;
			int k = 3;
			for (; j >= 0; j--)
			{
				if (arr[i][j] > 0)
				{
					if (arr[i][k] == 0)
					{
						arr[i][k] = arr[i][j];
						arr[i][j] = 0;
					}
					else if (arr[i][k] == arr[i][j])
					{
						arr[i][k] = 2 * arr[i][k];
						score += arr[i][k];
						arr[i][j] = 0;
						k--;
					}
					else
					{
						arr[i][--k] = arr[i][j];
						if (j != k)
						{
							arr[i][j] = 0;
						}
					}
				}
			}
		}
	}
	//向上移
	void MoveUp()
	{
		for (int j = 0; j < COL; j++)
		{
			int i = 1;
			int k = 0;
			for (; i < 4; i++)
			{
				if (arr[i][j] > 0)
				{
					if (arr[k][j] == arr[i][j])
					{
						score += arr[k++][j] *= 2;
						arr[i][j] = 0;
					}
					else if (arr[k][j] == 0)
					{
						arr[k][j] = arr[i][j];
						arr[i][j] = 0;
					}
					else
					{
						arr[++k][j] = arr[i][j];
						if (i != k)
						{
							arr[i][j] = 0;
						}
					}
				}
			}
		}
	}
	//向下移
	void MoveDown()
	{
		for (int j = 0; j < COL; j++)
		{
			int i = 2;
			int k = 3;
			for (; i >= 0; i--)
			{
				if (arr[i][j] > 0)
				{
					if (arr[k][j] == 0)
					{
						arr[k][j] = arr[i][j];
						arr[i][j] = 0;
					}
					else if (arr[k][j] == arr[i][j])
					{
						arr[k][j] = 2 * arr[k][j];
						score += arr[k][j];
						arr[i][j] = 0;
						k--;
					}
					else
					{
						arr[--k][j] = arr[i][j];
						if (i != k)
						{
							arr[i][j] = 0;
						}
					}
				}
			}
		}
	}
	//游戏继续
	void GameContinue()
	{
		//为了判断在键盘上按下的哪个键
		int ch1 = 0;
		int ch2 = 0;
		while (1)
		{
			if (ch1 = _getch())
			{
				ch2 = _getch();
				if (ch2 == 72)
				{
					MoveUp();
					break;
				}
				if (ch2 == 80)
				{
					MoveDown();
					break;
				}
				if (ch2 == 75)
				{
					MoveLeft();
					break;
				}
				if (ch2 == 77)
				{
					MoveRight();
					break;
				}
			}
		}
	}
	
	void game()
	{
		srand((unsigned int)time(NULL));
		ViewInit(20, 10);
		RandNum(ROW, COL);
		RandNum(ROW, COL);
		GamePrint(ROW, COL);
		while (1)
		{
			if (IfWin(ROW, COL) == 1)
			{
				printf("YOU WIN!\n");
				return;
			}
			else if (IfWin(ROW, COL) == -1)
			{
				printf("GAME OVER\n");
				return;
			}
			else
			{
				GameContinue();
				system("cls");
				RandNum(ROW, COL);
				GamePrint(ROW, COL);
			}
		}
	}
	
	int main()
	{
		game();
		system("pause");
		return 0;
	}

  • 15
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值