C语言写2048

1、ubuntu上的效果

注意:ubuntu上面的函数和win上面的函数可能有些不能兼容
如果要在win上面运行该代码需要进行相应改动
在这里插入图片描述
2048应该有很多同学都玩过,不过是否尝试过自己亲手写一个出来呢

2、重要的定义

这里的定义很关键
这些数组、变量都是程序中很重要的部分,会为后序编写代码带来很多方便之处

//此数组是2048的界面
char Interface[] =  "\
 `````````````````````\n\
 |    |    |    |    |\n\
 `````````````````````\n\
 |    |    |    |    |\n\
 `````````````````````\n\
 |    |    |    |    |\n\
 `````````````````````\n\
 |    |    |    |    |\n\
 `````````````````````\n";

char Random[5] = {2,4,4,2,8};       //随机数组
int zb_xy[] = {25, 30, 35, 40,      //一排下标
			   71, 76, 81, 86,      //二排下标
			   117,122,127,132,     //三排下标
			   163,168,173,178};    //四排下标
			   
int  num_all[16] = {0};				//临时存储每个坐标的数值数组
char buff_4[4] = {0};				//临时存储每一排的数值的字符型格式
int  score = 0;                     //计分变量

3、左移代码

上下左右移动的代码其实差不多,只是稍有逻辑改动,后面我会把整个工程代码贴出来


```c
void Move_Left(void)   						//左移函数
{
	char i,j,x,z;	
	char cnt_1 = 0;
	char cnt_2 = 0;
	
	update_num_all_buff();                  //更新临时存储每个坐标的数值数组
	
	for(x=0;x<4;x++)						//这个三重循环是为了寻找整个数组里面左右相等的数值
	{										//然后进行相加(注意:这里上下排的首变量和尾变量相邻
		for(i=0;i<4;i++)					//不会相加)
		{
			for(j=i+1;j<4;j++)
			{
				if(num_all[cnt_1+i] == num_all[cnt_1+j]&&num_all[cnt_1+i] != 0&&num_all[cnt_1+j] != 0)
				{
					num_all[cnt_1+i] = num_all[cnt_1+i]+num_all[cnt_1+j];
					num_all[cnt_1+j] = 0;
					score += num_all[cnt_1+i];		//更新计分变量
					break;
				}
				else if(num_all[cnt_1+i] != num_all[cnt_1+j]&&num_all[cnt_1+i] != 0&&num_all[cnt_1+j] != 0)
				{
					break;
				}
			}
		}
		cnt_1 += 4;
	}
	for(x=0;x<4;x++)					   	//循环四次,(4*4)遍历16个单元
	{
		for(i=0;i<4;i++)
		{
			if(num_all[cnt_2+i] == 0)
			{
				for(j=i+1;j<4;j++)
				{
					if(num_all[cnt_2+j] != 0)
					{
						for(z=0;z<4-j;z++)
						{
							num_all[cnt_2+i+z] = num_all[cnt_2+j+z];
							num_all[cnt_2+j+z] = 0;
						}
						break;
					}
				}
			}
		}
		cnt_2 += 4;
	}
	update_interface_buff();         //刷新游戏显示界面
}

4、设置输入Input无缓冲(ubuntu_base)

这一部分代码是设置键盘读取不存储在缓冲区内,也就是输入得到的数据不需要按下Enter键才能被读取

int getch(void)
{
     struct termios tm, tm_old;
     int fd = 0, ch;
 
     if (tcgetattr(fd, &tm) < 0) {//保存现在的终端设置
          return -1;
     }
 
     tm_old = tm;
     cfmakeraw(&tm);//更改终端设置为原始模式,该模式下所有的输入数据以字节为单位被处理
     if (tcsetattr(fd, TCSANOW, &tm) < 0) {//设置上更改之后的设置
          return -1;
     }
	 
     ch = getchar();
     if (tcsetattr(fd, TCSANOW, &tm_old) < 0) {//更改设置为最初的样子
          return -1;
     }
    
     return ch;
}

5、全部代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>    				
#include <termio.h>
#include <time.h>

char Interface[] =  "\
 `````````````````````\n\
 |    |    |    |    |\n\
 `````````````````````\n\
 |    |    |    |    |\n\
 `````````````````````\n\
 |    |    |    |    |\n\
 `````````````````````\n\
 |    |    |    |    |\n\
 `````````````````````\n";

