20 鱼币
这是之前看的一位鱼油发的代码,程序的内容是一个贪吃蛇。我稍微改了一下发现运行一段时间后会崩溃掉。原因可能是创建食物的时候有一个递归程序,我将这个递归换成迭代之后程序就不会有问题,但是我想知道这个递归是怎么出问题的。请大神们帮我看看,谢谢大家!
#include<stdio.h>
#include<windows.h>
#include<time.h>
#define MAP_LENGTH 78 //定义地图的长度
#define MAP_HIGHT 24 //定义地图的宽度
#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3
void Pos(int x, int y);
void CreatMap();
void InitSnake();
void CreatFood();
void BiteSelf();
void CantCrossWall();
void RunSnake();
void EndGame();
void ControlSnake();
typedef struct snake
{
int x;
int y;
struct snake *next;
}snake;
snake *head; //定义一个蛇头
snake *food; //用于记录食物
snake *p; //用于遍历蛇的指针
int endstatus = 0; //结束游戏的原因
int run_status = DOWN; //用于记录运动方向
int main()
{
CreatMap();
InitSnake();
CreatFood();
while (1)
{
ControlSnake();
BiteSelf();
CantCrossWall();
EndGame();
if (endstatus)
break;
}
return 0;
}
void Pos(int x, int y) //定位光标位置
{
COORD pos;
pos.X = x;
pos.Y = y;
HANDLE
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOutput, pos);
}
void CreatMap() //创建地图
{
int i;
for (i = 0; i < MAP_LENGTH; i += 2) //创建地图顶横行
{
Pos(i, 0);
printf("口");
}
for (i = 0; i < MAP_LENGTH; i += 2) //创建地图底横行
{
Pos(i, MAP_HIGHT);
printf("口");
}
for (i = 0; i < MAP_HIGHT; i++) //创建地图左竖行
{
Pos(0, i);
printf("口");
}
for (i = 0; i < MAP_HIGHT; i++) //创建地图右竖行
{
Pos(MAP_LENGTH, i);
printf("口");
}
}
void InitSnake() //初始化蛇
{
int i;
snake *tail = (snake*)malloc(sizeof(snake));//定义蛇的初始位置
tail->next = NULL;
tail->x = 24;
tail->y = 5;
for (i = 0; i < 5; i++) //用头插法插入蛇的身体
{
head = (snake*)malloc(sizeof(snake));
head->next = tail;
head->x = 24 + 2 * i;
head->y = 5;
Pos(head->x, head->y);
printf("口");
tail = head;
}
}
void CreatFood() //创建食物
{
srand(GetTickCount()); //随机创建一个食物
static snake *food_1 = NULL;
food_1 = (snake*)malloc(sizeof(snake));
do
{
food_1->x = rand() %( MAP_LENGTH-1)+1;
} while ((food_1->x) % 2 != 0); //与蛇头对齐
food_1->y = rand() % (MAP_HIGHT-1)+1;
for (p = head; p; p = p->next) //判断创建的食物是否在蛇身上
{
if (food_1->x == p->x && food_1->y == p->y)
{
free(food_1);
CreatFood();
}
}
food = food_1;
Pos(food_1->x, food_1->y); //打印出食物
printf("口");
}
void BiteSelf() //判断是否咬到自己
{
for (p = head->next; p; p = p->next)
{
if (p->x == head->x && p->y == head->y)
endstatus = 1;
}
}
void CantCrossWall() //判断会不会撞到墙
{
if (head->x == 0 || head->x == MAP_LENGTH)
endstatus = 2;
if (head->y == 0 || head->y == MAP_HIGHT)
endstatus = 2;
}
void RunSnake() //控制蛇的运动
{
snake *nexthead = (snake*)malloc(sizeof(snake));
switch (run_status)
{
case UP: //控制蛇向上前进
nexthead->y = head->y - 1;
nexthead->x = head->x;
if (food->x == nexthead->x && food->y == nexthead->y) //如果碰到了食物
{
nexthead->next = head;
head = nexthead;
Pos(head->x, head->y);
printf("口");
free(food);
CreatFood();
}
else //如果没碰到食物
{
nexthead->next = head;
head = nexthead;
for (p = head; p->next->next != NULL; p = p->next)
{
Pos(p->x, p->y);
printf("口");
}
Pos(p->next->x, p->next->y);
printf(" ");
free(p->next);
p->next = NULL;
}
break;
case DOWN: //控制蛇向下前进
nexthead->y = head->y + 1;
nexthead->x = head->x;
if (food->x == nexthead->x && food->y == nexthead->y) //如果碰到了食物
{
nexthead->next = head;
head = nexthead;
Pos(head->x, head->y);
printf("口");
free(food);
CreatFood();
}
else //如果没碰到食物
{
nexthead->next = head;
head = nexthead;
for (p = head; p->next->next != NULL; p = p->next)
{
Pos(p->x, p->y);
printf("口");
}
Pos(p->next->x, p->next->y);
printf(" ");
free(p->next);
p->next = NULL;
}
break;
case LEFT: //控制蛇向左前进
nexthead->x = head->x - 2;
nexthead->y = head->y;
if (food->x == nexthead->x && food->y == nexthead->y) //如果碰到了食物
{
nexthead->next = head;
head = nexthead;
Pos(head->x, head->y);
printf("口");
free(food);
CreatFood();
}
else //如果没碰到食物
{
nexthead->next = head;
head = nexthead;
for (p = head; p->next->next != NULL; p = p->next)
{
Pos(p->x, p->y);
printf("口");
}
Pos(p->next->x, p->next->y);
printf(" ");
free(p->next);
p->next = NULL;
}
break;
case RIGHT: //控制蛇向右前进
nexthead->x = head->x + 2;
nexthead->y = head->y;
if (food->x == nexthead->x && food->y == nexthead->y) //如果碰到了食物
{
nexthead->next = head;
head = nexthead;
Pos(head->x, head->y);
printf("口");
free(food);
CreatFood();
}
else //如果没碰到食物
{
nexthead->next = head;
head = nexthead;
for (p = head; p->next->next != NULL; p = p->next)
{
Pos(p->x, p->y);
printf("口");
}
Pos(p->next->x, p->next->y);
printf(" ");
free(p->next);
p->next = NULL;
}
break;
default:
break;
}
}
void ControlSnake() //按键判断蛇前进方向
{
if (GetAsyncKeyState(VK_UP) && run_status != DOWN)
run_status = UP;
else if (GetAsyncKeyState(VK_DOWN) && run_status != UP)
run_status = DOWN;
else if (GetAsyncKeyState(VK_LEFT) && run_status != RIGHT)
run_status = LEFT;
else if (GetAsyncKeyState(VK_RIGHT) && run_status != LEFT)
run_status = RIGHT;
Sleep(300);
RunSnake();
}
void EndGame() //游戏结束判断
{
switch (endstatus)
{
case 1:
printf("你咬到自己啦!游戏结束");
break;
case 2:
printf("你撞到墙啦!游戏结束");
break;
default:
break;
}
}
我来回答