Linux字符版2048小游戏开发

轻松玩Linux,从写个2048玩玩开始,不多说,有注解有代码,就差你了,快上车!

1.简介:Linux上的2048;写个2048代码还能玩到2048,那你就是写得了代码,玩得了2048的2048程序员了。

2.准备:电脑有Linux系统就可以了,gcc,编辑器任意;

3.原理:主要是对一个4*4的数组的操作处理,还需要用到字符的输出显示,键盘输入的获取;

4.展示一下:

5.动手:

a.显示内容:

a1.打开屏幕,关闭屏幕

void open_screen(void)
{
	initscr(); //初始化字符屏幕
	cbreak(); //Ctrl + c
	noecho(); //不用回显 
	keypad(stdscr, TRUE); //使用功能键

}
void close_screen(void)
{
	endwin(); //关闭字符窗口
}

 a2.初始化一个放数组的窗口:

WINDOW *w_2048=NULL;

void init_window()
{
	w_2048 = newwin(4, 24, w_2048_y0, w_2048_x0);
}

a3.在刚刚的窗口内显示内容:

void init_window_h(void)
{
	w_2048 = newwin(2, 24, 4, 40);
	//指定位置显示字符
	wmove(w_2048, 0,5 ); 
	waddstr(w_2048,"hello 2048!");
	wmove(w_2048, 1,3 ); 
	waddstr(w_2048,"designed by lin");
	wrefresh(w_2048);
}

b.获取键盘输入:

#define LEFT 1
#define RIGHT 2
#define UP 3
#define DOWN 4
#define QUIT 10

int get_user_input()
{
	keypad(w_2048,true);//打开功能键(方向键等)
	int ch=wgetch(w_2048);
	keypad(w_2048,false);//功取消能键
	if(ch=='Q'||ch=='q')
		return QUIT;
	if(ch=='W'||ch=='w'||ch==KEY_UP)
		return UP;
	if(ch=='S'||ch=='s'||ch==KEY_DOWN)
		return DOWN;
	if(ch=='A'||ch=='a'||ch==KEY_LEFT)
		return LEFT;
	if(ch=='D'||ch=='d'||ch==KEY_RIGHT)
		return RIGHT;
	
}

c.数组处理:

随机数随机填充:

#define N 4
int matrix_2048[N][N]={
	0,0,0,0,
	0,0,0,0,
	0,0,0,0,
	0,0,0,0
};
void fill_a_number(void)
{
	srandom(time(NULL));//设置随机数种子
	//long int random();
	int k=random();
	k=k%4;
	int p=random();
	p=p%4;
	
	for(int i=0;i<4;i++)	//获取是否还有0
	for(int j=0;j<4;j++)
		if(matrix_2048[i][j]==0)
		num++;
	if(num==0)
		return;
	while(matrix_2048[k][p]!=0)
	{
		k=random();
		k=k%4;
		p=random();
		p=p%4;
	}
	
		int m=random();
		m=m%5;
		while(m==0||m==1||m==3)
		{
			m=random();
			m=m%5;
		}
		matrix_2048[k][p]=m;
}
void draw_matrix(void)
{

	fill_a_number();	//随机在0的位置填充一个数
	for(int i=0;i<4;i++)
	{
		for(int j=0;j<4;j++)
		{
			wmove(w_2048, i,j*6 ); 
			char buf[6];
			sprintf(buf,"%d",matrix_2048[i][j]);
			waddstr(w_2048,buf);
		}
	}
	wrefresh(w_2048);	
}

方法一:思想比较简单,就是每次都先去0,再合成,再去0;

