C语言实现贪吃蛇(转载修改版)

 

我是用Devc软件进行编写的。

此外,需调用的子函数和主函数写在一个文件里,并没有创建头文件进行分写。

程序主体是按照转载链接作者编写的。

再其基础上进行小小修改后,该小游戏可以自行增加游戏难度和分数,第N关成功后可以选择是否继续闯关。

PS:具体注释详见转载作者;

废话不多说

520行代码如下:

#include<stdio.h> 
#include<stdlib.h>
#include<Windows.h>
#include<time.h>
#include<malloc.h>
#include<assert.h>

#define  rowMap 20 
#define  colMap 40

int succesScore=20;
enum Direction
{
    
    D,
    A,
    S,
    W,
    
}dir;

enum State
{
    eatSelf,
    crashWall,
    nomal,
    success,
    exitWindow,
    again,
    
}sta;
struct snake
{
    size_t x;
    size_t y;
    struct snake*next;
};

void startGame();
void runGame();
void endGame();

struct snake*snakeHead = NULL;
struct snake*food=NULL;
int sleepTime=500;
int score=0;
int everyScore=1;
int countTime=0;
const char Food = '#';
const char Snake='*';
void pos(int x,int y) 
{
    COORD pos;
    pos.X = x;
    pos.Y = y;
    
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);    
}
void face()
{
    system("color 0C");
    printf("*************************************\n");
    printf("*              welcome              *\n");
    printf("*                                   *\n");
    printf("*       ->开始游戏请按回车键<-      *\n");
    printf("*       ->退出游戏 请按Esc键<-      *\n");
    printf("*       ->暂停游戏请按空格键<-      *\n");
    printf("*                                   *\n");
    printf("*************************************\n");
    printf("\n");
    printf("\n");
    printf("*****************提示****************\n"); 
    printf("* 1.通过上下左右按键来控制蛇的移动  *\n");
    printf("*                                   *\n");
    printf("* 2.通过F1键来减速  通过F2键来加速  *\n");
    printf("*************************************\n");     
}
void map()
{
    int i = 0;
    for(i=0;i<colMap;i+=2)
    {
        pos(i,0);
        printf("■");
        pos(i,rowMap-1);
        printf("■");
    }
    for(i=0;i<rowMap;i++)
    {
        pos(0,i);
        printf("■");
        pos(colMap-2,i);
        printf("■");
    }
}

void printSnake()
{
    struct snake*cur = snakeHead;
    while(cur)
    {
        pos(cur->y,cur->x);
        printf("%c",Snake);
        cur = cur->next;
    } 
}

void initSnake()//初始化蛇身 
{
    int initNum = 3;
    int i=0;
    struct snake*cur;
    snakeHead=(struct snake*)malloc(sizeof(struct snake));
    snakeHead->x=5;
    snakeHead->y=10;
    snakeHead->next=NULL;
    cur=snakeHead;
    
    for(i=1;i<initNum;i++)
    {
        struct snake*newNode=(struct snake*)malloc(sizeof(struct snake));
        newNode->x = 5+i;
        newNode->y = 10;
        newNode->next=NULL;
        cur->next =newNode;
        cur=cur->next;
    }
    printSnake(); 
    
}

void createFood()
{
    struct snake*cur = snakeHead;
    food = (struct snake*)malloc(sizeof(struct snake));
    srand((unsigned)time(NULL));
    food->x = rand()%(rowMap-2-1+1)+1;
    food->y = rand()%(colMap-3-2+1)+2;
    while(cur)
    {
        if(cur->x ==food->x&&cur->y==food->y)
        {
            free(food);
            food=NULL;
            createFood();
            return;
        }
        cur = cur->next;
    }
    pos(food->y,food->x);
    printf("%c",Food);
}


