修改以下c语言项目代码

修改以下c语言项目代码,要求增加一条蛇,用W、S、D、A控制方向,要求能同时操控两条蛇,且两条蛇相撞不影响。

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<malloc.h>
#include<time.h>
#include<stdbool.h>

#define X 20
#define Y 20

enum Dir {enum_east,enum_south,enum_west,enum_north};  //枚举类型 方向 

struct Snake                                            //蛇结构体 
{
    int iX,iY;
    enum Dir emDir;            
};

struct Node                                                //链表的节点 
{
    struct Snake stSnake;
    int iCount;
    struct Node *pPre;
    struct Node *pNext;    
};

struct Node *g_pHead=NULL;
struct Node *g_pEnd=NULL;

char g_Back[X][Y];
void Head(void);//头 英文 
void Frame(void);//框架 英文 
void GotoXY(unsigned short hang,unsigned short lie);//去某行某列 
void CreatSnake(int iCount);//创造蛇 
void Free();
void DrawSnake(void); 
void Move(void);
void Drop(void);
void KeyState(void);//箭头控制转向 
void Food(void);
void Appand(void);//附加 英文 
bool Eat(void);
bool IsDie(void); 
void HideCursor(); // 用于隐藏光标

int main(void)
{
    srand((unsigned int)time(NULL)); 
    Head();    //提示文字
    Frame();   //产生边框      
    //GotoXY(50,50);
    //g_pHead;
    CreatSnake(3);                
    DrawSnake();
    Food();
//    HideCursor();   //隐藏光标 
    while(1)
    {
        KeyState();
        if(true==Eat())
        {
            Food();
        }
        if(true==IsDie())
        {
            system("pause>0");
        }
        Drop();    
        Move();
        DrawSnake();
        
        
        Sleep(300);
    }

    
    Free();
    return 0;
} 

void HideCursor() // 用于隐藏光标

{

CONSOLE_CURSOR_INFO cursor_info = {1, 0};  // 第二个值为0表示隐藏光标

SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);

}

bool IsDie(void)                                //撞边结束 
{
    if(1==g_Back[g_pHead->stSnake.iX][g_pHead->stSnake.iY])    //1表示墙 0表示空气 2表示食物 
    {
    //    GotoXY(69,69);
        printf("Game over!");
        return true;
    }
    return false;
}

void GotoXY(unsigned short hang,unsigned short lie)            //设置光标位置 
{
    COORD cd = {lie,hang};
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),cd);
}

void Appand(void)                                //吃食后增加长度 
{
    //创建节点 
    struct Node *pTemp=(struct Node*)malloc(sizeof(struct Node));
    if(NULL==pTemp)
        return;
    //节点成员赋值 
    pTemp->iCount++;
        pTemp->pPre=NULL;
    pTemp->pNext=NULL;
    pTemp->stSnake.emDir=g_pEnd->stSnake.emDir;
    switch(g_pEnd->stSnake.emDir)
    {
        case enum_east:
            pTemp->stSnake.iX=g_pEnd->stSnake.iX;
            pTemp->stSnake.iY=g_pEnd->stSnake.iY+1;
            break;
        case enum_south:
            pTemp->stSnake.iX=g_pEnd->stSnake.iX+1;
            pTemp->stSnake.iY=g_pEnd->stSnake.iY;
            break;
        case enum_west:
            pTemp->stSnake.iX=g_pEnd->stSnake.iX;
            pTemp->stSnake.iY=g_pEnd->stSnake.iY-1;
            break;
        case enum_north:
            pTemp->stSnake.iX=g_pEnd->stSnake.iX-1;
            pTemp->stSnake.iY=g_pEnd->stSnake.iY;
            break;
    }
    //链接到链表的尾巴上 
    pTemp->pPre=g_pEnd;
    g_pEnd->pNext=pTemp;
    g_pEnd=pTemp;
    
}

bool Eat(void)                                    //判断是否吃食 
{
    if(2==g_Back[g_pHead->stSnake.iX][g_pHead->stSnake.iY])
    {
        g_Back[g_pHead->stSnake.iX][g_pHead->stSnake.iY]=0;
        Appand();
        return true;    
    }    
    else if(3==g_Back[g_pHead->stSnake.iX][g_pHead->stSnake.iY])
    {
        g_Back[g_pHead->stSnake.iX][g_pHead->stSnake.iY]=0;
        Appand();
        Appand();
        return true;    
    }
    return false;
} 