void left_zero()//左移去0
{
	int m,n;
	for(m=0;m<4;m++)	//移动0
		{
			int a[4]={0,0,0,0},k=0;
			for(n=0;n<4;n++)
			{
				if(matrix_2048[m][n]!=0)
				{
					a[k]=matrix_2048[m][n];
					k++;
				}
			}
			for(n=0;n<4;n++)
			{
				matrix_2048[m][n]=a[n];
			}
		}
}
	int m=0,n=0;
	if(Ku==LEFT)
	{				
		for(m=0;m<4;m++)//计算
			for(n=0;n<4;n++)
			{
				left_zero();
			
				if(n+1<4&&matrix_2048[m][n+1]==matrix_2048[m][n])
				{
					matrix_2048[m][n]+=matrix_2048[m][n+1];
					matrix_2048[m][n+1]=0;
					sadd+=matrix_2048[m][n];
				}
			}
	}
while(1)
	{
		//获取键盘操作,对相应方向的数值比较运算,计算出分数
		int mv=get_user_input();

		if(mv==QUIT)//操作退出
			break;
		int chan=change_matrix(mv);//更改矩阵,改变=0,不改变=1,用来判断是否有效滑动

		int cheak=0;//判断邻近是否有相同字符
		for(int i=0;i<3;i++)
			for(int j=0;j<3;j++)
			{
				if(matrix_2048[i][j]==matrix_2048[i][j+1]||matrix_2048[i][j]==matrix_2048[i+1][j])
					cheak++;
			}
		for(int i=0;i<3;i++)
			if(matrix_2048[3][i]==matrix_2048[3][i+1])
				cheak++;
		for(int i=0;i<3;i++)
			if(matrix_2048[i][3]==matrix_2048[i+1][3])
				cheak++;
		for(int i=0;i<4;i++)//判断有没有0
			for(int j=0;j<4;j++)
			{
				if(matrix_2048[i][j]==0)
					cheak++;
			}
		if(cheak==0)	//判断结束,没有0字符,没有邻近相同字符
			break;
		if(chan==1)	//判断滑动是否有效
			continue;
		init_window();
		init_window_s();//分数窗口
		//显示数字矩阵
		draw_matrix();
	}

方法二:快捷:

//向左滑动 矩阵matrix_2048
void move_left()
{	
	int i;
	int x;
	int m;
	int k;

	for (i = 0; i < N; i++)
	{
		//matrix_2048[i]第i行
		m = 0;
		x = 0;
		for (k = 0; k < N; k++)
		{
			if (matrix_2048[i][k] != 0)
			{
				if (x == 0)
				{
					x =	matrix_2048[i][k];
					matrix_2048[i][k] = 0;
				}
				else
				{
					if (matrix_2048[i][k] == x)
					{
						//合并,再移动
						x = x + matrix_2048[i][k];
						matrix_2048[i][k] = 0;
						matrix_2048[i][m++] = x;
						x = 0;
					}
					else
					{	
						//相邻但不相等
						//先移动x,然后把matrix[i][k]->x
						matrix_2048[i][m++] = x;
						x = matrix_2048[i][k];
						matrix_2048[i][k] = 0;
					}
				}
			}
		}
		matrix_2048[i][m++] = x;
	}
	
}
if (mv == LEFT)
	{
		move_left();
	}

 

d.判断结束:

条件满足:1.字符的右、下没有相同字符   2.没有0字符,同时满足即调转结束;

e.积分数:每次有合成即对分数增加

6.主代码:

#include <curses.h>		//随机数random
#include<time.h>
#include<stdlib.h>

#include"input.h"

//指向标题窗口
WINDOW *w_2048_h=NULL;


//指向数字窗口
WINDOW *w_2048=NULL;

//指向得分窗口
WINDOW *w_score = NULL;

//结束窗口
WINDOW *w_2048_over=NULL;


//窗口w_2048,左上顶点的坐标,在第几行,第几列
int w_2048_y0 = 4;
int w_2048_x0 = 40;


#define N 4
int matrix_2048[N][N]={
	0,0,0,0,
	0,0,0,0,
	0,0,0,0,
	0,0,0,0
};