void startGame()
{
    face();
    system("pause");
    if(GetAsyncKeyState(VK_RETURN))
    {
        system("cls");
        pos(colMap+5,1);        
        printf("当前分数/通关分数:");
        pos(colMap+24,1);
        printf("%d/%d",score,succesScore);
        pos(colMap+5,3);
        printf("每个食物分数:%d",everyScore);
        printf("\n");
        pos(colMap+5,5);
        printf("速度越快 得分越高!!\n");    
        
        
        map();
        initSnake();
        createFood();
    }
    else if(GetAsyncKeyState(VK_ESCAPE))
    {
        exit(0);
    } 
    
}

void startGameAgain()//添加新的再一次开始游戏的函数 
{
        system("pause");
        if(GetAsyncKeyState(VK_RETURN))
        {
            system("cls");
            pos(colMap+5,1);        
            printf("当前分数/通关分数:");
            pos(colMap+24,1);
            printf("%d/%d",score,succesScore);
            pos(colMap+5,3);
            printf("每个食物分数:%d",everyScore);
            printf("\n");
            pos(colMap+5,5);
            printf("速度越快 得分越高!!\n");    
            
            
            map();
            initSnake();
            createFood();
        }
        else if(GetAsyncKeyState(VK_ESCAPE))
        {
            exit(0);
        } 
}

int IfcrashWall()
{
    if(snakeHead->x<=0||snakeHead->x>=rowMap-1
        ||snakeHead->y<=1||snakeHead->y>=colMap-2)
    {
        sta = crashWall;
        return 0;
    }    
    return 1;
}

int IfeatSelf(struct snake*newHead)
{
    struct snake*cur=snakeHead;
    //assert(newHead);
    while(cur)
    {
        if(cur->x==newHead->x&&cur->y==newHead->y)
        {
            sta = eatSelf;    
            return 0;
        }
        cur=cur->next;
    }
    return 1;
}

int  isFood(struct snake*poss)
{
//    assert(poss);
    if(poss->x==food->x&&poss->y==food->y)
    {
        return 1;
    }
    return 0;
}


void snakeMove()//蛇移动 
{
    struct snake*newHead=NULL;
    newHead= (struct snake*)malloc(sizeof(struct snake));
    if(dir == D)
    {
        newHead->x=snakeHead->x;
        newHead->y=snakeHead->y+1;
        newHead->next=snakeHead;
        //countTime
    }
    if(dir == A)
    {
        newHead->x=snakeHead->x;
        newHead->y=snakeHead->y-1;
        newHead->next=snakeHead;
        
    }
    if(dir == S)
    {
        newHead->x=snakeHead->x+1;
        newHead->y=snakeHead->y;
        newHead->next=snakeHead;        
    }
    if(dir == W)
    {
        newHead->x=snakeHead->x-1;
        newHead->y=snakeHead->y;
        newHead->next=snakeHead;            
    }
    if(isFood(newHead))
    {
        snakeHead = newHead;
        printSnake();
        createFood();
        score+=everyScore;
        pos(colMap+5,1);        
        printf("当前分数/通关分数:");
        pos(colMap+24,1);
        printf("%d/%d",score,succesScore);
        if(score>=succesScore)
        {
            sta=success;
            score=0;
        }
    }
    else
    {
        if(IfcrashWall()&&IfeatSelf(newHead))
        {
            struct snake*cur=NULL;
            snakeHead=newHead;
            cur=snakeHead;
        
               while(cur->next->next!=NULL)
             {
                 pos(cur->y,cur->x);
                 printf("%c",Snake);
                 cur = cur->next; 
               }
               pos(cur->y,cur->x);
               printf("%c",Snake);
               pos(cur->next->y,cur->next->x);
               printf(" ");
               free(cur->next);
               cur->next =NULL;
               
        }
        else{
             free(newHead);
             newHead = NULL;    
            }  
    }
}

void pause()
{
    while(1)
    {
        Sleep(sleepTime);
        if(GetAsyncKeyState(VK_SPACE))
        {
            break;
        }
        
         
    }
}

