简易贪食蛇C语言

 #ifndef __SNAKE_H_ 

#define __SNAKE_H_
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h> //linux线程,编译文件需链接 -lpthread
#include <time.h>


#define MAX     100//最大长度

#define W       40 //游戏界面宽
#define H       20 //游戏界面高
#define HEAD     '@' //头形状
#define FOOD     'o' //食物和身体形状
#define TAIL    '*' //尾巴形状


#define UP       1 //方向
#define DOWN     2
#define LEFT     3
#define RIGHT   4


char board[W][H] = {}; //游戏界面用二维数组表示


struct node_t { //每个节点信息
    int x;//x坐标
    int y;//y坐标
    struct node_t *next;
    struct node_t *prev;
};


struct snake_t { //创建贪食蛇链表信息
    int num; //目前蛇的长度
    int speed; //行走速度
    int step; //步长
    int dir; //方向
    int quit; //游戏结束标志位
    struct node_t *head; //定义指向蛇头指针
    struct node_t *tail; //定义指向蛇尾指针
};


struct snake_t *snake_init(int x, int y, int speed); //初始化
void *snake_run(void *arg); //运行函数
void snake_del(struct snake_t *snake); //链表销毁函数


#endif

====================================================================================================================================

#include "snake.h"


struct snake_t *snake_init(int x, int y, int speed)
{
    struct snake_t *snake = NULL;
    struct node_t *new = NULL;


    snake = (struct snake_t *)malloc(sizeof(struct snake_t));
    new = (struct node_t *)malloc(sizeof(struct node_t));


    new->x = x;
    new->y = y;
    new->next = NULL;
    new->prev = NULL;
    snake->head = new;
    snake->tail = new;


    snake->speed = speed;
    snake->num = 0;
    snake->step = 1;
    snake->dir = 0;
    snake->quit = 0;


    return snake;
}

/*添加一个节点*/
void add_node(struct snake_t **snake, int x, int y)
{
    struct node_t *new = NULL;


    new = (struct node_t *)malloc(sizeof(struct node_t));
    new->x = x;
    new->y = y;
    (*snake)->num++;


    new->next = NULL;
    new->prev = (*snake)->head;
    (*snake)->head->next = new;
    (*snake)->head = new;
}

/*画游戏界面*/
void drawboard(struct snake_t *snake)
{
    int i, j;
    struct node_t *tail = NULL;


        printf("\033[1;1H\033[2J"); //linux系统终端VT码,实现定位,清屏
        for (tail = snake->head; tail != NULL; tail = tail->prev)
        {
            if (tail == snake->head)
                board[tail->x][tail->y] = HEAD;
            else if (tail == snake->tail)
                board[tail->x][tail->y] = TAIL;
            else
                board[tail->x][tail->y] = FOOD;
        }
        for (j = 1; j <= H; j++)
        {
            for (i = 1; i <= W; i++)
            {
                if (i == 1 || i == W || j == 1 || j == H)
                    printf("#");
                else if (board[i][j] == 1)
                    printf("o");
                else if (board[i][j] == 0)
                    printf(" ");
                else
                    printf("%c", board[i][j]);
            }
            printf("\n");
        }
}

/*随机一个坐标*/
void food(void)
{
    int x, y;


    srand(time(NULL));
RAND:
    x = rand() % (W - 2) + 2;
    y = rand() % (H - 2) + 2;
    if (board[x][y] == HEAD || board[x][y] == FOOD || board[x][y] == TAIL)
        goto RAND;


    board[x][y] = 1;
}

/*检测目前界面中有无食物,没有随机放置*/
int set_food(void)
{
    int i, j;


    for (i = 1; i <= W; i++)
    {
        for (j = 1; j <= H; j++)
        {
            if (board[i][j] == 1)
                return 0;
        }
    }
    food();


    return 0;
}