//标题窗口
void init_window_h(void)
{
	w_2048_h = newwin(2, 24, 1, 39);

	//显示字符
	wmove(w_2048_h, 0,5 ); //
	waddstr(w_2048_h,"hello 2048!");
	wmove(w_2048_h, 1,3 ); //
	waddstr(w_2048_h,"designed by lin");
	wrefresh(w_2048_h);
}

//分数窗口
int sco=0,sadd=0;
void init_window_s(void)
{
	sco+=sadd;
	w_score = newwin(2, 24, 5, 20);

	//显示字符
	wmove(w_score, 0,5 ); //
	waddstr(w_score,"score  ");
	wmove(w_score, 1,5 ); //
	char buf[6]="";
	sprintf(buf,"%d",sco);
	waddstr(w_score,buf);
	wrefresh(w_score);
	sadd=0;
}

int num=0;

void init_window()
{
	w_2048 = newwin(4, 24, w_2048_y0, w_2048_x0);
}

void fill_a_number(void)
{
	srandom(time(NULL));//设置随机数种子
	//long int random();
	int k=random();
	k=k%4;
	int p=random();
	p=p%4;
	
	for(int i=0;i<4;i++)	//获取是否还有0
	for(int j=0;j<4;j++)
		if(matrix_2048[i][j]==0)
		num++;
	if(num==0)
		return;
	while(matrix_2048[k][p]!=0)
	{
		k=random();
		k=k%4;
		p=random();
		p=p%4;
	}
	
		int m=random();
		m=m%5;
		while(m==0||m==1||m==3)
		{
			m=random();
			m=m%5;
		}
		matrix_2048[k][p]=m;
}

void draw_matrix(void)
{

	fill_a_number();	//随机在0的位置填充一个数
	for(int i=0;i<4;i++)
	{
		for(int j=0;j<4;j++)
		{
			wmove(w_2048, i,j*6 ); 
			char buf[6];
			sprintf(buf,"%d",matrix_2048[i][j]);
			waddstr(w_2048,buf);
		}
	}
	wrefresh(w_2048);	
}

void left_zero()//左移去0
{
	int m,n;
	for(m=0;m<4;m++)	//移动0
		{
			int a[4]={0,0,0,0},k=0;
			for(n=0;n<4;n++)
			{
				if(matrix_2048[m][n]!=0)
				{
					a[k]=matrix_2048[m][n];
					k++;
				}
			}
			for(n=0;n<4;n++)
			{
				matrix_2048[m][n]=a[n];
			}
		}
}
void right_zero()//右移去0
{
	int m,n;
	for(m=0;m<4;m++)
			{
				int a[4]={0,0,0,0},k=3;
				for(n=3;n>=0;n--)
				{
					if(matrix_2048[m][n]!=0)
					{
						a[k]=matrix_2048[m][n];
						k--;
					}
				}
				for(n=0;n<4;n++)
				{
					matrix_2048[m][n]=a[n];
				}
			}
}
void up_zero()//上移去0
{
	int m,n;
	for(n=0;n<4;n++)
		{
			int a[4]={0,0,0,0},k=0;
			for(m=0;m<4;m++)
			{
				if(matrix_2048[m][n]!=0)
				{
					a[k]=matrix_2048[m][n];
					k++;
				}
			}
			for(m=0;m<4;m++)
			{
				matrix_2048[m][n]=a[m];
			}
		}
}
void down_zero()//下移去0
{
	int m,n;
	for(n=0;n<4;n++)
		{
			int a[4]={0,0,0,0},k=3;
			for(m=3;m>=0;m--)
			{
				if(matrix_2048[m][n]!=0)
				{
					a[k]=matrix_2048[m][n];
					k--;
				}
			}
			for(m=3;m>=0;m--)
			{
				matrix_2048[m][n]=a[m];
			}
		}
}



