这串代码写出来的电脑控制的蛇不知道为什么会上下反复横跳,望知其原因和修改意见

#include<bits/stdc++.h>
#include<windows.h>
#include<conio.h>
#include<cstdio>
using namespace std;
char ch; 
int headx = 58 , heady = 13; 
int enemy_headx = 27 , enemy_heady = 9; 
int score = 0;
vector<vector<int>> candy;  
vector<vector<int>> body; 
vector<int> clone_body;
vector<int> head;
vector<vector<int>> enemy_body; 
vector<int> enemy_clone_body;
vector<int> enemy_head; 
void gotoxy(short x, short y) 
{
    COORD coord = {x, y};
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void print_candy(int headx , int heady , int enemy_headx , int enemy_heady)
{
    int ret = 0;
    for(auto x : candy)
    {
        if(headx == x[0] && heady == x[1])  
        {
            candy.erase(candy.begin() + ret);
            score += 5;
            clone_body.resize(0);
            if(body.size() > 1)
            {
                clone_body.push_back( body[body.size() - 1][0] + 1 );
                clone_body.push_back( body[body.size() - 1][1] );
                body.push_back(clone_body);
            }
            else
            {
                clone_body.push_back(headx+1);
                clone_body.push_back(heady);
                body.push_back(clone_body);
            } 
            print_candy(headx,heady,enemy_headx,enemy_heady);    
            break;
        }
        else if(enemy_headx == x[0] && enemy_heady == x[1])
        {
            candy.erase(candy.begin() + ret);
            enemy_clone_body.resize(0);
            if(enemy_body.size() > 1)
            {
                enemy_clone_body.push_back( enemy_body[enemy_body.size() - 1][0] + 1 );
                enemy_clone_body.push_back( enemy_body[enemy_body.size() - 1][1] );
                enemy_body.push_back(enemy_clone_body);
            }
            else
            {
                enemy_clone_body.push_back(enemy_headx+1);
                enemy_clone_body.push_back(enemy_heady);
                enemy_body.push_back(enemy_clone_body);
            } 
            print_candy(headx,heady,enemy_headx,enemy_heady);
            break;
        }
        else
        {
            gotoxy(x[0],x[1]);
            cout<<"*";
        }
        ret++;
    }    
}
void print_edge()
{
    for(int i = 5; i <= 109 ; i++) { gotoxy(i,4); cout << "__"; }
    for(int i = 5; i <= 109 ; i++) { gotoxy(i,22); cout << "__"; }
    for(int i = 5; i <= 22 ; i++) { gotoxy(5,i); cout << "|"; }
    for(int i = 5; i <= 22 ; i++) { gotoxy(110,i); cout << "|"; }
}
bool if_enemy_touch_me()
{
    for(int i = body.size()-1 ; i >= 0 ; i--)
    {
        if(enemy_head[0] == body[i][0] && enemy_head[1] == body[i][1]) return true;
    }
    return false;
}
bool if_i_touch_enemy()
{
    for(int i = enemy_body.size()-1 ; i >= 0 ; i--)
    {
        if(head[0] == enemy_body[i][0] && head[1] == enemy_body[i][1]) return true;
    }
    return false;
}
void enemy_move_head(int headx , int heady)
{
    int u=0,d=0,l=0,r=0;
    bool judge = true;
    for(auto x : candy)
    {
        if(enemy_head[0]+1==x[0]&&enemy_head[1]==x[1]) 
        {
            judge=false;
            if(enemy_head[0]+1==109) r=INT_MIN;
            else if(enemy_head[1]==heady&&enemy_head[0]+1==headx) r=INT_MIN;
            else r += 10;
        }
        else if(enemy_head[0]-1==x[0]&&enemy_head[1]==x[1]) 
        {
            judge=false;
            if(enemy_head[0]-1==5) l=INT_MIN;
            else if(enemy_head[1]==heady&&enemy_head[0]-1==headx) l=INT_MIN;
            else l += 10;
        }
        else if(enemy_head[0]==x[0]&&enemy_head[1]+1==x[1]) 
        {
            judge=false;
            if(enemy_head[1]+1==21) u=INT_MIN;
            else if(enemy_head[1]+1==heady&&enemy_head[0]==headx) u=INT_MIN;
            else u += 10;
        }
        else if(enemy_head[0]==x[0]&&enemy_head[1]-1==x[1]) 
        {
            judge=false;
            if(enemy_head[1]-1==5) d=INT_MIN;
            else if(enemy_head[1]-1==heady&&enemy_head[0]==headx) d=INT_MIN;
            else d += 10;
        }
    }
    if(judge)
    {
        if(enemy_heady-1==5) d=INT_MIN;
        else if(enemy_heady-1==heady&&enemy_headx==headx) d=INT_MIN;
        if(enemy_heady+1==21) u=INT_MIN;
        else if(enemy_heady+1==heady&&enemy_headx==headx) u=INT_MIN;
        if(enemy_headx-1==5) l=INT_MIN;
        else if(enemy_heady==heady&&enemy_headx-1==headx) l=INT_MIN;
        if(enemy_headx+1==109) r=INT_MIN;
        else if(enemy_heady==heady&&enemy_headx+1==headx) r=INT_MIN;
    }
    int a[4] = {d,u,l,r};
    sort(a,a+5);
    if(a[3]==d) enemy_heady++;
    else if(a[3]==u) enemy_heady--;
    else if(a[3]==l) enemy_headx--;
    else if(a[3]==r) enemy_headx++;
}
int main()
{
    print_edge();
    for(int i = 0 ; i <= 320 ; i++) 
    {
        int candyx = rand()%(100) + 6 , candyy = rand()%(15)+6;
        gotoxy(candyx,candyy); 
        candy.resize(321);
        candy[i].resize(3);
        candy[i][0] = candyx;
        candy[i][1] = candyy;
        cout<<"*";
    }
    head.push_back(headx);
    head.push_back(heady);
    gotoxy(headx,heady);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
    cout<<"o";
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);
    enemy_head.push_back(enemy_headx);
    enemy_head.push_back(enemy_heady);
    gotoxy(enemy_headx,enemy_heady);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);
    cout<<"E";
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);
    int life = 3,enemy_life = 4; 
    gotoxy(5,24);
    cout << "life :";
    for(int i = 1 ; i <= 3 ; i++)  cout << "# ";
    cout << "           enemy life : ";
    for(int i = 1 ; i <= 4 ; i++)  cout << "$ ";
    gotoxy(5,25);
    cout<< "score : " << score;
    gotoxy(5,27);
    cout << "注意 :不要去边缘!";
    gotoxy(5,27);
    cout<<"敌方长度:1"<<"    我方长度:1"; 
    gotoxy(5,26); 
    cout << "请在输入指示符wasd(不需要按换行键)";
    while(true)
    {    
        if(_kbhit())
        {
            ch = _getch();
            int judgex = 0;
            if(headx < 109 && headx > 5 && heady > 5 && heady < 21)
            {
                if(ch == 'w') heady-=1; 
                if(ch == 's') heady+=1;
                if(ch == 'a') headx-=1;
                if(ch == 'd') headx+=1;
            }    
            if(headx == 109) { headx = 108;  life--; } 
            if(heady == 21)  { heady = 20;   life--; } 
            if(heady == 5)   { heady = 6;    life--; }
            if(headx == 5)   { headx = 6;    life--; }
            enemy_move_head(headx , heady);
            if(enemy_headx == 109) { enemy_headx = 108;  enemy_life--; } 
            if(enemy_heady == 21)  { enemy_heady = 20;   enemy_life--; } 
            if(enemy_heady == 5)   { enemy_heady = 6;    enemy_life--; }
            if(enemy_headx == 5)   { enemy_headx = 6;    enemy_life--; }
            gotoxy(0,0);
            system("cls");
            print_edge();
            print_candy(headx,heady,enemy_headx,enemy_heady);
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
            if(body.size() > 1) 
            {
                for(auto i = body.size() - 1 ; i >= 1 ; i--)  
                {
                    body[i][0] = body[i - 1][0];
                    body[i][1] = body[i - 1][1];
                    gotoxy(body[i][0],body[i][1]);
                    cout<<"+";
                }
            }
            if(body.size() != 0) 
            {
                body[0][0] = head[0] , body[0][1] = head[1];
                gotoxy(body[0][0],body[0][1]);
                cout<<"+";
            }
            else if(body.size() == 1)
            {
                gotoxy(body[0][0],body[0][1]);
                cout<<"+";
            } 
            gotoxy(headx,heady); 
            cout<<"o";
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);
            if(enemy_body.size() > 1) 
            {
                for(auto i = enemy_body.size() - 1 ; i >= 1 ; i--)  
                {
                    enemy_body[i][0] = enemy_body[i - 1][0];
                    enemy_body[i][1] = enemy_body[i - 1][1];
                    gotoxy(enemy_body[i][0],enemy_body[i][1]);
                    cout<<"+";
                }
            }
            if(enemy_body.size() != 0) 
            {
                enemy_body[0][0] = enemy_head[0] , enemy_body[0][1] = enemy_head[1];
                gotoxy(enemy_body[0][0],enemy_body[0][1]);
                cout<<"+";
            }
            else if(enemy_body.size() == 1)
            {
                gotoxy(enemy_body[0][0],enemy_body[0][1]);
                cout<<"+";
            } 
            gotoxy(enemy_headx,enemy_heady);
            cout<<"E";
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);
            if(if_i_touch_enemy() == true) life--;
            if(if_enemy_touch_me() == true) 
            {
                score+=10;
                enemy_life--;
            }
            gotoxy(5,24);
            if(life == 0) 
            {
                Sleep(800);
                Beep(698,700);
                Sleep(100);
                cout << "You lose! Your life is zero!" << endl << endl << "     本次得分:" << score << "分!";
                return 0;
            }
            if(enemy_life == 0) 
            {
                Sleep(800);
                Beep(698,700);
                Sleep(100);
                cout << "You win!" << endl << endl << "     本次得分:" << score << "分!" << endl  << endl << endl << endl << endl << endl;
                return 0;
            }
            cout << "life : ";
            for(int i = 1 ; i <= life ; i++)  cout << "# ";
            cout << "           enemy life : ";
            for(int i = 1 ; i <= enemy_life ; i++)  cout << "$ ";
            gotoxy(5,25);
            cout<< "score : " << score;
            gotoxy(5,27);
            cout << "注意 :不要去边缘!";
            gotoxy(5,27);
            cout<<"敌方长度:"<<enemy_body.size()+1<<"    我方长度:"<<body.size()+1; 
             gotoxy(5,26); 
            head.resize(0); 
            head.push_back(headx);
            head.push_back(heady); 
            enemy_head.resize(0); 
            enemy_head.push_back(enemy_headx);
            enemy_head.push_back(enemy_heady);
            cout << "请在输入指示符wasd(不需要按换行键)"; 
        }
    }
}


