C语言实现贪吃蛇小游戏

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

#define FOOD "□"

void SetPos(int x, int y)
{
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD pos;
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(handle, pos);
}

void CreateMap(void)
{
    int i = 0;
    for (; i <= 56; i += 2) {
        SetPos(i, 0);
        printf(FOOD);
        SetPos(i, 26);
        printf(FOOD);
    }
    for (i = 1; i <= 25; i++) {
        SetPos(0, i);
        printf(FOOD);
        SetPos(56, i);
        printf(FOOD);
    }
    fflush(stdout);
}

typedef struct Node {
    int x;
    int y;
    struct Node* next;
}SnakeNode, *pSnakeNode;

enum DIRECTION { UP, DOWN, LEFT, RIGHT };
enum STATUS { OK, KILL_BY_SELF, KILL_BY_WALL, END_NORM };

typedef struct Snake {
    pSnakeNode _pSnake;       //指向整条蛇的指针
    pSnakeNode _pFood;        //指向食物的指针
    enum DIRECTION _Dir;      //蛇的运动方向
    enum STATUS _Status;      //蛇的状态
    int _SleepTime;           //停留时间
}Snake, *pSnake;

#define INIT_X 24
#define INIT_Y 5


void SnakeInit(Snake *ps)
{
    pSnakeNode cur = NULL;
    cur = malloc(sizeof(SnakeNode));
    cur->x = INIT_X;
    cur->y = INIT_Y;
    cur->next = NULL;

    //初始化蛇的数据结构
    int i = 1;
    for (; i <= 4; i++) {
        ps->_pSnake = malloc(sizeof(SnakeNode));
        ps->_pSnake->next = cur;
        ps->_pSnake->x = INIT_X + i * 2;
        ps->_pSnake->y = INIT_Y;
        cur = ps->_pSnake;
    }

    //绘制蛇
    while (cur != NULL) {
        SetPos(cur->x, cur->y);
        printf(FOOD);
        cur = cur->next;
    }

    ps->_Dir = RIGHT;
    ps->_SleepTime = 500;
    ps->_Status = OK;
}

void CreateFood(pSnake ps)
{
    pSnakeNode pFood = NULL;
    pFood = malloc(sizeof(SnakeNode));
again:
    while ((pFood->x % 2) != 0) {
        pFood->x = rand() % 52 + 2;
    }   
    pFood->y = rand() % 25 + 1;
    pSnakeNode cur = ps->_pSnake;
    while (cur != NULL) {
        if (cur->x == pFood->x && cur->y == pFood->y)
            goto again;
        cur = cur->next;
    }

    ps->_pFood = pFood;
    SetPos(pFood->x, pFood->y);
    printf(FOOD);
}

void enmu(void)
{
    SetPos(35, 10);
    printf("Welcome To Snake Game\n");
    SetPos(32, 13);
    printf("使用 ↑ ↓ ←  → 调整方向\t");
    system("pause");
    system("cls");
}

void GameStart(pSnake ps)
{
    srand(time(NULL));
    system("mode con cols=100 lines=35");//设置屏幕的大小
    enmu();
    CreateMap();
    SnakeInit(ps);
    CreateFood(ps);
}

int NextHasFood(pSnakeNode psn, pSnake ps)
{
    return psn->x == ps->_pFood->x && psn->y == ps->_pFood->y;
}

void EatFood(pSnakeNode psn, pSnake ps)
{
    pSnakeNode cur = NULL;
    psn->next = ps->_pSnake;
    ps->_pSnake = psn;
    cur = ps->_pSnake;
    while (cur != NULL) {
        SetPos(cur->x, cur->y);
        printf(FOOD);
        cur = cur->next;
    }
    CreateFood(ps);
}

void NoFood(pSnakeNode psn, pSnake ps)
{
    pSnakeNode cur = NULL;
    psn->next = ps->_pSnake;
    ps->_pSnake = psn;
    cur = ps->_pSnake;

    while (cur->next->next != NULL) {
        SetPos(cur->x, cur->y);
        printf(FOOD);
        cur = cur->next;
    }
    SetPos(cur->next->x, cur->next->y);
    printf("  ");
    free(cur->next);
    cur->next = NULL;
}

void SnakeMove(ps);

void KillByWall(pSnake ps)
{
    if (ps->_pSnake->x == 0 || ps->_pSnake->x == 56 ||
        ps->_pSnake->y == 0 || ps->_pSnake->y == 26) {
        ps->_Status = KILL_BY_WALL;

    }
}

void KillBySelf(pSnake ps)
{
    pSnakeNode cur = ps->_pSnake->next;
    while (cur != NULL) {
        if (cur->x == ps->_pSnake->x && cur->y == ps->_pSnake->y) {
            ps->_Status = KILL_BY_SELF;
            break;
        }
        cur = cur->next;
    }
}

void GameEnd(pSnake ps)
{
    SetPos(25, 15);
    switch (ps->_Status)
    {
    case KILL_BY_SELF:
        printf("很遗憾,你把自己咬死了\n");
        break;
    case KILL_BY_WALL:
        printf("很遗憾,你撞墙了\n");
        break;
    default:
        break;
    }
}

void GameRun(pSnake ps)
{
    do {
        if (GetAsyncKeyState(VK_UP) && ps->_Dir != DOWN) {
            ps->_Dir = UP;
        }
        else if (GetAsyncKeyState(VK_DOWN) && ps->_Dir != UP) {
            ps->_Dir = DOWN;
        }
        else if (GetAsyncKeyState(VK_LEFT) && ps->_Dir != RIGHT) {
            ps->_Dir = LEFT;
        }
        else if (GetAsyncKeyState(VK_RIGHT) && ps->_Dir != LEFT) {
            ps->_Dir = RIGHT;
        }
        Sleep(ps->_SleepTime);
        SnakeMove(ps);
        KillByWall(ps);
        KillBySelf(ps);
    } while (ps->_Status == OK);
    GameEnd(ps);
}

void SnakeMove(pSnake ps)
{
    pSnakeNode nextNode = malloc(sizeof(SnakeNode));
    nextNode->x = ps->_pSnake->x;
    nextNode->y = ps->_pSnake->y;

    switch(ps->_Dir) {
    case UP:
        nextNode->y -= 1;
        break;
    case DOWN:
        nextNode->y += 1;
        break;
    case RIGHT:
        nextNode->x += 2;
        break;
    case LEFT:
        nextNode->x -= 2;
        break;
    default:
        break;
    }

    if (NextHasFood(nextNode, ps)) {
        EatFood(nextNode, ps);
    }
    else { 
        NoFood(nextNode, ps);
    }
}


int main(void)
{
    Snake s;
    GameStart(&s);

    GameRun(&s);

    printf("\n");
    system("pause");
}

你可能感兴趣的:(C语言,数据结构)