char Random[5] = {2,4,4,2,8};       //随机数字
int zb_xy[] = {25, 30, 35, 40,      //一排下标
			   71, 76, 81, 86,      //二排下标
			   117,122,127,132,     //三排下标
			   163,168,173,178};    //四排下标
			   
int  num_all[16] = {0};
char buff_4[4] = {0};
int  score = 0;                     //计分变量

void Move_Left(void);	            //左移函数
void Move_Right(void);   		    //右移函数
void Move_Down(void);    			//下移函数
void Move_Up(void);                 //上移函数
void Random_Funcation(void);		//随机函数
void update_interface_buff(void);
void update_interface_only(char i);
void update_num_all_buff(void);     //刷新数组
int  getch(void);					//输入函数(无缓冲区)

void print_interface(void)
{
	printf("\033[H\033[J");
	printf("%s",Interface);
	printf("                 成绩: %d\n",score);
	printf("W(上)、S(下)\nA(左)、D(右)\nQ(退出)\n");
}

int main(void)
{
	char i = 0,j = 0;
	
	printf("\033[H\033[J");
	printf("%s",Interface);
	Random_Funcation();
	
	while(1)
	{
		j = 0;
		switch(getch())
		{
			case 'w':                     //Up
			case 'W':
				printf("\033[H\033[J");
				Move_Up();
				Random_Funcation();
				//print_num_all();
				break;
			case 's':					  //Down
			case 'S':
				printf("\033[H\033[J");
				Move_Down();    		  //下移函数
				Random_Funcation();
				break;
			case 'a':                     //Left
			case 'A':
				printf("\033[H\033[J");
				Move_Left();              //左移函数
				Random_Funcation();
				break;
			case 'd':                     //Right
			case 'D':
				printf("\033[H\033[J");
				Move_Right();
				Random_Funcation();
				break;
			case 'q':
			case 'Q':
				return 0;
			default:
				{
					printf("Press error,please again!\n");
				}
		}
		for(i=0;i<16;i++)
			if(num_all[i] == 0)
			{
				j++;
			}
		if(j == 0)
		{
			printf("############Game over!############\n");
			return 0;
		}
	}
}


void update_interface_buff(void)
{
	char i,j,z;	
	int x;
	
	for(i=0;i<16;i++)
	{
		j=3;
		x = num_all[i];
		while(1)
		{
			if(x)
			{
				buff_4[j--] = x%10;
				x = x/10;
			}
			else
			{
				for(;j>=0;j--)
					buff_4[j] = ' ';
				break;
			}
		}
		for(j=0,z=0;j<4;j++)
		{
			if(buff_4[j] != ' ')
			{
				Interface[zb_xy[i]+z] = buff_4[j]+'0';
				z++;
			}
			else 
				Interface[zb_xy[i]+3-j] = ' ';
		}
	}
	print_interface();
}

void update_interface_only(char i)
{
	char j,z;	
	int x;
	
	j=3;
	x = num_all[i];
	while(1)
	{
		if(x)
		{
			buff_4[j--] = x%10;
			x = x/10;
		}
		else
		{
			for(;j>=0;j--)
				buff_4[j] = ' ';
			break;
		}
	}
	for(j=0,z=0;j<4;j++)
	{
		if(buff_4[j] != ' ')
		{
			Interface[zb_xy[i]+z] = buff_4[j]+'0';
			z++;
		}
		else 
			Interface[zb_xy[i]+3-j] = ' ';
	}
	print_interface();
}

