linux下实现的2048游戏示例

my2048.c

代码如下:

#include"my_getch.h"

#include"math.h"

#include"time.h"

#define SPACE() printf(" ")

#define RED_NUM(n) printf("33[;31m%4d",(n))

#define GREEN_NUM(n) printf("33[;32m%4d",(n))

#define BLUE_NUM(n) printf("33[;34m%4d",(n))

#define YELLOW_NUM(n) printf("33[;33m%4d",(n))

#define PURPLE_NUM(n) printf("33[;35m%4d",(n))

#define DEEPGREEN_NUM(n) printf("33[;36m%4d",(n))

/*根据不同的number进行不同的宏替换,输出不同颜色的数字*/

void printNum(const int num)

{

if(num==0)

SPACE();

else if(num==1024 || num==32)

RED_NUM(num);

else if(num==2 || num==64 )

BLUE_NUM(num);

else if(num==4 || num==128)

GREEN_NUM(num);

else if(num==8 || num==256)

YELLOW_NUM(num);

else if(num==16 || num==512)

PURPLE_NUM(num);

else

DEEPGREEN_NUM(num);

}

enum game_stat{PLAYING,FAILED,EXITED,DONE};

enum cmd{UP,DOWN,LEFT,RIGHT,QUIT,INVALID};

enum cmd direction;

short empty[16];

struct Game

{

int box[16];

enum game_stat stat;

int step;

unsigned long int point;

}game;

void init_game()

{

int i;

for(i=0;i<16;i++)

game.box[i]=0;

game.stat=PLAYING;

game.step=0;

game.point=0;

}

/*检验游戏是否能否继续*/

void check_fail()

{

int i,j;

for(i=0;i<4;i++)

for(j=0;j<3;j++)

if(game.box[i*4+j]==game.box[i*4+j+1])

return;

for(j=0;j<4;j++)

for(i=0;i<3;i++)

if(game.box[i*4+j]==game.box[(i+1)*4+j])

return;

game.stat=FAILED;

}

/*2和4出现的概率比为3/1*/

int get2or4()

{

int x=rand()%4;

return x>3 ? 4:2;

}

/*接收键盘的键入,方向键由三个char类型字符表示:

上:27 91 65

下:27 91 66

右:27 91 67

左:27 91 68

*/

void inputCmd()

{

char c=my_getch();

if(c==27)

{

c=my_getch();

if(c==91)

{

c=my_getch();

if(c==65)

direction=UP;

if(c==66)

direction=DOWN;

if(c==67)

direction=RIGHT;

if(c==68)

direction=LEFT;

//printf("%d ",c);

}

}

else if(c=='n')

direction=QUIT;

else

direction=INVALID;

}

/*检索空位,即为0的值

*/

int findPos()

{

int i,count=0,pos;

for(i=0;i<16;i++)

empty[i]=-1;

for(i=0;i<16;i++)

{

if(game.box[i]==0)

empty[count++]=i;

}

if(count==0)

return -1;//game over

pos=empty[rand()%count];

//printf("pos=%dn",pos);

return pos;

}

int merge()//不可以移动时返回-1