int change_matrix(int Ku)
{
	int matrix[N][N]={
	0,0,0,0,
	0,0,0,0,
	0,0,0,0,
	0,0,0,0
	};
	for(int m=0;m<4;m++)//保存
		for(int n=0;n<4;n++)
		{
			matrix[m][n]=matrix_2048[m][n];
		}
	int m=0,n=0;
	if(Ku==LEFT)
	{				
		for(m=0;m<4;m++)//计算
			for(n=0;n<4;n++)
			{
				left_zero();
			
				if(n+1<4&&matrix_2048[m][n+1]==matrix_2048[m][n])
				{
					matrix_2048[m][n]+=matrix_2048[m][n+1];
					matrix_2048[m][n+1]=0;
					sadd+=matrix_2048[m][n];
				}
			}
	}
	if(Ku==RIGHT)
	{
		
		for(m=0;m<4;m++)
			for(n=3;n>=0;n--)
			{
				right_zero();
				
				if(n-1>=0&&matrix_2048[m][n-1]==matrix_2048[m][n])
				{
					matrix_2048[m][n]+=matrix_2048[m][n-1];
					matrix_2048[m][n-1]=0;
					sadd+=matrix_2048[m][n];
				}				
			}
	}
	if(Ku==UP)
	{
		
		for(n=0;n<4;n++)
			for(m=0;m<4;m++)
			{
				up_zero();
				if(m+1<4&&matrix_2048[m+1][n]==matrix_2048[m][n])
				{
					matrix_2048[m][n]+=matrix_2048[m+1][n];
					matrix_2048[m+1][n]=0;
					sadd+=matrix_2048[m][n];
				}				
			}
	}
	if(Ku==DOWN)
	{
		
		for(n=0;n<4;n++)
			for(m=3;m>=0;m--)
			{
				down_zero();
				if(m-1>=0&&matrix_2048[m-1][n]==matrix_2048[m][n])
				{
					matrix_2048[m][n]+=matrix_2048[m-1][n];
					matrix_2048[m-1][n]=0;
					sadd+=matrix_2048[m][n];
				}					
			}
	}

	//判断数组是否改变
	for(m=0;m<4;m++)
		for(n=0;n<4;n++)
		{
			if(matrix[m][n]!=matrix_2048[m][n])
				return 0;
		}
	return 1;
}

void game_over()
{
	w_2048_over = newwin(2, 24, 1, 10);
	//显示结束字符
	wmove(w_2048_over, 0,5 ); //
	waddstr(w_2048_over,"game over !");
	wrefresh(w_2048_over);	
}
//2048游戏的主循环
void game_2048(void)
{
	//初始化一个数字矩阵窗口
	init_window();
	
	init_window_h();//标题窗口

	init_window_s();//分数窗口

	//显示数字矩阵
	draw_matrix();

	while(1)
	{
		//获取键盘操作,对相应方向的数值比较运算,计算出分数
		int mv=get_user_input();

		if(mv==QUIT)//操作退出
			break;
		int chan=change_matrix(mv);//更改矩阵,改变=0,不改变=1,用来判断是否有效滑动

		int cheak=0;//判断邻近是否有相同字符
		for(int i=0;i<3;i++)
			for(int j=0;j<3;j++)
			{
				if(matrix_2048[i][j]==matrix_2048[i][j+1]||matrix_2048[i][j]==matrix_2048[i+1][j])
					cheak++;
			}
		for(int i=0;i<3;i++)
			if(matrix_2048[3][i]==matrix_2048[3][i+1])
				cheak++;
		for(int i=0;i<3;i++)
			if(matrix_2048[i][3]==matrix_2048[i+1][3])
				cheak++;
		for(int i=0;i<4;i++)//判断有没有0
			for(int j=0;j<4;j++)
			{
				if(matrix_2048[i][j]==0)
					cheak++;
			}
		if(cheak==0)	//判断结束,没有0字符,没有邻近相同字符
			break;
		if(chan==1)	//判断滑动是否有效
			continue;
		init_window();
		init_window_s();//分数窗口
		//显示数字矩阵
		draw_matrix();
	}

	while(1)
	game_over();

}

附:全部代码打包 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Super algorithm

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

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

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

打赏作者

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

抵扣说明:

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

余额充值