C语言实现贪吃蛇(VS code环境)

代码是参考网上的(自己写了一遍 附在后面),主要是分享遇到的bug以及感悟
问题1.贪吃蛇初始方向不受控?
解决:一开始一直以为是自己控制方向的数组dy dx逻辑出错,后来才发现是自己把蛇头位置+蛇头方向 写成 蛇头位置+蛇身方向,所以乱了

问题2.贪吃蛇运动过程中,方向失控?
解决:主要是没看清楚代码 先入为主的把dy dx 方向改了

问题3:吃食物出现bug?
解决:还是move函数里面的判断出错了,逻辑问题,要多学会透过问题看本质

问题4:request时候,出bug?
解决:init函数没有及时重置相关全局变量

架构:在这里插入图片描述

感悟:
1.看代码要仔细
2.透过现象看本质
3.初始函数一定记得及时初始化各个变量
优化:
代码之间的函数联系可不可再更简化 做到高内聚 低耦合

//author shuaishuai
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#include <string.h>
#include <time.h>



int sum = 5; // snack length
int speed = 0;
char map[20][20];
int dy[4] = {0, 0, -1, 1};// w s a d
int dx[4] = {-1, 1, 0, 0};
int flag = 0; //标志位判断是否失败
int x1 = 0;
int y2 = 0;

void init();
void show();
void check();
void turn();
void food();
void move();

struct snake
{
    int x;
    int y;
    int dir;
}A[100];

int main() {
    printf("Welcome to snack game\n");
    printf("'w', 's', 'a', 'd' control\n");
    printf("Enter any key to start");
    char ch = _getch();    
    system("cls");
    init();  //初始化地图 食物 以及贪吃蛇
    show();
}

void init() {
    sum = 5;
    flag = 0;
    speed = 500;
    int i;
    int j;
    flag = 0;
    for (i = 0; i < 100; i++) {   //初始化蛇身
        A[i].x = 0;
        A[i].dir = 0;
        A[i].y = 0;
    }
    A[0].x = 1; A[0].y = 1;
    A[1].x = 1; A[1].y = 2;
    A[2].x = 1; A[2].y = 3;
    A[3].x = 1; A[3].y = 4;
    A[4].x = 1; A[4].y = 5;
    A[4].dir = 1;
    for (i = 0; i < 20; i++) {
        for (j = 0; j < 20; j++) {
            map[i][j] = '*';
        }
    }
    for (i = 1; i < 19; i++) {
        for (j = 1; j < 19; j++) {
            map[i][j] = ' ';
        }
    }
    map[A[4].x][A[4].y] = 'H';
    for (i = 0; i < 4; i++) {
        map[A[i].x][A[i].y] = 'X';
    }
    food();
}

void show() {
    int i, j, x, y;
    int speed = 500;
    for (i = 0; i < 20; i++) {
        for (j = 0; j < 20; j++) {
            printf("%c", map[i][j]);
        }
        printf("\n");
    }
    while (1) {
        Sleep(speed);
        turn();
        move();
        if (flag) {
            printf("Input 'r' to restart\nInput 'q' to quit\n");
            while (1) {
                char ch = _getch();
                if (ch == 113) { //q
                    return;
                } else if (ch == 114) { //r
                    init();
                    break;
                }
            }
        }
        system("cls");
        for (i = 0; i < 20; i++) {
            for (j = 0; j < 20; j++) {
                printf("%c", map[i][j]);
            }
            printf("\n");
        }        
    }
    
}

void food () {
    int x = 0;
    int y = 0;
    while (1) {
         x = (int)(18 * rand() / (RAND_MAX + 1.0));  //随机产生一组食物坐标
         y = (int)(18 * rand() / (RAND_MAX + 1.0));
         if(map[x][y] == ' ') {
             map[x][y] = 'o';
             break;
         }
    }
}

void turn () {
    if (_kbhit()) {
        char dir = _getch();
        switch (dir)
        {
        case 119: A[sum - 1].dir = 0; break;    
        case 115: A[sum - 1].dir = 1; break;
        case 97:  A[sum - 1].dir = 2; break;
        case 100: A[sum - 1].dir = 3; break;
        }
    }
}

void move () {
    int x, i, j;
    int t = sum; //t记录当前蛇长度
    check();
    if (t == sum) { //没吃到
        for (i = 0; i < sum - 1; i++) {
            if (i == 0) {
                map[A[i].x][A[i].y] = ' '; //蛇尾处变空格 蛇身都变前面一个
                A[i].x = A[i + 1].x;
                A[i].y = A[i + 1].y;
            }
            else {
                A[i].x = A[i + 1].x;    // 蛇身都变前面一个
                A[i].y = A[i + 1].y;                
            }
            map[A[i].x][A[i].y] = 'X'; //蛇的坐标都为X 
        }
        A[sum - 1].x = A[sum - 1].x + dx[A[sum - 1].dir]; //新蛇头位置
        A[sum - 1].y = A[sum - 1].y + dy[A[sum - 1].dir];
        map[A[sum - 1].x][A[sum - 1].y] = 'H'; 
    }
    else {  // 吃到了
        map[A[sum - 2].x][A[sum - 2].y] = 'X'; // 原先蛇头变蛇身
        A[sum - 1].x = A[sum - 2].x + dx[A[sum - 2].dir]; //新蛇头位置
        A[sum - 1].y = A[sum - 2].y + dy[A[sum - 2].dir];
        A[sum - 1].dir = A[sum - 2].dir; //蛇头方向不变
        map[A[sum - 1].x][A[sum - 1].y] = 'H'; 
        food();
    }
}

