C语言:贪吃蛇

代码

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

#define FrameWidght 22
#define FrameHeight 22

short generateRandNumber(short a, short b) ;
void posConsoleCursor(short x, short y) ;
void hideConsoleCursorIcon() ;

void initStartHint() ;
void initHint() ;
void initFrame() ;
void initSnake() ;
void initGame() ;

void generateFood() ;
int knockSankeBody(int yx) ;

void move(short dx, short dy) ;
void pauseGame() ;
void listenKey(int *dx, int *dy) ;

void run() ;


/**
 *定义共同体 ,short x,y与int p占用同一位置
 * 蛇的一小截的位置的结构体
 * 系统采用小端方式存储
 * x是p的低位 ,y是p的高位
 */
typedef struct _Position
{
  union
  {
    struct
    {
        short x,y ;
    } ;
    int yx ;
  };
  struct _Position *next ;
}Position ;

/**
 *蛇的结构体
 */
typedef struct{
    int len ;
    Position *front ;
    Position *rear ;
} Snake;


/**
 *定义全局变量
 */
Snake snake ;
Position *food ;
int score =0 ;
int isGameOver ;

/**
 *主函数
 */
int main()
{
    //初始化全局变量
    food = NULL ;
    score = 0 ;
    isGameOver = 0 ;
    snake.front = NULL ;
    snake.len = 0 ;
    snake.rear = NULL ;
    //随机种子
    srand((unsigned)time(NULL)) ;
    //初始化显示
    initGame();
    run() ;

    posConsoleCursor((FrameWidght+1)*2,4);
    printf("游戏结束!!,您的分数是:") ;
    system("pause") ;
    //释放申请的空间
    if(food!=NULL)
        free(food) ;
    Position *p = snake.front ;
    Position *next = NULL ;
    while(p!=NULL)
    {
        next = p->next ;
        free(p) ;
        p =next ;
    }
    return 0 ;
}

/**
 *生成随机数函数
 */
short generateRandNumber(short a,short b)
{
    return a+rand()%(b-a+1) ;
}

/**
 *移动光标位置
 */
void posConsoleCursor(short x,short y)
{
    COORD pos ;
    pos.X = x ;
    pos.Y = y ;
    HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE) ;
    SetConsoleCursorPosition(hOutput,pos) ;
    return ;
}

/**
 *隐藏光标
 */
void hideConsoleCursorIcon()
{
    CONSOLE_CURSOR_INFO cci ;
    cci.bVisible = false ;
    cci.dwSize = sizeof(cci) ;
    HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE) ;
    SetConsoleCursorInfo(hOutput,&cci) ;
    return ;
}


/**
 *初始化游戏开始提示栏
 */
void initStartHint()
{
    printf("\n\n\t") ;
    printf("游戏提示:") ;
    printf("\n\n\t") ;
    printf("↑上移\t↓下移\t←左移\t→右移") ;
    printf("\n\n\t") ;
    printf("SPACE 暂停\tESC 结束") ;
    printf("\n\n\t") ;
    system("pause") ;
    system("cls") ;
}

/**
 *初始化提示
 */
void initHint()
{
    posConsoleCursor((FrameWidght+1)*2,4);
    printf("Your Score :") ;
    posConsoleCursor((FrameWidght+1)*2,5);
    printf("%d",score) ;
}

/**
 *初始化方框
 */
void initFrame()
{
    int i ;
    hideConsoleCursorIcon();
    for(i=0 ;i <FrameWidght ;++i )
    {
        posConsoleCursor(i*2,0);
        printf("□") ;
    }

    for(i=0 ;i <FrameWidght ;++i )
    {
        posConsoleCursor(i*2,FrameHeight-1);
        printf("□") ;
    }

    for(i=1 ;i <FrameHeight-1 ;++i )
    {
        posConsoleCursor(0,i);
        printf("□") ;
    }


    for(i=1 ;i <FrameHeight-1 ;++i )
    {
        posConsoleCursor((FrameWidght-1)*2,i);
        printf("□") ;
    }

}

/**
 *初始化蛇
 */
