C语言-------2048游戏(linux环境)

2048最核心的应该是合并的部分,一开始不知道怎么4行往一个方向合并,就想着那就先把一行的合并搞定.只要实现一个一维数组往同一个方向合并,之后慢慢扩展就可以了.

  • 实现一行合并的代码
#include <stdio.h>

int main(){
	
	int a[4]={2,0,2,0};
	
	int i;
	int n=3;
	while(n--){											
		for(i=0;i<3;i++){		//删除中间的0,创造合并条件
			if(a[i]==0){
				a[i]=a[i+1];	
				a[i+1]=0;
			}
		}	
	}
	n=3;
	for(i=0;i<3;i++){		 	//同时合并,合并之后,可能会产生0
		if(a[i]==a[i+1]){		//比如一开始是{2,2,2,2},合并后是{4,0,4,0}
			a[i]+=a[i+1];
			a[i+1]=0;
		}
	}
	while(n--){						//删除中间的0			
		for(i=0;i<3;i++){
			if(a[i]==0){
				a[i]=a[i+1];
				a[i+1]=0;
			}
		}	
	}
	n=3;

	for(i=0;i<4;i++){
		printf("%d",a[i]);
	}
	return 0;
} 
  • 完整代码

一.主函数

main.c

#include <stdio.h>
#include "draw.h"
#include "control.h"
#include "game.h"

int main(void){

    int box[4][4]={0};
    int step=0;
    int score=0;
    int dir; 
    int result;
    int state=0;
    srand(time(NULL));
    rand_init(box);                 //在界面上随机生成2个数字,2或4 
    while(1){    
        draw_from(box,step,score);  //刷新界面 
        if(state==1){
            printf("YOU WIN!\n");
            break;
        }
        dir = user_command();       //等待按键输入 
        if (dir == 4){              //回车结束游戏 
            break;
        }
        else if(dir==5){            //其他按键,返回刷新界面 
            continue; 
        } 
        else{                       //上下左右 
            result=merge(box,dir);
            state=check(box);       //检查输赢状态 
            if(result==-1){         //无效移动 
                if(state==-1){
                    printf("GAME OVER!\n");
                    break;
                }
                else{
                    continue;
                }
            } 
            else{                   //有效移动,计算得分和步数 
                score+=result;
                step++;
                randnumber(box,result); //生成随机数2或4 
            }
        } 

    }   
    return 0; 
}       

二.界面绘制

draw.c

#include <stdio.h> 

void draw_from(int box[4][4],int step,int score);

void draw_from(int box[4][4],int step,int score){
    int i,j;
    int x=0,y=0;
    printf("\033[2J");
    printf("steps:   %d\n",step);
    printf("scores:  %d\n",score);
    for(i=0;i<=16;i++){
        for(j=0;j<=32;j++){
            if(i%4==0){
                if(j%8==0){
                    printf("\033[42;33m+\033[0m");
                }
                else{
                    printf("\033[42;33m-\033[0m"); 
                } 
            }
            else if(i%2==1){
                if(j%8==0){
                    printf("\033[42;33m|\033[0m");
                }
                else{
                    printf(" ");
                } 
            }   
            else if(i%2==0){
                if(j%8==0){
                    printf("\033[42;33m|\033[0m");  //可以改颜色 
                }
                else if(j%8==3){
                    if(box[x][y]==0){
                        y++;
                        printf(" \t");
                    }
                    else{
                        printf("  \033[0;33m%d\t\033[0m",box[x][y++]);
                    }
                    if(y==4){
                        x++;
                        y=0;
                    }
                }
                else;
            } 
            else; 
        }   
        printf("\n\033[?25l"); 
    }   
}


头文件
draw.h

#ifndef _DRAW_H
#define _DRAW_H

extern void draw_from(int box[4][4],int step,int score); 

#endif

三.键盘操作控制

control.c

#include <stdio.h>
#include <termios.h> 
#include <unistd.h>
#include <assert.h>
#include <string.h>

int user_command(void);
char my_getch();