/*移动*/
void move(struct snake_t *snake, int dir)
{
    struct node_t *tail = snake->tail;


    board[tail->x][tail->y] = 0;


    for (tail = snake->tail; tail != NULL; tail = tail->next)
    {
        if (tail == snake->head && dir != 0)
        {
            if (dir == LEFT || dir == RIGHT)
            {
                tail->x += snake->step;
                if (board[tail->x + snake->step][tail->y] == 1)
                {
                    add_node(&snake, tail->x + snake->step, tail->y);
                    board[tail->x + snake->step][tail->y] = 0;
                }
                else if ((board[tail->x][tail->y + snake->step] == 1 || board[tail->x][tail->y - snake->step] == 1)
                            && (dir == UP || dir == DOWN))
                {
                    add_node(&snake, tail->x + snake->step, tail->y);
                    board[tail->x + snake->step][tail->y] = 0;
                }
            }


            else if (dir == UP || dir == DOWN)
            {
                tail->y += snake->step;
                if (board[tail->x][tail->y + snake->step] == 1)
                {
                    add_node(&snake, tail->x, tail->y + snake->step);
                    board[tail->x][tail->y + snake->step] = 0;
                }
            }
        }


        else 
        {
            if (dir != 0)
            {
                tail->x = tail->next->x;
                tail->y = tail->next->y;
            }
        }
    }
}

/*获取按键信息*/
int getInput(void)
{
    char ch[8];
    int ret;


    ret = read(0, ch, 8);


    if (ret == 1)
        return ch[0];
    else if (ret == 3 && ch[0] == 27 && ch[1] == 91)
        return ch[2] + 127;


    return -1;
}


/*按键处理*/
void *key_handler(void *arg)
{
    char ch;
    struct node_t *tail = NULL;
    struct snake_t *snake = (struct snake_t *)arg;


    while (1)
    {
        ch = getchar();
        switch (ch)
        {
            case 'h':
                if (snake->dir != RIGHT)
                {
                    snake->step = -1;
                    snake->dir = LEFT;
                }
                break;
            case 'l':
                if (snake->dir != LEFT)
                {
                    snake->step = 1;
                    snake->dir = RIGHT;
                }
                break;
            case 'j':
                if (snake->dir != UP)
                {
                    snake->step = 1;
                    snake->dir = DOWN;
                }
                break;
            case 'k':
                if (snake->dir != DOWN)
                {
                    snake->step = -1;
                    snake->dir = UP;
                }
                break;
            case 'q':
                snake->quit = 1;
        }
    usleep(1000);
    }
}

/*检测游戏运行状态*/
void dead_check(void *arg)
{
    struct snake_t *snake = (struct snake_t *)arg;
    struct node_t *tail = NULL;


    if (snake->head->x <= 1 || snake->head->x >= W || snake->head->y >= H || snake->head->y <= 1)
    {
        printf("\033[11;60H GAME OVER!\n");
        snake->quit = 1;
        return;
    }
    else
    {
        for (tail = snake->tail; tail != snake->head; tail = tail->next)
        {
            if ((tail->x == snake->head->x) && (tail->y == snake->head->y))
            {
                printf("\033[11;60H GAME OVER!\n");
                snake->quit = 1;
                return;
            }
        }
    }
}


void *snake_run(void *arg)
{
    struct snake_t *snake = (struct snake_t *)arg;


    while (1)
    {
        set_food();
        move(snake, snake->dir);
        drawboard(snake);
        printf("\033[10;60H Score: %d\n", snake->num);

        usleep(snake->speed);
    }
}


void snake_del(struct snake_t *snake)
{
    struct node_t *tail = NULL;


    for (tail = snake->head; tail != NULL; tail = tail->prev)
        free(tail);
    free(snake);
}