void Food(void)                                    //食物 
{
    while(1)
    {
        //产生一组坐标 
        int x=rand()%(X-2)+1;
        int y=rand()%(Y-2)+1;
        //判断是否在蛇身上
        struct Node *pT=g_pHead;
        while(pT!=NULL)
        {
            if(x==pT->stSnake.iX&&y==pT->stSnake.iY)
                break;
            pT=pT->pNext;
        }
        //在的话就下一次 
        if(NULL!=pT)
            continue;
        //不在,那就是合理的位置
        else
        {
            int foodshape=rand()%3;
            if(foodshape==0)
            {
                foodshape=3;
            }
            else if(foodshape==1)
            {
                foodshape=2;
            }
            g_Back[x][y]=foodshape;
            GotoXY(9+x,y*2+30);    
            if(foodshape==2)
            {
                printf("□");
            }
            else if(foodshape==3)
            {
                printf("o");    
            }
            break;
        } 
    }
}


void KeyState(void)                                //箭头控制转向 
{
    if(GetAsyncKeyState(VK_UP))
    {
        g_pHead->stSnake.emDir=enum_north;
    }
    else if(GetAsyncKeyState(VK_DOWN))
    {
        g_pHead->stSnake.emDir=enum_south;
    }
    else if(GetAsyncKeyState(VK_LEFT))
    {
        g_pHead->stSnake.emDir=enum_west;
    }
else if(GetAsyncKeyState(VK_RIGHT))
    {
        g_pHead->stSnake.emDir=enum_east;
    }
}

void Move(void)                                    //移动蛇 
{
    if(NULL==g_pHead)
        return;
    struct Node *pT=g_pEnd;
    while(pT!=g_pHead)            
    {
        pT->stSnake=pT->pPre->stSnake;
        pT=pT->pPre;
    }
    switch (g_pHead->stSnake.emDir)
    {
        case enum_east:
            g_pHead->stSnake.iY++;
            break;
        case enum_south:
            g_pHead->stSnake.iX++;
            break;
        case enum_west:
            g_pHead->stSnake.iY--;
            break;
        case enum_north:
            g_pHead->stSnake.iX--;
            break;
    }
}

void Drop(void)                                    //消除尾巴 
{
    GotoXY(9+g_pEnd->stSnake.iX,g_pEnd->stSnake.iY*2+30);
    printf(" ");
}

void DrawSnake(void)                            //画蛇 
{
    if(NULL==g_pHead)
        return;
    struct Node *pT=g_pHead;
    while(pT!=NULL)
    {
        GotoXY(9+pT->stSnake.iX,pT->stSnake.iY*2+30);
        printf("O");
        pT=pT->pNext;
    }
} 

void CreatSnake(int iCount)                    //链表、节点  创造蛇的大小 
{
    if(iCount<=0)
        return;
        int i;
    for(i=0;i<iCount;i++)
    {
        //创建节点 
        struct Node *pT=(struct Node*)malloc(sizeof(struct Node));
        if(NULL==pT)
            return ;
        //节点成员赋值 
        pT->iCount=0;
        pT->pNext=NULL;
        pT->pPre=NULL;
        pT->stSnake.emDir=enum_west;
        pT->stSnake.iX=0;
        pT->stSnake.iY=0;
        // 将节点连在链表上
        if(NULL==g_pHead)
        {
            g_pHead=pT;
            g_pEnd=pT;
            
            g_pHead->iCount=1;

            g_pHead->stSnake.iX=rand()%(X-2)+1;         //随机数取余数,确保iX小于(X-2)+1 
            g_pHead->stSnake.iY=rand()%(Y-iCount-1)+3;  //随机数取余数,确保iY小于(Y-iCount)+1
        } 
        else
        {
            g_pEnd->pNext=pT;
            pT->pPre=g_pEnd;
            g_pEnd=pT;
            
            g_pHead->iCount+=1;
            
            g_pEnd->stSnake.iX=g_pEnd->pPre->stSnake.iX;
            
            g_pEnd->stSnake.iY=g_pEnd->pPre->stSnake.iY+1;
        }
    }
}

