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++;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值