void check () {  // 检查死亡还是吃到食物
    int i, j;
    x1 = A[sum - 1].x + dx[A[sum - 1].dir];
    y2 = A[sum - 1].y + dy[A[sum - 1].dir];
    if (map[x1][y2] == '*' || map[x1][y2] == 'X') { // 如果死亡
        if (x1 != A[0].x || y2 != A[0].y) { 
            // 蛇尾碰触不算死亡
            map[8][4] = 'G'; map[8][5] = 'A'; map[8][6] = 'M'; map[8][7] = 'E';  //输出“GAME OVER” 
            map[8][9] = 'O'; map[8][10] = 'V'; map[8][11] = 'E'; map[8][12] = 'R';
            map[8][8] = ' ';
            system("cls");
            for (i = 0; i < 20; i++) {  //  
                for (j = 0; j < 20; j++) {
                    printf("%c", map[i][j]);
                }
            printf("\n");
            }
            flag = 1;
        }
    }  
    else if (map[x1][y2] == 'o') { // 吃到
        sum++;
    }
}

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是一个简单的C语言实现贪吃蛇的代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <time.h> #include <conio.h> #include <windows.h> #define WIDTH 40 // 地图宽度 #define HEIGHT 20 // 地图高度 #define SNAKE_MAX_LENGTH 100 // 蛇的最大长度 int map[HEIGHT][WIDTH]; // 地图数组,0表示空格,1表示蛇身,2表示食物 int snake[SNAKE_MAX_LENGTH][2]; // 蛇身坐标数组,存储每个蛇节的横纵坐标 int snake_length = 3; // 蛇的长度 int food_x, food_y; // 食物的横纵坐标 int direction = 0; // 蛇的移动方向,0表示上,1表示右,2表示下,3表示左 // 初始化地图 void init_map() { for (int i = 0; i < HEIGHT; i++) { for (int j = 0; j < WIDTH; j++) { map[i][j] = 0; } } } // 初始化蛇 void init_snake() { snake[0][0] = HEIGHT / 2; snake[0][1] = WIDTH / 2; map[snake[0][0]][snake[0][1]] = 1; snake[1][0] = HEIGHT / 2 + 1; snake[1][1] = WIDTH / 2; map[snake[1][0]][snake[1][1]] = 1; snake[2][0] = HEIGHT / 2 + 2; snake[2][1] = WIDTH / 2; map[snake[2][0]][snake[2][1]] = 1; } // 生成食物 void generate_food() { int x, y; do { x = rand() % HEIGHT; y = rand() % WIDTH; } while (map[x][y] != 0); food_x = x; food_y = y; map[food_x][food_y] = 2; } // 显示地图 void show_map() { system("cls"); // 清屏 for (int i = 0; i < HEIGHT; i++) { for (int j = 0; j < WIDTH; j++) { if (i == food_x && j == food_y) { // 食物 printf("O"); } else if (map[i][j] == 1) { // 蛇身 printf("#"); } else { // 空格 printf(" "); } } printf("\n"); } } // 检测是否吃到食物 void check_eat_food() { if (snake[0][0] == food_x && snake[0][1] == food_y) { snake_length++; generate_food(); } } // 检测是否撞到墙或自己 void check_dead() { if (snake[0][0] < 0 || snake[0][0] >= HEIGHT || snake[0][1] < 0 || snake[0][1] >= WIDTH) { exit(0); } for (int i = 1; i < snake_length; i++) { if (snake[i][0] == snake[0][0] && snake[i][1] == snake[0][1]) { exit(0); } } } // 移动蛇 void move_snake() { // 计算蛇头新的位置 int new_head_x = snake[0][0], new_head_y = snake[0][1]; switch (direction) { case 0: new_head_x--; break; // 上 case 1: new_head_y++; break; // 右 case 2: new_head_x++; break; // 下 case 3: new_head_y--; break; // 左 } // 更新蛇身坐标数组和地图数组 for (int i = snake_length - 1; i > 0; i--) { snake[i][0] = snake[i - 1][0]; snake[i][1] = snake[i - 1][1]; map[snake[i][0]][snake[i][1]] = 1; } snake[0][0] = new_head_x; snake[0][1] = new_head_y; map[snake[0][0]][snake[0][1]] = 1; } // 键盘输入事件 void keyboard_event() { if (_kbhit()) { // 判断是否有键盘输入 char ch = _getch(); switch (ch) { case 'w': direction = 0; break; // 上 case 'd': direction = 1; break; // 右 case 's': direction = 2; break; // 下 case 'a': direction = 3; break; // 左 } } } int main() { // 初始化 srand(time(NULL)); // 设置随机数种子 init_map(); init_snake(); generate_food(); // 游戏循环 while (1) { show_map(); check_eat_food(); check_dead(); move_snake(); keyboard_event(); Sleep(100); // 等待一段时间,控制蛇的移动速度 } return 0; } ``` 该示例代码使用了Windows系统的控制台API,如果在其他操作系统下运行需要进行适当修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值