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();

}

附:全部代碼打包 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章