贪吃蛇的小升级-吃字母游戏

简易说明:简化了之前的代码,优化了效率,更改了游戏的显示模式(相比之前的每一次清空之后再写入,此次取消了清空,直接对snake的部分进行逻辑处理),其它请在代码中查找。
显示如下:
在这里插入图片描述

/*蛇吃字母的游戏*/
/*画面产生A-Z字母,蛇头为@,蛇尾为oo,吃掉的字母在其蛇身顺序显示,如:@ABCoo */
/*2018.9.27*/
/*(c/c++)centos*/
#include <stdio.h>
#include <time.h>
#include <malloc.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/select.h>

#define high 15
#define wide 20

#define up 'w'
#define down 's'
#define left 'a'
#define right 'd'

int score  = 0;
int Level = 1;
int FoodNumber=0;
char direction = 'w';
char EatenFood;
int IsEat;
int FoodH=5,FoodW=10;

char Picture[high][wide];  //显示数组

typedef struct snake{
                int x;
                int y;
                struct snake* next;
}Node,*PSnake;

void setIO(int flag)
{
    if(flag)
        system("stty cbreak -echo");
    else
        system("stty cooked echo");
}

PSnake Init()           //生成一条蛇  坐标为中心点向下2个格,蛇头向上 
{
        printf("SnakeMake start!\n");
        int len=5;
        PSnake head=(PSnake)malloc(sizeof(Node));
        if(head == NULL)
                        printf("Snake head make failed!\n");
        head->x=wide/2;
        head->y=high/2+5;
        head->next=NULL;

        int i=0;
        for(;i<2;i++)
        {
                PSnake P=(PSnake)malloc(sizeof(Node));
                if(P==NULL)
                {
                          printf("Frog king is dead!\n");
                          break;
                }
                P->x=wide/2;
                P->y=high/2-i+4;
                P->next=head;
                head=P;
        }
        printf("Snake is alive!\n");
        return head;
}
/*吃食物*/                                
PSnake Eat(int x,int y,PSnake snake)                 //把食物与头调换位置完成“吃”的动作
{
   EatenFood=Picture[snake->y][snake->x]=Picture[y][x];
        PSnake p=(PSnake)malloc(sizeof(Node));
        if(p==NULL)
        {
                printf("New head make failed!");
        }
        p->x = x;
        p->y = y;
        Picture[y][x]='@';
        p->next=snake;
        score += Picture[snake->y][snake->x];
        FoodNumber--;
        IsEat=1;
        return p;
}
/*行进一步*/
void Walk(int x,int y,PSnake snake)                     //优化,把蛇身前移
{
        PSnake p=snake;
        int a,b;
        while(p!=NULL)
        {
                a=p->x;
                b=p->y;
                p->x = x;
                p->y = y;
                Picture[p->y][p->x] = Picture[b][a];
                if(p->next == NULL)
                {
                                  Picture[b][a]=' ';
                }
                x=a;
                y=b;
                p=p->next;
        }
}
/*检验是否会吃掉自己*/
int Serch(int x,int y,PSnake snake)     
{
        PSnake q=snake->next;
        while(q!= NULL)
        {
                 if( ( (q->x) == x ) && ( (q->y) == y ) )
                                        return 1;
                 q=q->next;
        }
        return 0;
}
/*初始化蛇的图像*/
void WriteSnake(PSnake snake)   //把蛇写入打印数组
{
        PSnake  p=snake;
        while(p != NULL)
        {
                if( p==snake )
                {
                                  Picture[p->y][p->x] = '@';
                }
                else
                {
                                  Picture[p->y][p->x] = 'o';
                }
                p=p->next;
        }
}
/*初始化游戏数组*/
void InitArray(void)       
{
        int y=high,x=wide,i,j;
        for(i=0; i<y; i++)
                        for(j=0; j<x; j++)
                                        Picture[i][j]=' ';
}
/*显示游戏画面*/
void Print(char* p,int score,int Lev)       //打印框架,生成画面
{
        int i=0,j;
        static int cnt=1;
        printf("\033c");
        printf("  The Snake Game is On!! The Write times is %d !\n",cnt);
        cnt++;
        printf("Player:%s   Score:%d   Level:%d \n",p,score,Lev);
        while( i < wide*2+2 )  
        {
                printf("-");
                i++;
        }
        printf("\n");
        for (i=0; i < high; i++)
        {
                printf("|");
                for(j=0; j<wide; j++)
                {
                                printf("%c ",Picture[i][j]);
                }
                printf("|");
                printf("\n");
        }
        for(i=0;i<=wide*2+1;i++)
        {
                printf("-");
        }
        printf("\nGameShow:");
        if( IsEat != 0)
        {
                          printf("Your snake eat a \"%c\"!Score:+%d !\n",EatenFood,EatenFood);
                          IsEat=0;
        }
        else
        {
                          printf("Your snake take a step!\n");
        }
        printf("-----------------------------------------------------\n");
        printf("----Wish you have fun!-------------------------------\n");
        printf("===========++++++++This is bottom!!!!++++++++++++++++\n");
}
/*食物产生*/
int MakeFood(void)       //创造食物并写入框图
{
        static int MC=0;         //MC =  FoodMake Count
        int timeLimit;
        struct timeval start,end;
        gettimeofday(&start,NULL);
        while(1)  
        {
                if(MC > ((high * wide)*2/3 ) )
                                  return 0;
                gettimeofday(&end,NULL);
                timeLimit = (end.tv_sec - start.tv_sec)*1000000 + end.tv_usec - start.tv_usec;
                if(timeLimit > 10000)             //控制食物生成时间,提升显示流畅度
                                  return 0;
                srand((int)time(0));
                FoodH=rand()%high;
                FoodW=rand()%wide;
                if(Picture[FoodH][FoodW] == ' ')
                {
                                  break;
                }
        }
        Picture[FoodH][FoodW]=rand()%26+65;
        MC++;
        FoodNumber++;
        return 1;
}
/*蛇的运动*/
PSnake MakeMove(PSnake s)    //蛇的动作
{
        int x,y;
        PSnake p=s;
        x=s->x,y=s->y;
		/*产生运动方向下的下一个坐标x,y,以此判断下列情况*/
        if(direction == up)
                          y = y - 1;
        if(direction == down)
                          y = y + 1;
        if(direction == right)
                          x = x + 1;
        if(direction == left)
                          x = x - 1;
        //check if the snake crash the wall
        if( (y>(high-1)) || ((y<0)) || ((x)<0) || (x>(wide-1)) )
        {
                //printf("x=%d y=%d s.x=%d s.y=%d \n",x,y,s->x,s->y);
                printf("The snake break the wall!\n");
                return NULL;
        }
		//check if the snake eat itself
        if(Serch(x,y,s))
        {
                printf("Your snake eat itsself!\n");
                return NULL;
        }
		//if there is a food
		if(Picture[y][x] != ' ')
        { 
                s=Eat(x,y,s);
        }
		//if there is no food
        else
		{ 
                Walk(x,y,s);
        }
        return s;
}
/*检查是否有键按下*/
int kbhit(void)
{
        struct timeval tv;
        fd_set rdfs;
        tv.tv_sec = 0;
        tv.tv_usec = 0;
        FD_ZERO(&rdfs);
        FD_SET(STDIN_FILENO,&rdfs);
        select(STDIN_FILENO+1,&rdfs,NULL,NULL,&tv);
        return FD_ISSET(STDIN_FILENO,&rdfs); 
}
/*控制输入*/
void InputCTL(int level)
{
   char Dir=direction;
        int timeUse;
        struct timeval start,end;
        gettimeofday(&start,NULL);   
        setIO(1);
        while(1)
        {
                gettimeofday(&end,NULL);
                timeUse = 1000000*(end.tv_sec - start.tv_sec) +
                            end.tv_usec - start.tv_usec;
                if(timeUse > 1000000 - level*100000)
                        break;
                if(kbhit())
                        Dir=getchar();
        }
        setIO(0);
		/*如果按键方向与蛇原来的行进方向相反,则忽略*/
        if( ((Dir == 'w') && (direction == down) ) || ((Dir == 's') && (direction == up))
                    || ((Dir == 'a') && (direction == right)) || ((Dir == 'd') && (direction == left) ) )
        {
                printf("Dir = %d \n",Dir);
        }
		/*如果按键是有效的,则使用新的direction*/
        else if((Dir == 'a') || (Dir=='s') || (Dir=='w') || (Dir=='d'))
        {
                direction = Dir;
        }
        else
        {
                printf("Input direction Wrong!");
        }
}
/*游戏等级控制及输出*/
int CheckLevel(int score)               
{
        static int change=0;
        if(((score - change) >= 1000) && (Level < 9) )
        {
                Level ++;
                change += 1000;
        }
        return Level;
}
/*游戏运行*/
void GameRun(void) 
{
        int GameState=1;
		score=0;
        Level=1;
        char Name[10];
        printf("Please input your name,push the 'Enter' to end:");
        scanf("%s",&Name);
        PSnake jack=Init();
        InitArray();
        WriteSnake(jack);
        while(GameState)
        {                           
                if(FoodNumber<5)                                            如果存在的食物少于5,则产生新的食物
                {
                MakeFood();
                }
                Print(Name,score,CheckLevel(score));                      //打印游戏画面
                InputCTL(Level);                                          //控制输入
                jack = MakeMove(jack);
                if( jack == NULL )         //游戏结束判断
                {
                        GameState=0;
                        printf("Game Over!\n");
                        printf("Your final score:%d.\n",score);
                }
        }
}
int main(void)
{
        GameRun();
        return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值