int user_command(){
    
    char ch = my_getch();
    if (ch == 27)
    {
        ch = my_getch();
        if (ch == 91)
        {
            ch = my_getch();
            switch(ch){
                case 65: return 0;break;
                case 66: return 1;break;
                case 67: return 2;break;
                case 68: return 3;break;
            }
                
        }
    }
    else if(ch == '\n')
    {   
        return 4;
    }
    else{
        return 5;
    }
}
char my_getch()
{
        int c=0;  int res=0;
        struct termios org_opts, new_opts;
        res=tcgetattr(STDIN_FILENO, &org_opts);
        assert(res==0);
        memcpy(&new_opts, &org_opts, sizeof(new_opts));
        new_opts.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOKE | ICRNL);
        tcsetattr(STDIN_FILENO, TCSANOW, &new_opts);
        c=getchar();//
        res=tcsetattr(STDIN_FILENO, TCSANOW, &org_opts);
        assert(res==0);
        return c;
}

头文件
control.h

#ifndef _DRAW_H
#define _DRAW_H

extern int user_command(void);
extern char my_getch();

#endif

四.游戏过程

game.c

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

void rand_init(int (*box)[4]);
int merge(int (*box)[4], int dir);
int up(int (*box)[4],int dir,int (*temp)[4]);
int down(int (*box)[4],int dir,int (*temp)[4]);
int left(int (*box)[4],int dir,int (*temp)[4]);
int right(int (*box)[4],int dir,int (*temp)[4]);
void randnumber(int (*box)[4],int result);
int check(int (*box)[4]);
void copy_box(int (*box)[4],int (*temp)[4]); 
int compare_box(int (*box)[4],int (*temp)[4]); 
    