{

int box_4x4[4][4];

int i,j,deep;

int has_move=-1,merge_line=0;

for(i=0;i<4;i++)

for(j=0;j<4;j++)

box_4x4[i][j]=game.box[i*4+j];

if(direction==RIGHT)

{

//printf("RIGHT");

for(i=0;i<4;i++)

{

deep=3;

merge_line=0;

for(j=3;j>=0;j--)

{

if(box_4x4[i][j]!=0)

{

box_4x4[i][deep]=box_4x4[i][j];

if(deep!=j) box_4x4[i][j]=0;

if(deep<3 && merge_line==0 && box_4x4[i][deep]==box_4x4[i][deep+1] )

{ game.point+=box_4x4[i][deep+1]; box_4x4[i][deep+1]*=2;

box_4x4[i][deep]=0; merge_line=1; }

else deep--;

}

}

}

}

if(direction==LEFT)

{

//printf("LEFT");

for(i=0;i<4;i++)

{

deep=0;

merge_line=0;

for(j=0;j<4;j++)

{

if(box_4x4[i][j]!=0)

{

box_4x4[i][deep]=box_4x4[i][j];

if(deep!=j) box_4x4[i][j]=0;

if(deep>0 && merge_line==0 && box_4x4[i][deep]==box_4x4[i][deep-1] )

{ game.point+=box_4x4[i][deep-1]; box_4x4[i][deep-1]*=2;

box_4x4[i][deep]=0; merge_line=1; }

else deep++;

}

}

}

}

if(direction==UP)

{

//printf("UP");

for(j=0;j<4;j++)

{

deep=0;

merge_line=0;

for(i=0;i<4;i++)

{

if(box_4x4[i][j]!=0)

{

box_4x4[deep][j]=box_4x4[i][j];

if(deep!=i) box_4x4[i][j]=0;

if(deep>0 && merge_line==0 && box_4x4[deep][j]==box_4x4[deep-1][j])

{ game.point+=box_4x4[deep-1][j]; box_4x4[deep-1][j]*=2;

box_4x4[deep][j]=0; merge_line=1; }

else deep++;

}

}

}

}

if(direction==DOWN)

{

//printf("DOWN");

for(j=0;j<4;j++)

{

merge_line=0;

deep=3;

for(i=3;i>=0;i--)

{

if(box_4x4[i][j]!=0)

{

box_4x4[deep][j]=box_4x4[i][j];

if(deep!=i) box_4x4[i][j]=0;

if(deep<3 && merge_line==0 && box_4x4[deep][j]==box_4x4[deep+1][j])

{ game.point+=box_4x4[deep+1][j]; box_4x4[deep+1][j]*=2;

box_4x4[deep][j]=0; merge_line=1; }

else deep--;

}

}

}

}

for(i=0;i<4;i++)

for(j=0;j<4;j++)

if(game.box[i*4+j]!=box_4x4[i][j])

{

game.box[i*4+j]=box_4x4[i][j];

has_move=1;

if(game.box[i*4+j]==2048) game.stat=DONE;

}

return has_move;

}

void drawBox()

{

int *box=game.box;

printf("33[2J");//清屏

printf("33[2H");//光标复位

printf("33[?25l");//隐藏光标

printf(" steps: %8d points: %10lu n",game.step,game.point);

printf("33[;30m---------------------------------n");

printf("33[;30m| | | | |n");

//printf("| %4d | %4d | %4d | %4d |n",box[0],box[1],box[2],box[3]);

printf("33[;30m| ");

printNum(box[0]); printf("33[;30m | ");

printNum(box[1]); printf("33[;30m | ");

printNum(box[2]); printf("33[;30m | ");

printNum(box[3]); printf("33[;30m |n");

printf("33[;30m| | | | |n");

printf("33[;30m+-------+-------+-------+-------+n");

printf("33[;30m| | | | |n");

//printf("| %4d | %4d | %4d | %4d |n",box[4],box[5],box[6],box[7]);

printf("33[;30m| ");

printNum(box[4]); printf("33[;30m | ");

printNum(box[5]); printf("33[;30m | ");

printNum(box[6]); printf("33[;30m | ");

printNum(box[7]); printf("33[;30m |n");

printf("33[;30m| | | | |n");

printf("33[;30m+-------+-------+-------+-------+n");

printf("33[;30m| | | | |n");

//printf("| %4d | %4d | %4d | %4d |n",box[8],box[9],box[10],box[11]);

printf("33[;30m| ");

printNum(box[8]); printf("33[;30m | ");

printNum(box[9]); printf("33[;30m | ");

printNum(box[10]); printf("33[;30m | ");

printNum(box[11]); printf("33[;30m |n");

printf("33[;30m| | | | |n");

printf("33[;30m+-------+-------+-------+-------+n");

printf("33[;30m| | | | |n");

//printf("| %4d | %4d | %4d | %4d |n",box[12],box[13],box[14],box[15]);

printf("33[;30m| ");

printNum(box[12]); printf("33[;30m | ");

printNum(box[13]); printf("33[;30m | ");

printNum(box[14]); printf("33[;30m | ");

printNum(box[15]); printf("33[;30m |n");

printf("33[;30m| | | | |n");

printf("33[;30m---------------------------------n");

if(game.stat==FAILED)

printf(" oh,failed! try again.n");

else if(game.stat==DONE)

printf(" yeah,you won! n");

else

}