void update_num_all_buff(void)                //刷新数组
{ 
	char i,x,z;	
	int  j;
	for(i=0; i<16; i++)
	{
		j = 0;
		if(Interface[zb_xy[i]] == ' ')
		{
			num_all[i] = 0;
			continue;
		}
		for(z=3,x=3;z>=0;z--)
		{
			if(Interface[zb_xy[i]+z] != ' ')
			{
				j = j + ((Interface[zb_xy[i]+z]-48)*pow(10,3-x));
				x--;
			}
		}
		num_all[i] = j;
	}
}

void Random_Funcation(void)					   //随机函数
{
	char i ,z;
	
	srand(time(NULL));
	
	while(1)
	{
		z = rand()%16;
		
		if(num_all[z] == 0)
			break;
		else
			continue;
	}
	num_all[z] = Random[rand()%5];
	update_interface_only(z);
}

void Move_Left(void)   						//左移函数
{
	char i,j,x,z;	
	char cnt_1 = 0;
	char cnt_2 = 0;
	
	update_num_all_buff();
	
	for(x=0;x<4;x++)
	{
		for(i=0;i<4;i++)
		{
			for(j=i+1;j<4;j++)
			{
				if(num_all[cnt_1+i] == num_all[cnt_1+j]&&num_all[cnt_1+i] != 0&&num_all[cnt_1+j] != 0)
				{
					num_all[cnt_1+i] = num_all[cnt_1+i]+num_all[cnt_1+j];
					num_all[cnt_1+j] = 0;
					score += num_all[cnt_1+i];
					break;
				}
				else if(num_all[cnt_1+i] != num_all[cnt_1+j]&&num_all[cnt_1+i] != 0&&num_all[cnt_1+j] != 0)
				{
					break;
				}
			}
		}
		cnt_1 += 4;
	}
	for(x=0;x<4;x++)					   //循环四次,(4*4)遍历16个单元
	{
		for(i=0;i<4;i++)
		{
			if(num_all[cnt_2+i] == 0)
			{
				for(j=i+1;j<4;j++)
				{
					if(num_all[cnt_2+j] != 0)
					{
						for(z=0;z<4-j;z++)
						{
							num_all[cnt_2+i+z] = num_all[cnt_2+j+z];
							num_all[cnt_2+j+z] = 0;
						}
						break;
					}
				}
			}
		}
		cnt_2 += 4;
	}
	update_interface_buff();
}

void Move_Right(void)    //右移函数
{
	char i,j,x,z;	
	char cnt_1 = 0;
	char cnt_2 = 0;
	
	update_num_all_buff();
	
	for(x=0;x<4;x++)
	{
		for(i=0;i<4;i++)
		{
			for(j=i+1;j<4;j++)
			{
				if(num_all[cnt_1+i] == num_all[cnt_1+j]&&num_all[cnt_1+i] != 0&&num_all[cnt_1+j] != 0)
				{
					num_all[cnt_1+j] = num_all[cnt_1+i]+num_all[cnt_1+j];
					num_all[cnt_1+i] = 0;
					score += num_all[cnt_1+j];
					break;
				}
				else if(num_all[cnt_1+i] != num_all[cnt_1+j]&&num_all[cnt_1+i] != 0&&num_all[cnt_1+j] != 0)
				{
					break;
				}
			}
		}
		cnt_1 += 4;
	}
	for(x=0;x<4;x++)//循环四次,(4*4)遍历16个单元
	{
		for(i=3;i>=0;i--)
		{
			if(num_all[cnt_2+i] == 0)
			{
				for(j=i-1;j>=0;j--)
				{
					if(num_all[cnt_2+j] != 0)
					{
						for(z=0;z<j+1;z++)
						{
							num_all[cnt_2+i-z] = num_all[cnt_2+j-z];
							num_all[cnt_2+j-z] = 0;
						}
						break;
					}
				}
			}
		}
		cnt_2 += 4;
	}
	update_interface_buff();	
}