void Free(void)
{
    if(NULL==g_pHead)
        return;
    struct Node *pT=g_pHead;
    while(NULL!=pT)
    {
        //记录被删除的节点
        struct Node *pp=pT; 
        //节点往下走 
        pT=pT->pNext;
        //释放记录 
        free(pp);
    }
    g_pHead=NULL;
    g_pEnd=NULL;
}
void Frame(void)                                            //边框赋值 
{
    int i;
    for(i=0;i<X;i++)
    {
        int j;
        for(j=0;j<Y;j++)
        {
            if(i==0||j==0||i==X-1||j==Y-1)
                g_Back[i][j]=1;
            else g_Back[i][j]=0;
        }
    }
    for(i=0;i<X;i++)
    {
        GotoXY(i+9, 0);
        printf("\t\t\t\t   ");
        int j;
        for(j=0;j<Y;j++)
        {

            if(g_Back[i][j]==1)
                printf("■ ");
             
            else 
                printf("  ");
        }
        putchar('\n');
    }    
}

void Head(void)                                                //提示文字 
{
    printf("\t\t\t\t\t>>>>>>>>>>  贪吃蛇  <<<<<<<<<<\n");
    printf("\t\t\t\t\t>>>>>  Enter 启动/暂停   <<<<<\n");
    printf("\t\t\t\t\t>>>>> ↑←↓→ 控制方向  <<<<<\n");
    printf("\t\t\t\t\t>>>>>   1 查看历史记录   <<<<<\n");
    printf("\t\t\t\t\t>>>>>   Q 重新开始       <<<<<\n");
    printf("\t\t\t\t\t>>>>> tab 切换难度: 简单 <<<<<\n");
    printf("\t\t\t\t\t>>>>>    当前长度: 0     <<<<<\n");
    printf("\t\t\t\t\t>>>>>   ESC  退出游戏    <<<<<\n");
    printf("\t\t\t\t\t>>>>>>>>>>>>>>><<<<<<<<<<<<<<<\n");
}

代码修改如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <malloc.h>
#include <time.h>
#include <stdbool.h>
#include <conio.h>
#define X 20
#define Y 20

enum Dir { enum_east, enum_south, enum_west, enum_north };  //枚举类型 方向 

struct Snake                                            //蛇结构体 
{
    int iX, iY;
    enum Dir emDir;
};

struct Node                                                //链表的节点 
{
    struct Snake stSnake;
    int iCount;
    struct Node* pPre;
    struct Node* pNext;
};

int g_Back[X][Y];

struct SNakeClass
{
    struct Node* g_pHead;
    struct Node* g_pEnd;
    
    
    void CreatSnake(int iCount);//创造蛇 
    void Free();
    void DrawSnake(void);
    void Move(void);
    void Drop(void);
     
    void Food(void);
    void Appand(void);//附加 英文 
    bool Eat(void);
    bool IsDie(void);

    SNakeClass() 
    {
        g_pHead = NULL;
        g_pEnd = NULL;
    }

};






void Head(void);//头 英文 
void Frame(void);//框架 英文 
void GotoXY(unsigned short hang, unsigned short lie);//去某行某列 
void KeyState(struct SNakeClass sn1,struct SNakeClass sn2);//箭头控制转向
void HideCursor(); // 用于隐藏光标

int main(void)
{
    srand((unsigned int)time(NULL));
    Head();    //提示文字
    Frame();   //产生边框      
    //GotoXY(50,50);
    //g_pHead;
    SNakeClass sn1;
    SNakeClass sn2;
    sn1.CreatSnake(3);
    sn2.CreatSnake(4);
    sn1.DrawSnake();
    sn2.DrawSnake();
    sn1.Food();
    sn2.Food();
    //    HideCursor();   //隐藏光标 
    while (1)
    {
        KeyState(sn1,sn2);
        if (true == sn1.Eat())
        {
            sn1.Food();
        }
        if (true == sn2.Eat())
        {
            sn2.Food();
        }
        if (true == sn1.IsDie() || true == sn2.IsDie() )
        {
            system("pause>0");
        }
        sn1.Drop();
        sn2.Drop();
        sn1.Move();
        sn2.Move();
        sn1.DrawSnake();
        sn2.DrawSnake();


        Sleep(300);
    }


    sn1.Free();
    sn2.Free();
    return 0;
}

void HideCursor() // 用于隐藏光标

{

    CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };  // 第二个值为0表示隐藏光标

    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);

}

bool SNakeClass::IsDie(void)                                //撞边结束 
{
    if (1 == g_Back[g_pHead->stSnake.iX][g_pHead->stSnake.iY])    //1表示墙 0表示空气 2表示食物 
    {
        //    GotoXY(69,69);
        printf("Game over!");
        return true;
    }
    return false;
}

