輕鬆玩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();
}
附:全部代碼打包