修改以下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");
}
/*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++;
}*/
代码修改如下:
#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++;
}*/
同时控制两条蛇,相当于两个客户端,一个进程下控制不了。
你可以查一下多线程C编程,应该可以
您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!