void GotoXY(unsigned short hang, unsigned short lie)            //设置光标位置 
{
    COORD cd = { lie,hang };
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cd);
}

void SNakeClass::Appand(void)                                //吃食后增加长度 
{
    //创建节点 
    struct Node* pTemp = (struct Node*)malloc(sizeof(struct Node));
    if (NULL == pTemp)
        return;
    //节点成员赋值 
    pTemp->iCount++;
    pTemp->pPre = NULL;
    pTemp->pNext = NULL;
    pTemp->stSnake.emDir = g_pEnd->stSnake.emDir;
    switch (g_pEnd->stSnake.emDir)
    {
    case enum_east:
        pTemp->stSnake.iX = g_pEnd->stSnake.iX;
        pTemp->stSnake.iY = g_pEnd->stSnake.iY + 1;
        break;
    case enum_south:
        pTemp->stSnake.iX = g_pEnd->stSnake.iX + 1;
        pTemp->stSnake.iY = g_pEnd->stSnake.iY;
        break;
    case enum_west:
        pTemp->stSnake.iX = g_pEnd->stSnake.iX;
        pTemp->stSnake.iY = g_pEnd->stSnake.iY - 1;
        break;
    case enum_north:
        pTemp->stSnake.iX = g_pEnd->stSnake.iX - 1;
        pTemp->stSnake.iY = g_pEnd->stSnake.iY;
        break;
    }
    //链接到链表的尾巴上 
    pTemp->pPre = g_pEnd;
    g_pEnd->pNext = pTemp;
    g_pEnd = pTemp;

}

bool SNakeClass::Eat(void)                                    //判断是否吃食 
{
    if (2 == g_Back[g_pHead->stSnake.iX][g_pHead->stSnake.iY])
    {
        g_Back[g_pHead->stSnake.iX][g_pHead->stSnake.iY] = 0;
        Appand();
        return true;
    }
    else if (3 == g_Back[g_pHead->stSnake.iX][g_pHead->stSnake.iY])
    {
        g_Back[g_pHead->stSnake.iX][g_pHead->stSnake.iY] = 0;
        Appand();
        Appand();
        return true;
    }
    return false;
}

void SNakeClass::Food(void)                                    //食物 
{
    while (1)
    {
        //产生一组坐标 
        int x = rand() % (X - 2) + 1;
        int y = rand() % (Y - 2) + 1;
        //判断是否在蛇身上
        struct Node* pT = g_pHead;
        while (pT != NULL)
        {
            if (x == pT->stSnake.iX && y == pT->stSnake.iY)
                break;
            pT = pT->pNext;
        }
        //在的话就下一次 
        if (NULL != pT)
            continue;
        //不在,那就是合理的位置
        else
        {
            int foodshape = rand() % 3;
            if (foodshape == 0)
            {
                foodshape = 3;
            }
            else if (foodshape == 1)
            {
                foodshape = 2;
            }
            g_Back[x][y] = foodshape;
            GotoXY(9 + x, y * 2 + 30);
            if (foodshape == 2)
            {
                printf("□");
            }
            else if (foodshape == 3)
            {
                printf("o");
            }
            break;
        }
    }
}


void KeyState(struct SNakeClass sn1, struct SNakeClass sn2)                                //箭头控制转向 
{
    if (GetAsyncKeyState('w') || GetAsyncKeyState('W'))//(GetAsyncKeyState(VK_UP))
    {
        sn1.g_pHead->stSnake.emDir = enum_north;
        sn2.g_pHead->stSnake.emDir = enum_north;
    }
    else if (GetAsyncKeyState('s') || GetAsyncKeyState('S'))//(GetAsyncKeyState(VK_DOWN))
    {
        sn1.g_pHead->stSnake.emDir = enum_south;
        sn2.g_pHead->stSnake.emDir = enum_south;
    }
    else if (GetAsyncKeyState('a') || GetAsyncKeyState('A'))//(GetAsyncKeyState(VK_LEFT))
    {
        sn1.g_pHead->stSnake.emDir = enum_west;
        sn2.g_pHead->stSnake.emDir = enum_west;
    }
    else if (GetAsyncKeyState('d') || GetAsyncKeyState('D'))// (GetAsyncKeyState(VK_RIGHT))
    {
        sn1.g_pHead->stSnake.emDir = enum_east;
        sn2.g_pHead->stSnake.emDir = enum_east;
    }
}

