| 
                     贡献一个原创小程序,是unix下用终端控制字符实现的贪吃蛇小游戏,供大家一乐。
 
 /***snake.c***/#include <stdio.h>#include <malloc.h>#include <sys/time.h>#include <sys/types.h>#include <sys/select.h>#include <termio.h>#include <fcntl.h>#define SNAKE_INITX 5#define SNAKE_INITY 5#define SNAKE_SHAPE '*'#define SNAKE_INITLEN 8#define WIN_X1 1#define WIN_X2 80#define WIN_Y1 1#define WIN_Y2 24#define MAX_LEVEL 20#define MAX_INTER 200000#define MIN_INTER 0#define MAX_RICH 10#define DEVRATE 5#define OVER "Game Over!!!"struct stNode{      int x;      int y;      char shape;      struct stNode *next;};struct stFood{      int x;      int y;};struct stNode *gpstHead,*gpstTail;struct stFood gastFood[MAX_RICH];int giLevel=1;int giRich=1;int giScore=0;int giLen=0;void settty(int iFlag){      int fd;      struct termio stTerm;            if((fd = open(ttyname(1),O_RDWR))==-1) return;      if(iFlag == 1)      {            ioctl(fd,TCGETA,&stTerm);            stTerm.c_lflag &= ~ICANON;            stTerm.c_lflag &= ~ECHO;            stTerm.c_cc[4] = 1;            stTerm.c_cc[5] = 0;            stTerm.c_iflag &= ~ISTRIP;            stTerm.c_cflag |= CS8;            stTerm.c_cflag &= ~PARENB;            ioctl(fd,TCSETA,&stTerm);      }      else      {            ioctl(fd,TCGETA,&stTerm);            stTerm.c_lflag |= ICANON;            stTerm.c_lflag |= ECHO;            stTerm.c_cc[4] = 4;            stTerm.c_cc[5] = 5;            stTerm.c_iflag &= ~ISTRIP;            stTerm.c_cflag |= CS8;            stTerm.c_cflag &= ~PARENB;            ioctl(fd,TCSETA,&stTerm);      }      close(fd);}void vDrawOneNode(struct stNode *pstNode,int iFlag){      printf("\033[%dm\033[40;%dm\033[%d;%d;H%c",      iFlag,iFlag*3+30,pstNode->y,pstNode->x,pstNode->shape);      fflush(stdout);}void vDrawOneFood(int x,int y){      printf("\033[1m\033[40;36m\033[%d;%d;H%c",y,x,'@');      fflush(stdout);}int iGetDir(int iOriDir){      fd_set rset;      struct timeval hTmo;      int iRet,iFlag=0;      char cCh;            FD_ZERO(&rset);      FD_SET(0,&rset);      hTmo.tv_sec=0;      hTmo.tv_usec=MAX_INTER-(MAX_INTER-MIN_INTER)/MAX_LEVEL*giLevel;            iRet=select(1,&rset,NULL,NULL,&hTmo);      if(iRet<=0)      {            return(iOriDir);      }      for(;;)      {            cCh=getchar();            if(cCh != -1)            {                  switch(cCh)                  {                         case 27 :                        case 91 :                        iFlag++;                        break;                        case 65 ://UP                        case 66 ://DOWN                        case 67 ://RIGHT                        case 68 ://LEFT                        if(iFlag==2)                        return((!((cCh-0x41)^iOriDir^1))^(cCh-0x41));                        default :                        return(iOriDir);                  }            }      }}void vInitScreen(){      settty(1);      printf("\033[?25l\033[2J");}void vRestoreScreen(){      printf("\033[24;1H\033[1m\033[40;34m\033[?25h");      settty(0);}void vDrawScope(){      int i,j;            for(j=WIN_Y1;j<=WIN_Y2;j+=WIN_Y2-WIN_Y1)      {            printf("\033[%d;%dH+",j,WIN_X1);            for(i=WIN_X1+1;i<WIN_X2;i++)            printf("-");            printf("+");      }      for(i=WIN_Y1+1;i<WIN_Y2;i++)      printf("\033[%d;%dH|%*c|\n",i,WIN_X1,WIN_X2-WIN_X1-1,' ');}void vCreateSnake(){      struct stNode *pstNew;      int i;            gpstHead=(struct stNode*)malloc(sizeof(struct stNode));      gpstHead->x=SNAKE_INITX;       gpstHead->y=SNAKE_INITY;      gpstHead->shape=SNAKE_SHAPE;      gpstHead->next=NULL;      vDrawOneNode(gpstHead,1);      gpstTail=gpstHead;      for(i=1;i<SNAKE_INITLEN;i++)      {            pstNew=(struct stNode*)malloc(sizeof(struct stNode));            pstNew->x=gpstHead->x+1;             pstNew->y=gpstHead->y;            pstNew->shape=SNAKE_SHAPE;            pstNew->next=NULL;            vDrawOneNode(pstNew,1);            gpstHead->next=pstNew;            gpstHead=pstNew;      }      return;}void vKillSnake(){      struct stNode *pstNode;            for(pstNode=gpstTail;gpstTail!=NULL;)      {            gpstTail=pstNode->next;            free(pstNode);            pstNode=gpstTail;      }}void vGenFood(int iIdx){      struct stNode *pstNode;      int i,iFound=0;            for(;!iFound;)      {            iFound=1;            gastFood[iIdx].x=rand()%(WIN_X2-WIN_X1-1)+WIN_X1+1;            gastFood[iIdx].y=rand()%(WIN_Y2-WIN_Y1-1)+WIN_Y1+1;            for(i=0;i<giRich;i++)            {                  if(i!=iIdx && gastFood[iIdx].x==gastFood[i].x &&                  gastFood[iIdx].y==gastFood[i].y)                  {                        iFound=0;                        break;                  }            }            if(!iFound) continue;            for(pstNode=gpstTail;pstNode!=NULL;pstNode=pstNode->next)            {                  if(gastFood[iIdx].x==pstNode->x &&                  gastFood[iIdx].y==pstNode->y)                  {                        iFound=0;                        break;                  }            }            if(!iFound) continue;      }      vDrawOneFood(gastFood[iIdx].x,gastFood[iIdx].y);}void vInitFood(){      int i;            srand(getpid());      for(i=0;i<giRich;i++) vGenFood(i);}int iIsValid(int x,int y){      struct stNode *pstNode;            if(x<=WIN_X1 || x>=WIN_X2 || y<=WIN_Y1 || y>=WIN_Y2)      return(0);      pstNode=gpstTail;      for(;pstNode!=NULL;)      {            if(x==pstNode->x && y==pstNode->y)            return(0);            pstNode=pstNode->next;      }      return(1);}int iEat(int x,int y){      int i,j;            for(i=0;i<giRich;i++)      {            if(x==gastFood[i].x && y==gastFood[i].y)            {                  vGenFood(i);                  giScore+=giLevel*10;                  giLen++;                  if(giLevel<MAX_LEVEL)                  if(giLen%DEVRATE==0)                  giLevel++;                  return(1);            }      }      return(0);}main(){int iDir=2,iNextX,iNextY;struct stNode *pstNew;char sPrompt[80];vInitScreen();vDrawScope();vCreateSnake();vInitFood();for(;;){      iDir=iGetDir(iDir);      iNextX=gpstHead->x+(iDir>>1)*(5-(iDir<<1));      iNextY=gpstHead->y-(!(iDir>>1))*(1-(iDir<<1));      if(!iIsValid(iNextX,iNextY))      {            printf("\033[%d;%dH\033[1m\033[40;34m%s\033[0m",            WIN_Y2-1,(WIN_X1+WIN_X2)/2-strlen(OVER)/2,OVER);            break;      }      pstNew=(struct stNode*)malloc(sizeof(struct stNode));      pstNew->x=iNextX;      pstNew->y=iNextY;      pstNew->shape=SNAKE_SHAPE;      pstNew->next=NULL;      gpstHead->next=pstNew;      gpstHead=pstNew;      vDrawOneNode(gpstHead,1);      if(!iEat(iNextX,iNextY))      {            vDrawOneNode(gpstHead,1);            vDrawOneNode(gpstTail,0);            pstNew=gpstTail;            gpstTail=pstNew->next;            free(pstNew);      }      sprintf(sPrompt,"Score:%7d Level:%2d",giScore,giLevel);      printf("\033[%d;%dH\033[1m\033[40;34m%s\033[0m",      WIN_Y2,(WIN_X1+WIN_X2)/2-strlen(sPrompt)/2,sPrompt);}vKillSnake();vRestoreScreen();}
 编译方法:
 AIX下:cc -qcpluscmt -o snake snake.c
 sco unix下:cc -o snake snake.c
 
 |