void controlSnake()
{
    
    if(GetAsyncKeyState(VK_UP)&&dir!=S)
    {
        dir = W;
    } 
    else if(GetAsyncKeyState(VK_DOWN)&&dir!=W)
    {
        dir = S;
    } 
    else if(GetAsyncKeyState(VK_RIGHT)&&dir!=A)
    {
        dir = D;
    } 
   else    if(GetAsyncKeyState(VK_LEFT)&&dir!=D)
    {
        dir = A;
    }     
    else if(GetAsyncKeyState(VK_F1))
    {
        if(sleepTime<500)
        {
               sleepTime += 100;
            everyScore -=1;
            pos(colMap+5,3);
             printf("每个食物分数:%d",everyScore);
             countTime=0;
        }
        else
        {
            sleepTime=500;
            everyScore=succesScore/20;
            pos(colMap+5,3);
            printf("每个食物分数:%d",everyScore);            
        }
    }
    else if(GetAsyncKeyState(VK_F2))
    {
        if(sleepTime>100)
        {
            sleepTime -= 100;
            everyScore +=1;
            pos(colMap+5,3);
             printf("每个食物分数:%d",everyScore);
            countTime=0;
        }
        else
        {
            sleepTime=100;
            everyScore=succesScore/20+4;
            pos(colMap+5,3);
            printf("每个食物分数:%d",everyScore);    
            countTime=0;        
        }         
    }
    else if(countTime*sleepTime>=30000)
    {
        if(sleepTime>100)
        {
            sleepTime -= 100;
            everyScore +=1;
            pos(colMap+5,3);
             printf("每个食物分数:%d",everyScore);
             countTime=0;
        }
        else
        {
            sleepTime=100;
            everyScore=succesScore/20+4;
            pos(colMap+5,3);
            printf("每个食物分数:%d",everyScore);            
        }
        
    }    
    else if(GetAsyncKeyState(VK_SPACE))
    {
        pause();
    }
    else if(GetAsyncKeyState(VK_ESCAPE))
    {
        exit(0);
    }
}
void  stateGame()//进行简单修改 实现循环闯关 
{
    if(sta==eatSelf)
    {
        system("cls");
        printf("很遗憾,蛇咬到自己,游戏失败!\n");
    }
    else if(sta == crashWall)
    {
        system("cls");
        printf("很遗憾,蛇碰到墙壁,游戏失败!\n");
    }
    else if(sta==success)
    {
        system("cls");
        printf("恭喜您,已通关!\n");
    printf("*************************************\n");
    printf("*          是否继续下一关           *\n");
    printf("*                                   *\n");
    printf("*       ->继续下一关按回车键<-      *\n");
    printf("*       ->退出游戏 请按Esc键<-      *\n");
    printf("*                                   *\n");
    printf("*************************************\n");
        for(countTime=10;countTime>=0;countTime--)
        { 
         pos(1,rowMap-2);
         printf("。。。。。。。%dS后无选择将退出游戏\n",countTime);
             
        if(GetAsyncKeyState(VK_RETURN)) 
         {
            succesScore+=20;
            if(succesScore>100)
            {
                system("cls");
                pos(colMap-20,rowMap);
                printf("恭喜你!闯过所有关卡");
                break;         
            } 
            everyScore=succesScore/20;
            sleepTime=500;
            sta=again;
            startGameAgain();
            break;
         }
            else if(GetAsyncKeyState(VK_ESCAPE)||countTime==0)
         {
            system("cls");
            sta=exitWindow;
         }
        Sleep(1000);
      }
    } 
}

void runGame()
{
    dir=D;
    sta=nomal;
    while(1)
    {
        controlSnake();
        snakeMove();
        countTime+=1; 
        if(sta!=nomal)
        { 
            stateGame();
            countTime=0;
            if(sta!=again)//添加新判断条件 
             {
               break;
              }
            
       }
        Sleep(sleepTime);
    }
}

void endGame()
{
    struct snake*cur = snakeHead;
    while(cur)
    {
        struct snake*del=cur;
        cur=cur->next;
        free(del);
        del=NULL;
    }
    snakeHead = NULL;
    if(food!=NULL)
    {
        free(food);
        food = NULL;
    }
    score = 0;
    everyScore=1;
    sleepTime=500;

int main()
{
    while(1)
    {
        startGame();
        runGame();
        endGame();
    }
    system("pause");
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值