void SNakeClass::Move(void)                                    //移动蛇 
{
    if (NULL == g_pHead)
        return;
    struct Node* pT = g_pEnd;
    while (pT != g_pHead)
    {
        pT->stSnake = pT->pPre->stSnake;
        pT = pT->pPre;
    }
    switch (g_pHead->stSnake.emDir)
    {
    case enum_east:
        g_pHead->stSnake.iY++;
        break;
    case enum_south:
        g_pHead->stSnake.iX++;
        break;
    case enum_west:
        g_pHead->stSnake.iY--;
        break;
    case enum_north:
        g_pHead->stSnake.iX--;
        break;
    }
}

void SNakeClass::Drop(void)                                    //消除尾巴 
{
    GotoXY(9 + g_pEnd->stSnake.iX, g_pEnd->stSnake.iY * 2 + 30);
    printf(" ");
}

void SNakeClass::DrawSnake(void)                            //画蛇 
{
    if (NULL == g_pHead)
        return;
    struct Node* pT = g_pHead;
    while (pT != NULL)
    {
        GotoXY(9 + pT->stSnake.iX, pT->stSnake.iY * 2 + 30);
        printf("O");
        pT = pT->pNext;
    }
}

void SNakeClass::CreatSnake(int iCount)                    //链表、节点  创造蛇的大小 
{
    if (iCount <= 0)
        return;
    int i;
    for (i = 0; i < iCount; i++)
    {
        //创建节点 
        struct Node* pT = (struct Node*)malloc(sizeof(struct Node));
        if (NULL == pT)
            return;
        //节点成员赋值 
        pT->iCount = 0;
        pT->pNext = NULL;
        pT->pPre = NULL;
        pT->stSnake.emDir = enum_west;
        pT->stSnake.iX = 0;
        pT->stSnake.iY = 0;
        // 将节点连在链表上
        if (NULL == g_pHead)
        {
            g_pHead = pT;
            g_pEnd = pT;

            g_pHead->iCount = 1;

            g_pHead->stSnake.iX = rand() % (X - 2) + 1;         //随机数取余数,确保iX小于(X-2)+1 
            g_pHead->stSnake.iY = rand() % (Y - iCount - 1) + 3;  //随机数取余数,确保iY小于(Y-iCount)+1
        }
        else
        {
            g_pEnd->pNext = pT;
            pT->pPre = g_pEnd;
            g_pEnd = pT;

            g_pHead->iCount += 1;

            g_pEnd->stSnake.iX = g_pEnd->pPre->stSnake.iX;

            g_pEnd->stSnake.iY = g_pEnd->pPre->stSnake.iY + 1;
        }
    }
}

void SNakeClass::Free(void)
{
    if (NULL == g_pHead)
        return;
    struct Node* pT = g_pHead;
    while (NULL != pT)
    {
        //记录被删除的节点
        struct Node* pp = pT;
        //节点往下走 
        pT = pT->pNext;
        //释放记录 
        free(pp);
    }
    g_pHead = NULL;
    g_pEnd = NULL;
}

void Frame(void)                                            //边框赋值 
{
    int i;
    for (i = 0; i < X; i++)
    {
        int j;
        for (j = 0; j < Y; j++)
        {
            if (i == 0 || j == 0 || i == X - 1 || j == Y - 1)
            {
                g_Back[i][j] = 1;
            }
            else
            {
                g_Back[i][j] = 0;
            }
        }
    }
    for (i = 0; i < X; i++)
    {
        GotoXY(i + 9, 0);
        printf("\t\t\t\t   ");
        int j;
        for (j = 0; j < Y; j++)
        {

            if (g_Back[i][j] == 1 )
                printf("■ ");

            else
                printf("  ");
        }
        putchar('\n');
    }
}

void Head(void)                                                //提示文字 
{
    printf("\t\t\t\t\t>>>>>>>>>>  贪吃蛇  <<<<<<<<<<\n");
    printf("\t\t\t\t\t>>>>>  Enter 启动/暂停   <<<<<\n");
    printf("\t\t\t\t\t>>>>> ↑←↓→ 控制方向  <<<<<\n");
    printf("\t\t\t\t\t>>>>>   1 查看历史记录   <<<<<\n");
    printf("\t\t\t\t\t>>>>>   Q 重新开始       <<<<<\n");
    printf("\t\t\t\t\t>>>>> tab 切换难度: 简单 <<<<<\n");
    printf("\t\t\t\t\t>>>>>    当前长度: 0     <<<<<\n");
    printf("\t\t\t\t\t>>>>>   ESC  退出游戏    <<<<<\n");
    printf("\t\t\t\t\t>>>>>>>>>>>>>>><<<<<<<<<<<<<<<\n");
}