void initSnake()
{

    Position *p = (Position *)malloc(sizeof(Position)) ;
    Position *next = NULL ;
    //p->yx =((FrameHeight-2)/2<<16)|(FrameWidght)/2 ;
    p->x = FrameWidght/2 ;
    p->y = (FrameHeight-2)/2 ;
    snake.front = p ;
    posConsoleCursor(p->x*2,p->y);
    printf("●");
    snake.len = 4 ;
    for(int i=0 ;i<3 ;++i)
    {
        next = (Position*)malloc(sizeof(Position)) ;
        //next->yx = (p->y<<16)|(p->x-1) ;
        next->x = p->x-1 ;
        next->y = p->y ;

        p->next = next ;
        p = next ;
        posConsoleCursor(p->x*2,p->y);
        printf("●");
    }
    p->next = NULL ;
    snake.rear = p ;
}

/**
 * 初始化游戏
 *
 */
void initGame()
{
    initStartHint() ;
    initFrame();
    initHint();
    initSnake() ;
    generateFood() ;
}

/**
 * 生成食物
 */
void generateFood()
{
    short x ,y ;
    int yx ;
    do
    {
        x = generateRandNumber(1,FrameWidght-2) ;
        y = generateRandNumber(1,FrameHeight-2) ;
        yx = (y<<16)|x ;
    }while(knockSankeBody(yx)) ;
    food = (Position*)malloc(sizeof(Position)) ;
    food->yx = yx ;
    food->next =NULL ;
    posConsoleCursor(food->x*2,food->y);
    printf("●");
}

/**
 *判断生成的随机数是否在蛇的身体上
 */
int knockSankeBody(int yx)
{
    int flag =0 ;
    Position *p  =  snake.front ;

    for(int i= 0; i<snake.len ;++i)
    {
        if(p->yx==yx)
        {
            flag =1 ;
            break;
        }
        p = p->next ;
    }
    return flag ;
}

/**
 *暂停游戏
 */
void pauseGame()
{
    while(1)
    {
        Sleep(500);
        if(GetAsyncKeyState(VK_SPACE))
            break ;
    }
}

/**
 *蛇的移动
 */
void move(short dx, short dy)
{
    Position *p = snake.front ;
    Position *move_p = snake.rear ;

    int x = snake.front->x+dx ;
    int y = snake.front->y+dy ;
    int yx = (y<<16)|x ;
    //判断是否撞到框
    if( x<1 || x > (FrameWidght-2)
            || y<1 || y > (FrameHeight-2) )
    {
        isGameOver =1 ;
        return ;
    }
    else if(yx == food->yx)//是否吃到食物
    {
        food->next = snake.front ;
        snake.front = food ;
        snake.len++ ;
        score+=10 ;
        posConsoleCursor((FrameWidght+1)*2,5);
        printf("%d",score) ;
        generateFood();
    }
    else
    {
        while(p->next!=move_p)
        {
            //判断是否撞到身体
            if(p->yx==yx)
            {
                isGameOver =1 ;
                break ;
            }
            p = p->next ;
        }

        if(isGameOver!=1)
        {
            snake.rear = p  ;
            p->next = NULL ;

            //清除
            posConsoleCursor(move_p->x*2,move_p->y);
            printf("  ") ;
            //打印头
            move_p->yx = yx ;
            move_p->next = snake.front ;
            snake.front = move_p ;
            posConsoleCursor(snake.front->x*2,snake.front->y);
            printf("●");

        }
    }
}


/**
 *监听按键
 */
void listenKey(int *dx ,int *dy)
{
    if(GetAsyncKeyState(VK_UP))
    {
        if(*dy==0)
        {
            *dx= 0;
            *dy=-1 ;
        }
        return ;
    }
    if(GetAsyncKeyState(VK_DOWN))
    {
        if(*dy==0)
        {
            *dx= 0;
            *dy=1 ;
        }
        return ;
    }
    if(GetAsyncKeyState(VK_LEFT))
    {
        if(*dx==0)
        {
            *dx=-1;
            *dy=0 ;
        }
        return ;
    }
    if(GetAsyncKeyState(VK_RIGHT))
    {
        if(*dx==0)
        {
            *dx=1;
            *dy=0 ;
        }
        return ;
    }
    if(GetAsyncKeyState(VK_SPACE))
    {
        pauseGame();
    }
}


/**
 *游戏运行
 */
void run()
{
    int dx=1 ;
    int dy=0 ;
    while(isGameOver==0)
    {
        Sleep(200);
        listenKey(&dx,&dy);
        move(dx,dy) ;
    }
}


结果

这里写图片描述


这里写图片描述

发布了62 篇原创文章 · 获赞 28 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/native_lee/article/details/53365508