大神求助,贪吃蛇自动移动出现问题?

问题应该出在main函数中的那个死循环里,我想的是判断按键按下时改变ch的值否则ch一直保持不变。但是运行时就能变成开始时自动移动,但我按下按键后,必须每按一次蛇cai'neng移动一格。

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
#include<ctype.h>
#include<time.h> //引用头文件
//预处理
#define WIDTH 40
#define HEIGHT 20
typedef struct line{
    int x;
    int y;
    struct line*next;
    struct line*before;
}snake;
struct  {
    int x;
    int y;
}food;
int snakesize=0;
struct {
    snake *head;
    snake *tail;
}mark;
void initialization();
void gotoxy(int, int);
void creatfood();
void snakegrown();
void showsnake();
void snakemove(int,int);
void eatfood();
int judge();

int main(void)
{
    char ch = 'A';
    initialization();
        while (1)
    {
            switch (ch)
            {
            case'W':
                snakemove(0, -1);
                break;
            case'A':snakemove(-2, 0);
                break;
            case'S':snakemove(0, 1);
                break;
            case'D':snakemove(2, 0);
                break;
            default:
                break;
            }
            if (_kbhit())
                ch = toupper(_getch());         
}
    gotoxy(0, HEIGHT + 1);
    system("pause");
    return 0;
}

void initialization()
{
    int x, y;
    mark.head = (snake*)malloc(sizeof(snake));
    mark.tail = mark.head;
    mark.head->x = WIDTH / 2;
    mark.head->y = HEIGHT / 2;
    mark.head->before = NULL;
    mark.head->next = NULL;//snakesize=1
    snakesize++;
    for (x = 0; x <= WIDTH; x += 2)
    {
        gotoxy(x, 0);
        printf("█");
        gotoxy(x, HEIGHT);
        printf("█");
    }
    for (y = 0; y <= HEIGHT; y++)
    {
        gotoxy(0, y);
        printf("█");
        gotoxy(WIDTH,y );
        printf("█");
    }
    while(snakesize <3)
        snakegrown();

    showsnake();
    creatfood();
    gotoxy(0, HEIGHT+1);
    puts("按下任意按键开始游戏");
}

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

void creatfood()
{
    snake* pc;
    srand((unsigned int)time(NULL));
    food.x = (rand()*2) % (WIDTH - 4) + 2;
    food.y = rand() % (HEIGHT - 2) + 1;     //限定刷新范围
    for(pc=mark.head;pc!=NULL;pc=pc->next)  //不能刷新在蛇身
        if (pc->x == food.x&&pc->y == food.y)
        {
            food.x = (rand() * 2) % (WIDTH - 4) + 2;
            food.y = rand() % (HEIGHT - 2) + 1;
            continue;
        }
    gotoxy(food.x, food.y);
    printf("回");
}

void snakegrown()
{
    struct line* pa;
    if (snakesize < 3)
    {
        pa = (snake*)malloc(sizeof(struct line));
        pa->next = NULL;
        pa->before = mark.tail;
        pa->x =mark.tail->x+2;
        pa->y = mark.tail->y;
        mark.tail->next = pa;
        mark.tail = mark.tail->next;
    }
    else
    {

        pa = (snake*)malloc(sizeof(struct line));
        pa->next = NULL;
        pa->before = mark.tail;
        pa->x = mark.tail->x;
        pa->y = mark.tail->y;
        mark.tail->next = pa;
        mark.tail = mark.tail->next;
    }
    snakesize++;
}
void snakemove(int i,int j)
{
    snake*pc;
    pc = mark.tail;
        while (pc->before != NULL)
        {
            gotoxy(mark.tail->x, mark.tail->y);
            printf("  ");
            pc->x = pc->before->x;
            pc->y = pc->before->y;
            pc = pc->before;
        }
        mark.head->x += i;
        mark.head->y += j;
        showsnake();
        if (judge() == 1)
        {
            gotoxy(WIDTH / 2, HEIGHT / 2);
            printf("你的分数为%d\n", snakesize - 3);
            gotoxy(WIDTH / 2, HEIGHT / 2 + 1);
            system("pause");
            exit(0);
        }
        Sleep(200);

}
void eatfood()
{
    if (food.x == mark.head->x&&food.y == mark.head->y)
    {
        snakegrown();
        creatfood();
    }
}
int judge()
{
    snake*pc;
    if (mark.head->x < 2 || mark.head->x > WIDTH || mark.head->y < 1 || mark.head->y >=HEIGHT)
        return 1;
    for (pc = mark.head->next; pc != NULL; pc = pc->next)
        if (mark.head->x == pc->x&&mark.head->y == pc->y)
            return 1;
    return 0;
}
void showsnake() 
{
    snake*pc;
    int i = 1;
    for (pc = mark.head; pc!= NULL; pc = pc->next)
    {
        gotoxy(pc->x, pc->y);
        printf("█");
    }
    eatfood();
}
c++