void Move_Up(void)    //上移函数
{
	char i,j,x,z;	
	char cnt_1 = 0;
	char cnt_2 = 0;
	
	update_num_all_buff();
	
	for(x=0;x<4;x++)
	{
		for(i=0;i<16;i+=4)
		{
			for(j=i+4;j<16;j+=4)
			{
				if(num_all[cnt_1+i] == num_all[cnt_1+j]&&num_all[cnt_1+i] != 0&&num_all[cnt_1+j] != 0)
				{
					num_all[cnt_1+i] = num_all[cnt_1+i]+num_all[cnt_1+j];
					num_all[cnt_1+j] = 0;
					score += num_all[cnt_1+i];
					break;
				}
				else if(num_all[cnt_1+i] != num_all[cnt_1+j]&&num_all[cnt_1+i] != 0&&num_all[cnt_1+j] != 0)
				{
					break;
				}
			}
		}
		cnt_1 += 1;
	}
	for(x=0;x<4;x++)//循环四次,(4*4)遍历16个单元
	{
		for(i=0;i<16;i+=4)
		{
			if(num_all[cnt_2+i] == 0)
			{
				for(j=i+4;j<16;j+=4)
				{
					if(num_all[cnt_2+j] != 0)
					{
						for(z=0;z<(4-(j/4));z++)
						{
							num_all[cnt_2+i+4*z] = num_all[cnt_2+j+4*z];
							num_all[cnt_2+j+4*z] = 0;
						}
						break;
					}
				}
			}
		}
		cnt_2 += 1;
	}
	update_interface_buff();
}

void Move_Down(void)    //下移函数
{
	char i,j,x,z;	
	char cnt_1 = 0;
	char cnt_2 = 0;
	
	update_num_all_buff();
	
	for(x=0;x<4;x++)
	{
		for(i=12;i>=0;i-=4)
		{
			for(j=i-4;j>=0;j-=4)
			{
				if(num_all[cnt_1+i] == num_all[cnt_1+j]&&num_all[cnt_1+i] != 0&&num_all[cnt_1+j] != 0)
				{
					num_all[cnt_1+i] = num_all[cnt_1+i]+num_all[cnt_1+j];
					num_all[cnt_1+j] = 0;
					score += num_all[cnt_1+i];
					break;
				}
				else if(num_all[cnt_1+i] != num_all[cnt_1+j]&&num_all[cnt_1+i] != 0&&num_all[cnt_1+j] != 0)
				{
					break;
				}
			}
		}
		cnt_1 += 1;
	}
	for(x=0;x<4;x++)//循环四次,(4*4)遍历16个单元
	{
		for(i=12;i>=0;i-=4)
		{
			if(num_all[cnt_2+i] == 0)
			{
				for(j=i-4;j>=0;j-=4)
				{
					if(num_all[cnt_2+j] != 0)
					{
						for(z=0;z<((j/4)+1);z++)
						{
							num_all[cnt_2+i-4*z] = num_all[cnt_2+j-4*z];
							num_all[cnt_2+j-4*z] = 0;
						}
						break;
					}
				}
			}
		}
		cnt_2 += 1;
	}
	update_interface_buff();
}

int getch(void)
{
     struct termios tm, tm_old;
     int fd = 0, ch;
 
     if (tcgetattr(fd, &tm) < 0) {//保存现在的终端设置
          return -1;
     }
 
     tm_old = tm;
     cfmakeraw(&tm);//更改终端设置为原始模式,该模式下所有的输入数据以字节为单位被处理
     if (tcsetattr(fd, TCSANOW, &tm) < 0) {//设置上更改之后的设置
          return -1;
     }
	 
     ch = getchar();
     if (tcsetattr(fd, TCSANOW, &tm_old) < 0) {//更改设置为最初的样子
          return -1;
     }
    
     return ch;
}

各位看官,如有不足之处多多指出…

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

思识己

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值