int main(int argc,char** argv)

{

int pwdlen=10;

int newPos;

int has_merge=1;

init_game();

srand(time(0));

fflush(stdin);

while(1)

{

//printf("33[2J");//清屏

//printf("33[2H");//光标复位

//printf("33[?25l");//隐藏光标

newPos=findPos();

if(newPos==-1)

{

check_fail();

if(game.stat==FAILED)

break;

}

if(has_merge!=-1)

{

game.box[newPos]=get2or4();

}

drawBox();

inputCmd(direction);

if(direction==QUIT)

break;

else if(direction==INVALID)

continue;

else

{

has_merge=merge();

if(game.stat==DONE) break;

if(has_merge!=-1) game.step++;

}

}

drawBox();

printf("33[;30m");

}

my_getch.h

复制代码 代码如下:

/*---------------------------------------

** copyright (c) 2013-3-2 DeltaYang

** E-mail: DeltaYang89@gmail.com

** getch.c:模拟实现getch()

**--------------------------------------*/

#ifndef MYGETCH_H

#define MYGETCH_H

#include

#include //操作终端

#include

#include

#include

char my_getch()

{

int c=0;

struct termios org_opts, new_opts;

int res=0;

//保留终端原来设置

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;

}

#endif

(0)

相关推荐

  • Linux下手动设置Windows磁盘挂载点

    Linux下手动设置Windows磁盘挂载点 我的笔记本是同时装了Linux系统和Windows系统。Linux系统启动后,Windows磁盘就会自动挂载在/media目录下,而且挂载点的名称又长又难 ...

  • linux下find查找命令用法

    Linux下find命令在目录结构中搜索文件,并执行指定的操作。Linux下find命令提供了相当多的查找条件,功能很强大。由于find具有强大的功能,所以它的选项也很多,其中大部分选项都值得我们花时 ...

  • Linux下修改root密码以及找回root密码的方法

    以root身份登陆,执行: # passwd 用户名 (修改密码) # useradd 用户名 (添加用户) 具体示例如下:[root@bogon ~]# passwd root Changing p ...

  • LINUX下的文件结构介绍

    /bin 二进制可执行命令 /dev 设备特殊文件 /etc 系统管理和配置文件 /etc/rc.d 启动的配置文件和脚本 /home 用户主目录的基点,比如用户user的主目录就是/home/use ...

  • Linux下使用Shell文本处理工具集锦

    Linux下的操作习惯不像windows一样可以有窗口进行操作,它是有很多不同的命令组成的,本文将介绍Linux下使用Shell处理文本时最常用的工具:find、grep、xargs、sort、uni ...

  • Linux下重启apache的方法

    Linux系统为Ubuntu 一、Start Apache 2 Server /启动apache服务 # /etc/init.d/apache2 start or $ sudo /etc/init.d ...

  • Linux下软件包的安装与管理

    先来看看Linux软件扩展名。软件后缀为.rpm最初是Red Hat Linux提供的一种包封装格式,现在许多Linux发行版本都使用;后缀为.deb是Debain Linux提供的一种包封装格式;后 ...

  • Linux下快速批量修改文件夹下的图片名称的方法

    我们都知道,要修改文件夹下的图片名称很容易,但是要批量修改就比较浪费时间了,那么有什么方法能够快速批量修改图片名称呢?下面小编就给大家介绍下Linux下快速批量修改图片名称的方法。 如10.11一批这 ...

  • Linux下如何直接从硬盘启动Linux ISO镜像文件

    通常Linux启动Linux ISO镜像都要现将文件刻录到光盘或从USB驱动启动,下面小编就给大家介绍下Linux下如何直接从硬盘启动Linux ISO文件,一起来学习下吧。 我们在Ubuntu 14 ...