2个回答

楼主再修改一下。
用一个tmp先接受键盘输入,你想按下其他按键,ch保持不变,可以筛选输入,如果为WASD,且没有反向,改变ch,否则ch不变,也就是继续移动。

另外程序有个小bug,贪吃蛇可以移动到右边界上,甚至可以把右边界吃了..

strchr 头文件 string.h

 int main(void)
{
    char ch = 'A';
    char tmp;
    initialization();
    while (1)
    {
        switch (ch)
        {
        case'W':
            snakemove(0, -1);
            break;
        case'A':snakemove(-2, 0);
            break;
        case'S':snakemove(0, 1);
            break;
        case'D':snakemove(2, 0);
            break;
        default:
            break;
        }
        if (_kbhit()) {
            tmp = toupper(_getch());
            if (strchr("WASD", tmp) != NULL && !((ch == 'W'&&tmp == 'S') || (ch == 'S'&&tmp == 'W') || (ch == 'A'&&tmp == 'D') || (ch == 'D'&&tmp == 'A')))
                ch = tmp;
        }
    }
    gotoxy(0, HEIGHT + 1);
    system("pause");
    return 0;
}
qq_40946921
Italink 回复weixin_43215350: 我这边是正常的,按下任意键,蛇就开始移动了,然后WASD转向,或者你加我Q:657959053
大约一年之前 回复
weixin_43215350
Mr Single 回复qq_40946921: 贴在下面了
大约一年之前 回复
qq_40946921
Italink 回复weixin_43215350: 我这边是正常的,你可以把你代码再贴一遍吗
大约一年之前 回复
weixin_43215350
Mr Single 回复qq_40946921: 我这边,第一次按下按键后,蛇就停住了,要我一直按键盘他才能移动啊,你运行的结果是正常的吗,我电脑有问题?
大约一年之前 回复
qq_40946921
Italink 回复weixin_43215350: 我没懂你说的自行移动啥意思,蛇不是一直在跑么...
大约一年之前 回复
weixin_43215350
Mr Single 谢谢老哥完善代码和指出bug,bug已改,但是蛇还是无法自行移动。。。
大约一年之前 回复
 #include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
#include<ctype.h>
#include<time.h>
//预处理
#define WIDTH 40
#define HEIGHT 20
typedef struct line{
    int x;
    int y;
    struct line*next;
    struct line*before;
}snake;
struct  {
    int x;
    int y;
}food;
int snakesize=0;
struct {
    snake *head;
    snake *tail;
}mark;
void initialization();
void gotoxy(int, int);
void creatfood();
void snakegrown();
void showsnake();
void snakemove(int,int);
void eatfood();
int judge();