int main(void)
{
    struct snake_t *snake = NULL; 
    pthread_t tid, tid1;
    char ch, flag = 0;

    system("stty -echo -icanon");
    snake = snake_init(W / 2, H / 2, 400000);
    pthread_create(&tid, NULL, snake_run, snake);
    pthread_create(&tid1, NULL, key_handler, snake);


    while (!snake->quit)
    {
        dead_check(snake);
        if ((snake->num > 0) && (flag == 0) && (snake->num % 10 == 0))
        {
            snake->speed = snake->speed * 4 / 5;
            flag = 1;
        }
        else
            flag = 0;

        if (snake->num == MAX)
            printf("\033[11;60H YOU WIN\n");


        usleep(10000);
    }
    printf("\033[%d;1H", H + 1);
    snake_del(snake);

    system("stty echo icanon");

    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的贪食蛇游戏的C语言实现,你可以参考一下: ```c #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <windows.h> #define WIDTH 40 // 游戏界面宽度 #define HEIGHT 20 // 游戏界面高度 int snake[100][2]; // 蛇身数组 int food[2]; // 食物位置 int length = 1; // 蛇身长度 int direction = 3; // 蛇头方向,1:上,2:左,3:下,4:右 // 在指定位置输出字符 void gotoxy(int x, int y) { COORD coord; coord.X = x; coord.Y = y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); } // 初始化游戏 void init() { // 初始化蛇头位置 snake[0][0] = WIDTH / 2; snake[0][1] = HEIGHT / 2; // 随机生成食物位置 food[0] = rand() % WIDTH; food[1] = rand() % HEIGHT; } // 绘制游戏界面 void draw() { // 清空屏幕 system("cls"); // 绘制游戏界面 for (int i = 0; i < WIDTH + 2; i++) { printf("#"); } printf("\n"); for (int i = 0; i < HEIGHT; i++) { printf("#"); for (int j = 0; j < WIDTH; j++) { if (i == snake[0][1] && j == snake[0][0]) { printf("O"); // 绘制蛇头 } else if (i == food[1] && j == food[0]) { printf("X"); // 绘制食物 } else { int flag = 0; for (int k = 1; k < length; k++) { if (i == snake[k][1] && j == snake[k][0]) { printf("o"); // 绘制蛇身 flag = 1; break; } } if (!flag) { printf(" "); } } } printf("#"); printf("\n"); } for (int i = 0; i < WIDTH + 2; i++) { printf("#"); } printf("\n"); } // 蛇移动 void move() { // 记录蛇尾位置 int tail[2]; tail[0] = snake[length - 1][0]; tail[1] = snake[length - 1][1]; // 移动蛇身 for (int i = length - 1; i > 0; i--) { snake[i][0] = snake[i - 1][0]; snake[i][1] = snake[i - 1][1]; } // 移动蛇头 switch (direction) { case 1: snake[0][1]--; break; case 2: snake[0][0]--; break; case 3: snake[0][1]++; break; case 4: snake[0][0]++; break; } // 判断是否撞墙或撞到自己的身体 if (snake[0][0] < 0 || snake[0][0] >= WIDTH || snake[0][1] < 0 || snake[0][1] >= HEIGHT) { printf("Game over!\n"); exit(0); } for (int i = 1; i < length; i++) { if (snake[0][0] == snake[i][0] && snake[0][1] == snake[i][1]) { printf("Game over!\n"); exit(0); } } // 判断是否吃到食物 if (snake[0][0] == food[0] && snake[0][1] == food[1]) { length++; food[0] = rand() % WIDTH; food[1] = rand() % HEIGHT; } // 清除蛇尾 gotoxy(tail[0] + 1, tail[1] + 1); printf(" "); } // 处理键盘输入 void input() { if (_kbhit()) { int key = _getch(); switch (key) { case 'w': if (direction != 3) { direction = 1; } break; case 'a': if (direction != 4) { direction = 2; } break; case 's': if (direction != 1) { direction = 3; } break; case 'd': if (direction != 2) { direction = 4; } break; } } } int main() { // 初始化游戏 init(); // 游戏循环 while (1) { // 绘制游戏界面 draw(); // 蛇移动 move(); // 处理键盘输入 input(); // 延时 Sleep(100); } return 0; } ``` 上面的代码使用了Windows API中的`gotoxy`函数来实现在指定位置输出字符的功能,如果你在其他操作系统上运行可能会出现问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值