/*void Change(void)   //目前无用
{
    static int g = 1;

    switch (g % 3)
    {
    case 1:  //中等
        GotoXY(5, 60);
        g_speed = 350;
        printf("中等");
        break;
    case 2:  //困难
        GotoXY(5, 60);
        g_speed = 200;
        printf("困难");
        break;
    case 0:  //简单
        GotoXY(5, 60);
        g_speed = 500;
        printf("简单");
    }
    g++;
}*/


同时控制两条蛇,相当于两个客户端,一个进程下实现不了。

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/7409616
  • 这篇博客也不错, 你可以看下C语言——结构体 以下程序有若干语法错误,不能正确输出s的成员n、s的成员b中的成员d、s的成员a的值。请找出并改正之。
  • 以下回答来自chatgpt:

    根据问题描述和参考资料,结合现有知识,可以给出以下解决方案来实现在C语言项目中添加两条蛇并控制其移动方向的功能:

    1. 首先,需要定义两条蛇的结构体,包括蛇的身体坐标和移动方向等信息。可以使用链表来表示蛇的身体部分,每个节点存储一个身体坐标,并通过指针链接节点。同时,为每条蛇设定一个标识,用于区分不同的蛇。
    typedef struct Node {
        int x; // 蛇身体节点的x坐标
        int y; // 蛇身体节点的y坐标
        struct Node* next; // 指向下一个节点的指针
    } Node;
    
    typedef struct Snake {
        int id; // 蛇的标识,用于区分不同的蛇
        int direction; // 蛇的移动方向
        Node* head; // 蛇头节点的指针
    } Snake;
    
    Snake snake1; // 第一条蛇
    Snake snake2; // 第二条蛇
    
    1. 初始化两条蛇,包括初始化蛇头节点、设置初始移动方向等。
    void initSnake(Snake* snake, int id, int x, int y, int direction) {
        snake->id = id;
        snake->direction = direction;
    
        Node* head = (Node*)malloc(sizeof(Node));
        head->x = x;
        head->y = y;
        head->next = NULL;
    
        snake->head = head;
    }
    
    1. 编写移动蛇的函数,根据蛇的移动方向更新蛇身体节点的坐标。在更新过程中,需要考虑蛇头节点的移动、蛇身体节点的相对移动等,以保持蛇的长度不变。
    void moveSnake(Snake* snake) {
        // 移动蛇头节点
        switch(snake->direction) {
            case 'W':
                snake->head->y -= 1;
                break;
            case 'S':
                snake->head->y += 1;
                break;
            case 'A':
                snake->head->x -= 1;
                break;
            case 'D':
                snake->head->x += 1;
                break;
            default:
                break;
        }
    
        // 移动蛇身体节点
        Node* node = snake->head;
        while(node->next != NULL) {
            node = node->next;
            node->x = node->x - (snake->head->x - preX);
            node->y = node->y - (snake->head->y - preY);
            preX = snake->head->x;
            preY = snake->head->y;
        }
    }
    
    1. 编写碰撞检测函数,检测两条蛇的头节点是否相撞。如果相撞,需要保持两条蛇的移动方向不变。
    void checkCollision(Snake* snake1, Snake* snake2) {
        if (snake1->head->x == snake2->head->x && snake1->head->y == snake2->head->y) {
            // 两条蛇相撞,保持移动方向不变
            snake1->direction = snake1->preDirection;
            snake2->direction = snake2->preDirection;
        }
    }
    
    1. 在主循环中,监听键盘输入,根据键盘输入来改变蛇的移动方向,并调用移动函数和碰撞检测函数来更新蛇的状态。
    while (1) {
        char input = getchar();
    
        if (input == 'W' || input == 'S' || input == 'A' || input == 'D') {
            snake1.direction = input;
        } else if (input == 'I' || input == 'K' || input == 'J' || input == 'L') {
            snake2.direction = input;
        }
    
        moveSnake(&snake1);
        moveSnake(&snake2);
    
        checkCollision(&snake1, &snake2);
    }
    

    这样,做了上述修改之后,便可以实现同时操控两条蛇,并且保持独立移动、不互相影响的功能了。需要注意的是,以上只是一个大致的实现方案,具体细节和业务逻辑可能需要根据实际需求进行调整和完善。


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