int main(void)
{
    char ch = 'A';
    char tmp;
    initialization();
    while (1)
    {
        switch (ch)
        {
        case'W':
            snakemove(0, -1);
            break;
        case'A':snakemove(-2, 0);
            break;
        case'S':snakemove(0, 1);
            break;
        case'D':snakemove(2, 0);
            break;
        default:
            break;
        }
        if (_kbhit()) {
            tmp = toupper(_getch());
            ch = strchr("WASD", tmp) != NULL ? tmp : ch; //ch不接受WSAD以外的按键
        }

    }
    gotoxy(0, HEIGHT + 1);
    system("pause");
    return 0;
}

void initialization()
{
    int x, y;
    mark.head = (snake*)malloc(sizeof(snake));
    mark.tail = mark.head;
    mark.head->x = WIDTH / 2;
    mark.head->y = HEIGHT / 2;
    mark.head->before = NULL;
    mark.head->next = NULL;//snakesize=1
    snakesize++;
    for (x = 0; x <= WIDTH; x += 2)
    {
        gotoxy(x, 0);
        printf("█");
        gotoxy(x, HEIGHT);
        printf("█");
    }
    for (y = 0; y <= HEIGHT; y++)
    {
        gotoxy(0, y);
        printf("█");
        gotoxy(WIDTH,y );
        printf("█");
    }
    while(snakesize <3)
        snakegrown();

    showsnake();
    creatfood();
    gotoxy(0, HEIGHT+1);
    system("pause");
}

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

void creatfood()
{
    snake* pc;
    srand((unsigned int)time(NULL));
    food.x = (rand()*2) % (WIDTH - 4) + 2;
    food.y = rand() % (HEIGHT - 2) + 1;     //限定刷新范围
    for(pc=mark.head;pc!=NULL;pc=pc->next)  //不能刷新在蛇身
        if (pc->x == food.x&&pc->y == food.y)
        {
            food.x = (rand() * 2) % (WIDTH - 4) + 2;
            food.y = rand() % (HEIGHT - 2) + 1;
            continue;
        }
    gotoxy(food.x, food.y);
    printf("回");
}

void snakegrown()
{
    struct line* pa;
    if (snakesize < 3)
    {
        pa = (snake*)malloc(sizeof(struct line));
        pa->next = NULL;
        pa->before = mark.tail;
        pa->x =mark.tail->x+2;
        pa->y = mark.tail->y;
        mark.tail->next = pa;
        mark.tail = mark.tail->next;
    }
    else
    {

        pa = (snake*)malloc(sizeof(struct line));
        pa->next = NULL;
        pa->before = mark.tail;
        pa->x = mark.tail->x;
        pa->y = mark.tail->y;
        mark.tail->next = pa;
        mark.tail = mark.tail->next;
    }
    snakesize++;
}
void snakemove(int i,int j)
{
    snake*pc;
    pc = mark.tail;
        while (pc->before != NULL)
        {
            gotoxy(mark.tail->x, mark.tail->y);
            printf("  ");
            pc->x = pc->before->x;
            pc->y = pc->before->y;
            pc = pc->before;
        }
        mark.head->x += i;
        mark.head->y += j;
        showsnake();
        if (judge() == 1)
        {
            gotoxy(WIDTH / 2, HEIGHT / 2);
            printf("你的分数为%d\n", snakesize - 3);
            gotoxy(WIDTH / 2, HEIGHT / 2 + 1);
            system("pause");
            exit(0);
        }
        Sleep(200);

}
void eatfood()
{
    if (food.x == mark.head->x&&food.y == mark.head->y)
    {
        snakegrown();
        creatfood();
    }
}
int judge()
{
    snake*pc;
    if (mark.head->x < 2 || mark.head->x > WIDTH-2 || mark.head->y < 1 || mark.head->y >=HEIGHT)
        return 1;
    for (pc = mark.head->next; pc != NULL; pc = pc->next)
        if (mark.head->x == pc->x&&mark.head->y == pc->y)
            return 1;
    return 0;
}
void showsnake() 
{
    snake*pc;
    int i = 1;
    for (pc = mark.head; pc!= NULL; pc = pc->next)
    {
        gotoxy(pc->x, pc->y);
        printf("█");
    }
    eatfood();
}

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!