【以下回答由 GPT 生成】

问题原因:

根据提供的代码片段,我们可以看到在函数print_candy中的gotoxy函数会导致蛇上下横跳的问题。正常情况下,蛇的移动应该是连贯的,但是通过使用gotoxy函数,在每次打印蛇的位置时,都会将光标移动到指定位置,导致屏幕上的蛇出现闪烁和抖动的现象。

解决方案:

  1. 避免使用gotoxy函数来控制光标的位置。可以使用其他方式来打印蛇和食物的位置,保持界面的连续性。例如,可以使用字符数组来表示屏幕上的界面,然后通过循环遍历该数组并打印到屏幕上。

示例代码:

#include <iostream>
#include <vector>
using namespace std;

const int ROWS = 25;
const int COLS = 110;

vector<vector<char>> screen(ROWS, vector<char>(COLS, ' '));

void print_screen() {
    system("cls");  // 清屏
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            cout << screen[i][j];
        }
        cout << endl;
    }
}

void print_candy(int headx, int heady, int enemy_headx, int enemy_heady) {
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            if (i == heady && j == headx) {
                screen[i][j] = '*';  // 打印蛇头
            } else if (i == enemy_heady && j == enemy_headx) {
                screen[i][j] = '#';  // 打印敌人蛇头
            } else {
                bool is_candy = false;
                for (auto x : candy) {
                    if (j == x[0] && i == x[1]) {
                        is_candy = true;
                        break;
                    }
                }
                if (is_candy) {
                    screen[i][j] = '*';  // 打印食物
                } else {
                    screen[i][j] = ' ';  // 打印空格
                }
            }
        }
    }
    print_screen();
}
  1. 在每次打印蛇和食物位置前,先清除之前的位置。可以在print_candy函数中的循环中,在打印之前加入清除的代码,将之前的位置重置为空格。

示例代码:

void print_candy(int headx, int heady, int enemy_headx, int enemy_heady) {
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            screen[i][j] = ' ';  // 清除之前的位置
        }
    }

    for (auto x : candy) {
        screen[x[1]][x[0]] = '*';  // 打印食物
    }
    screen[heady][headx] = '*';  // 打印蛇头
    screen[enemy_heady][enemy_headx] = '#';  // 打印敌人蛇头

    print_screen();
}

请注意,在示例代码中,我使用了一个字符数组screen来表示屏幕上的界面,并在每次打印蛇和食物位置时更新这个数组。最后,通过调用print_screen函数将整个界面打印到屏幕上。

希望以上解决方案对您有所帮助!如果有任何问题,请随时提问。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^