该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
这个是我自己写的贪吃蛇,但是运行之后每次报错都不同,
出错一:有时候崩溃掉 提示下图里那个指针无权访问数据(但是我的蛇身链表初始化是成功的啊)
出错二:可以正常运行,但是运行时间不固定(可能这次运行坚持了十多秒秒,可以正常吃食物,下次运行直接就提示结束了),然后就自己结束了
附上源码图片
度娘抽风了,我的源码长图可能太大了,老是提示参数错误
只好用链接发了
链接:https://pan.baidu.com/s/1cTMp2XvjG9g-hInsftD6UQ
提取码:K7N4
复制这段内容后打开百度网盘手机App,操作更方便哦
和源码
/**************************************************
* *
* 贪吃蛇 日期:2020.10.13 *
* *
**************************************************/
/******************头文件引用区******************/
#include
#include
#include
#include
#include
/********************宏定义区********************/
/*
* 定义状态Status
*/
#define OK 1
#define ERROR 0
/*
* 宏定义数值
*/
#define MAPWIDTH70
#define MAPHEIGHT30
#define SNAKEINITLENTH5
/*
* 宏定义按键
*/
#define UP 'W'
#define DOWN 'S'
#define LEFT 'A'
#define RIGHT 'D'
/*
* 宏定义字符
*/
#define SNAKE '*'
#define WALL '#'
#define FOOD '@'
/*******************全局变量区*******************/
unsigned int PlayerScores = 0;
unsigned int PlayerMaxScores = 0;
char SnakeMoveDirection;
unsigned int SleepTime = 150;
/*******************类型声明区*******************/
typedef int Status;//判断函数是否成功实现功能 OK ERROR
typedef struct {//坐标结构体
int x;
int y;
} _Position;
typedef enum {//判断食物是否被吃掉
die = 0,
alive = 1
} _HP;
typedef struct _SnakeNode {//蛇
_Position pos;
struct _SnakeNode* next;
} _SnakeNode;
typedef struct {//食物
_Position pos;
_HP hp;
} _Food;
/*******************函数声明区*******************/
void GotoXY(int x, int y);
void Welcome();
void Helper();
void GameOver();
void InitMap(int MapWidth, int MapHeight, char wall_char);
char InitSnake(_SnakeNode** s,int Snake_Init_Lenth, char snake_char, int MapWidth, int MapHeight);
Status JudgeSnakeHead(int Snake_Init_Position_X, int Snake_Init_Direction, int Snake_Init_Position_Y, int Snake_Init_Lenth, int MapWidth, int MapHeight);
void CreateFood(_Food* f, _SnakeNode* s, char food_char, int MapWidth, int MapHeight);
Status JudgeFoodPosition(_Food* f, _SnakeNode* s, int MapWidth, int MapHeight);
void MoveSnake(_SnakeNode**s, _Food*f, char Snake_Move_Direction, char snake_char);
void FreeSnakeNode(_SnakeNode** s);
Status JudgeGameOver(_SnakeNode* s, int MapWidth, int MapHeight);
/********************主函数区********************/
int main(void) {
/*定义数据*/
_SnakeNode* s = NULL;
_Food f;
int ch;
/*初始化*/
InitMap(MAPWIDTH, MAPHEIGHT, WALL);
SnakeMoveDirection = InitSnake(&s, SNAKEINITLENTH, SNAKE, MAPWIDTH, MAPHEIGHT);
CreateFood(&f, s, FOOD, MAPWIDTH, MAPHEIGHT);
/*游戏进程*/
while (JudgeGameOver(s, MAPWIDTH, MAPHEIGHT)) {
if (f.hp == die) {
CreateFood(&f, s, FOOD, MAPWIDTH, MAPHEIGHT);
}
MoveSnake(&s, &f, SnakeMoveDirection, SNAKE);
if (_kbhit()) {//判断是否有按键
ch = _getch();//接收按键
switch (ch) {
case UP: {
if (SnakeMoveDirection != DOWN) {
SnakeMoveDirection = UP;
}
break;
}
case DOWN: {
if (SnakeMoveDirection != UP) {
SnakeMoveDirection = DOWN;
}
break;
}
case LEFT: {
if (SnakeMoveDirection != RIGHT) {
SnakeMoveDirection = LEFT;
}
break;
}
case RIGHT: {
if (SnakeMoveDirection != LEFT) {
SnakeMoveDirection = RIGHT;
}
break;
}
}
}
Sleep(SleepTime);//游戏速度
}
/*游戏结束*/
FreeSnakeNode(&s);
return 0;
}
/*******************函数定义区*******************/
/*
* 跳转光标
*
* 参数1:intx横坐标
* 参数2:inty纵坐标
*/
void GotoXY(int x, int y) {
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD position = { x,y };
SetConsoleCursorPosition(handle, position);
}
/*
* 欢迎界面
*/
void Welcome() {
}
/*
* 帮助界面
*/
void Helper() {
}
/*
* 结束界面
*/
void GameOver() {
}
/*
* 初始化地图
*
* 参数1:intMapWidth地图宽度
* 参数2:intMapHeight地图高度
* 参数3:charwall_char地图符号
*
* 返回值:无
*
*/
void InitMap(int MapWidth, int MapHeight, char wall_char) {
int w, h;
/*打印上边界*/
for (w = 0; w < MapWidth; w++) {
printf("%c", wall_char);
}
/*打印下边界*/
GotoXY(0, MapHeight - 1);
for (w = 0; w < MapWidth; w++) {
printf("%c", wall_char);
}
/*打印左右边界*/
for (h = 1; h < MapHeight - 1; h++) {
GotoXY(0, h);
printf("%c", wall_char);
GotoXY(MapWidth - 1, h);
printf("%c", wall_char);
}
}
/*
* 初始化蛇链表并打印蛇
*
* 参数1:_SnakeNode**s蛇链表头指针的地址
* 参数2:intSnake_Init_Lenth蛇的初始化长度
* 参数3:charsnake_char蛇的符号
* 参数4:intMapWidth地图宽度
* 参数5:intMapHeight地图高度
*
* 返回值:charUP, DOWN, LEFT, RIGHT初始化方向
*/
char InitSnake(_SnakeNode** s, int Snake_Init_Lenth, char snake_char, int MapWidth, int MapHeight){
_SnakeNode* ptrNow = NULL;
/*随机生成蛇头*/
int SnakeInitDirection, SnakeInitPositionX, SnakeInitPositionY;
/*1为上,2为下,3为左,4为右*/
do {
srand((unsigned)time(NULL));
SnakeInitDirection = rand() % 5;
srand((unsigned)time(NULL));
SnakeInitPositionX = rand() % MapWidth;
srand((unsigned)time(NULL));
SnakeInitPositionY = rand() % MapHeight;
} while (!JudgeSnakeHead(SnakeInitPositionX, SnakeInitPositionY, SnakeInitDirection, Snake_Init_Lenth, MapWidth, MapHeight));
_SnakeNode* head = (_SnakeNode*)malloc(sizeof(_SnakeNode));
if (!head) {
exit(0);
}
head->pos.x = SnakeInitPositionX;
head->pos.y = SnakeInitPositionY;
head->next = NULL;
*s = ptrNow = head;
GotoXY(head->pos.x, head->pos.y);
printf("%c", snake_char);
/*循环生成蛇身*/
for (int i = 1; i < Snake_Init_Lenth; i++) {
_SnakeNode* body = (_SnakeNode*)malloc(sizeof(_SnakeNode));
if (!body) {
exit(0);
}
/*根基方向确定蛇身各节点坐标*/
switch (SnakeInitDirection) {
case 1: {
body->pos.x = SnakeInitPositionX;
body->pos.y = SnakeInitPositionY + i;
break;
}
case 2: {
body->pos.x = SnakeInitPositionX;
body->pos.y = SnakeInitPositionY - i;
break;
}
case 3: {
body->pos.x = SnakeInitPositionX + i;
body->pos.y = SnakeInitPositionY;
break;
}
case 4: {
body->pos.x = SnakeInitPositionX - i;
body->pos.y = SnakeInitPositionY;
break;
}
default: {
printf("\n错误:生成蛇身坐标阶段:蛇的初始化方向无效!!!\n");
return ERROR;
}
}
body->next = NULL;
/*利用尾插法将蛇身节点插入蛇链表*/
ptrNow->next = body;
ptrNow = body;
GotoXY(body->pos.x, body->pos.y);
printf("%c", snake_char);
}
switch (SnakeInitDirection) {
case 1: {
return UP;
break;
}
case 2: {
return DOWN;
break;
}
case 3: {
return LEFT;
break;
}
case 4: {
return RIGHT;
break;
}
}
}
/*
* 判断随机生成的蛇头坐标是否合法
*
* 参数1:intSnake_Init_Position_X蛇头x坐标
* 参数2:intSnake_Init_Position_Y蛇头y坐标
* 参数3:intSnake_Init_Direction蛇的初始化方向1为上,2为下,3为左,4为右
* 参数4:intSnake_Init_Lenth蛇的初始化长度
* 参数5:intMapWidth地图宽度
* 参数6:intMapHeight地图高度
*
* 返回值1:OK1合法
* 返回值2;ERROR0不合法
*
*/
Status JudgeSnakeHead(int Snake_Init_Position_X, int Snake_Init_Position_Y, int Snake_Init_Direction, int Snake_Init_Lenth, int MapWidth, int MapHeight) {
/*判断蛇头坐标是否越界*/
if (Snake_Init_Position_X < 1 || Snake_Init_Position_X > MapWidth - 2) {
return ERROR;
}
if (Snake_Init_Position_Y < 1 || Snake_Init_Position_Y > MapHeight - 2) {
return ERROR;
}
/*判断蛇身是否越界*/
switch (Snake_Init_Direction) {
case 1: {
if (Snake_Init_Position_Y + (Snake_Init_Lenth - 1) > MapHeight - 2) {
return ERROR;
}
break;
}
case 2: {
if (Snake_Init_Position_Y - (Snake_Init_Lenth - 1) > 1) {
return ERROR;
}
break;
}
case 3: {
if (Snake_Init_Position_Y + (Snake_Init_Lenth - 1) > MapWidth - 2) {
return ERROR;
}
break;
}
case 4: {
if (Snake_Init_Position_Y - (Snake_Init_Lenth - 1) > MapHeight - 2) {
return ERROR;
}
break;
}
default: {
return ERROR;
}
}
return OK;
}
/*
* 生成食物并打印
*
* 参数1:_Food*f指向食物结构体的指针
* 参数2:_SnakeNode*s蛇链表的头指针
* 参数3:charfood_char食物的符号
* 参数4:intMapWidth地图宽度
* 参数5:intMapHeight地图高度
*
* 返回值:无
*
*/
void CreateFood(_Food* f, _SnakeNode* s,char food_char, int MapWidth, int MapHeight) {
do {
srand((unsigned)time(NULL));
f->pos.x = rand() % MapWidth;
srand((unsigned)time(NULL));
f->pos.y = rand() % MapHeight;
} while (!JudgeFoodPosition(f, s, MapWidth, MapHeight));
f->hp = alive;
GotoXY(f->pos.x, f->pos.y);
printf("%c", food_char);
}
/*
* 判断食物坐标是否合法
*
* 参数1:_Food*f指向食物结构体的指针
* 参数2:_SnakeNode*s蛇链表的头指针
* 参数3:intMapWidth地图宽度
* 参数4:intMapHeight地图高度
*
* 返回值1:OK1合法
* 返回值2:ERROR0不合法
*
*/
Status JudgeFoodPosition(_Food* f, _SnakeNode* s, int MapWidth, int MapHeight) {
/*判断食物坐标是否越界*/
if (f->pos.x < 1 || f->pos.x > MapWidth - 2) {
return ERROR;
}
if (f->pos.y < 1 || f->pos.y > MapHeight - 2) {
return ERROR;
}
/*判断食物是否在蛇身上*/
while (s) {
if (f->pos.x == s->pos.x && f->pos.y == s->pos.y) {
return ERROR;
}
s = s->next;
}
return OK;
}
/*
* 向前移动蛇
*
* 参数1:_SnakeNode**s蛇链表头指针的地址
* 参数2:_Food*f指向食物结构体的指针
* 参数3:charSnake_Move_Direction蛇移动的方向UP, DOWN, LEFT, RIGHT
* 参数4:charsnake_char蛇的符号
*
* 返回值:无
*
*/
void MoveSnake(_SnakeNode** s, _Food* f, char Snake_Move_Direction, char snake_char) {
/*确定下一个点的坐标*/
int NextPositionX, NextPositionY;
switch (Snake_Move_Direction) {
case UP: {
NextPositionX = (*s)->pos.x;
NextPositionY = (*s)->pos.y - 1;
break;
}
case DOWN: {
NextPositionX = (*s)->pos.x;
NextPositionY = (*s)->pos.y + 1;
break;
}
case LEFT: {
NextPositionX = (*s)->pos.x - 1;
NextPositionY = (*s)->pos.y;
break;
}
case RIGHT: {
NextPositionX = (*s)->pos.x + 1;
NextPositionY = (*s)->pos.y;
break;
}
default: {
printf("\n错误:蛇移动阶段:蛇的移动方向无效!!!\n");
exit(0);
}
}
_SnakeNode* NextNode = (_SnakeNode*)malloc(sizeof(_SnakeNode));
if (!NextNode) {
exit(0);
}
NextNode->pos.x = NextPositionX;
NextNode->pos.y = NextPositionY;
/*通过头插法将该节点插入蛇链表*/
NextNode->next = *s;
*s = NextNode;
GotoXY(NextNode->pos.x, NextNode->pos.y);
printf("%c", snake_char);
/*处理尾节点*/
//1.吃到食物:食物hp改为die
//2.没吃到食物:释放尾节点,用空格填充
if (NextNode->pos.x == f->pos.x && NextNode->pos.y == f->pos.y) {
f->hp = die;
PlayerScores++;
}
else {
_SnakeNode* ptrNow = *s;
while (ptrNow->next->next) {
ptrNow = ptrNow->next;
}
GotoXY(ptrNow->next->pos.x, ptrNow->next->pos.y);
printf(" ");
free(ptrNow->next);
ptrNow->next = NULL;
}
}
/*
* 释放蛇链表
*
* 参数:_SnakeNode**s蛇链表头指针的地址
*
* 返回值:无
*
*/
void FreeSnakeNode(_SnakeNode** s) {
_SnakeNode* temp;
while (*s) {
temp = *s;
*s = (*s)->next;
free(temp);
}
}
/*
* 判断游戏是否结束
*
* 参数1:_SnakeNode*s蛇链表头指针
* 参数2:intMapWidth地图宽度
* 参数3:intMapHeight地图高度
*
* 返回值1:OK1未结束
* 返回值2:ERROR0结束
*
*/
Status JudgeGameOver(_SnakeNode* s, int MapWidth, int MapHeight) {
/*判断蛇头是否出界*/
if (s->pos.x < 1 || s->pos.x > MapWidth - 2) {
return ERROR;
}
if (s->pos.x < 1 || s->pos.x > MapHeight - 2) {
return ERROR;
}
/*判断是否撞到自己*/
int SnakeHeadPositionX = s->pos.x;
int SnakeHeadPositionY = s->pos.y;
s = s->next;
while (s) {
if (s->pos.x == SnakeHeadPositionX && s->pos.y == SnakeHeadPositionY) {
return ERROR;
}
s = s->next;
}
return OK;
}
求救各位吧友