void rand_init(int (*box)[4]){   

    randnumber(box,0); 
    randnumber(box,0);
    
    return ;
}
int merge(int (*box)[4], int dir){
    
    int temp[4][4];
    int score;
    copy_box(box,temp); 
    
    switch(dir){
        case 0:             //上 
            score=up(box,dir,temp);
            return score;
            break;
        case 1:             //下 
            score=down(box,dir,temp);
            return score;
            break;
        case 2:             //右
            score=right(box,dir,temp);      
            return score;
            break;
        case 3:             //左 
            score=left(box,dir,temp);
            return score;
            break;  
    }
    
}
int up(int (*box)[4],int dir,int (*temp)[4]){
    
    int i,j;
    int n;
    int t;
    int score=0;
    
    for(j=0;j<4;j++){
        n=3;
        while(n--){
            for(i=0;i<3;i++){
                if(box[i][j]==0){
                    box[i][j]=box[i+1][j];
                    box[i+1][j]=0;
                }
            }   
        }
        for(i=0;i<3;i++){
            if(box[i][j]==box[i+1][j]){
                box[i][j]+=box[i+1][j];
                score+=box[i][j];
                box[i+1][j]=0;
            }
        }   
        n=3;
        while(n--){
            for(i=0;i<3;i++){
                if(box[i][j]==0){
                    box[i][j]=box[i+1][j];
                    box[i+1][j]=0;
                }
            }   
        }
    }
    t=compare_box(box,temp);
    if(t==-1){
        return -1;
    }
    else{
        return score;   
    }   

}
int down(int (*box)[4],int dir,int (*temp)[4]){
    
    int i,j;    
    int n;
    int t;
    int score=0;
    
    for(j=0;j<4;j++){
        n=3;
        while(n--){
            for(i=3;i>0;i--){
                if(box[i][j]==0){
                    box[i][j]=box[i-1][j];
                    box[i-1][j]=0;
                }
            }   
        }
        for(i=3;i>0;i--){
            if(box[i][j]==box[i-1][j]){
                box[i][j]+=box[i-1][j];
                score+=box[i][j];
                box[i-1][j]=0;
            }
        }   
        n=3;
        while(n--){
            for(i=3;i>0;i--){
                if(box[i][j]==0){
                    box[i][j]=box[i-1][j];
                    box[i-1][j]=0;
                }
            }   
        }
    }
    t=compare_box(box,temp);
    if(t==-1){
        return -1;
    }
    else{
        return score;   
    }   
}
int left(int (*box)[4],int dir,int (*temp)[4]){
    
    int i,j;    
    int n;
    int t;
    int score=0;
    
    for(i=0;i<4;i++){
        n=3;
        while(n--){
            for(j=0;j<3;j++){                       //删除0 ,创造合并条件 
                if(box[i][j]==0){
                    box[i][j]=box[i][j+1];
                    box[i][j+1]=0;
                }
            }   
        }
        for(j=0;j<3;j++){                           //合并 ,合并必会产生0 
            if(box[i][j]==box[i][j+1]){
                box[i][j]+=box[i][j+1];
                score+=box[i][j];                   //和并分数 
                box[i][j+1]=0;
            }
        }
        n=3;                                        
        while(n--){                                 //删除0 
            for(j=0;j<3;j++){
                if(box[i][j]==0){
                    box[i][j]=box[i][j+1];
                    box[i][j+1]=0;
                }
            }   
        }
    }
    t=compare_box(box,temp);
    if(t==-1){
        return -1;
    }
    else{
        return score;   
    }   
}
int right(int (*box)[4],int dir,int (*temp)[4]){
    
    int i,j;    
    int n;
    int t;
    int score=0;
    
    for(i=0;i<4;i++){
        n=3;
        while(n--){
            for(j=3;j>0;j--){
                if(box[i][j]==0){
                    box[i][j]=box[i][j-1];
                    box[i][j-1]=0;
                }
            }   
        }
        for(j=3;j>0;j--){
            if(box[i][j]==box[i][j-1]){
                box[i][j]+=box[i][j-1];
                score+=box[i][j];
                box[i][j-1]=0;
            }
        }   
        n=3;
        while(n--){
            for(j=3;j>0;j--){
                if(box[i][j]==0){
                    box[i][j]=box[i][j-1];
                    box[i][j-1]=0;
                }
            }   
        }
    }   
    t=compare_box(box,temp);
    if(t==-1){
        return -1;
    }
    else{
        return score;   
    }   
}
void randnumber(int (*box)[4],int result){
    int x;
    int y;
    int whitch; 
    
    if(result>=0){     //有效移动,产生随机数 
        
        do{                     //随机找到空的格子 
            x=rand()%4;
            y=rand()%4;
        }while(box[x][y]!=0); 
        
        whitch=rand()%10;
        if(whitch<9){           //90%概率生成2 
            box[x][y]=2;
        }
        else{
            box[x][y]=4;        //10%概率生成4 
        } 
    } 
    return ;
} 
int check(int (*box)[4]){
    
    int i,j;
    
    for(i=0;i<4;i++){                   //检查是否出现2048 
        for(j=0;j<4;j++){
            if(box[i][j]==2048){
                return 1;
            }   
        }
    
    }
    for(i=0;i<4;i++){                   //横向检查 
        for(j=0;j<3;j++){
            if(box[i][j]==box[i][j+1] || box[i][j]==0 || box[i][j+1]==0){
                return 0;
            }   
        }
    
    }
    for(j=0;j<4;j++){                   //纵向检查 
        for(i=0;i<3;i++){
            if(box[i][j]==box[i+1][j]){
                return 0;
            }   
        }
    }   
    
    return -1;
}
void copy_box(int (*box)[4],int (*temp)[4]){
    
    int i,j;
    for(i=0;i<4;i++){
        for(j=0;j<4;j++){
            temp[i][j]=box[i][j];
        }
    }
} 
int compare_box(int (*box)[4],int (*temp)[4]){  
    
    int i,j;
    for(i=0;i<4;i++){
        for(j=0;j<4;j++){
            if(temp[i][j]!=box[i][j]){
                return 1;                       //不一样,有效移动 
            }   
        }
    }
    return -1;
}

头文件
game.h

#ifndef _DRAW_H
#define _DRAW_H

extern void rand_init(int (*box)[4]);
extern int merge(int (*box)[4], int dir);
extern int up(int (*box)[4],int dir,int (*temp)[4]);
extern int down(int (*box)[4],int dir,int (*temp)[4]);
extern int left(int (*box)[4],int dir,int (*temp)[4]);
extern int right(int (*box)[4],int dir,int (*temp)[4]);
extern void randnumber(int (*box)[4],int result);
extern int check(int (*box)[4]);
extern void copy_box(int (*box)[4],int (*temp)[4]); 
extern int compare_box(int (*box)[4],int (*temp)[4]); 

#endif

五.游戏截图

界面简陋了一点😁
游戏结束:
在这里插入图片描述
合成2048:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值