生成的可执行文件./step 结果贪吃蛇不移动,如图所示:
大致判断是snakeMove()函数出现问题
请教代码哪里出现问题,自己无法找到。
以下是全部代码:
head.h
#include<stdio.h>
#include<termios.h>
#include<stdlib.h>
#include<signal.h>
#include<time.h>
#include<string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <signal.h>
#include <sys/time.h>
//界面大小
#define WallX 55
#define WallY 20
#define U 1
#define D 2
#define L 3
#define R 4
//所有结构体的定义
struct termios tm_old; //键盘返回值不显示
typedef struct snake {
int x;
int y;
struct snake *next;
}snake;
//定义全局变量
int status;
snake *head ;
snake *food ;//蛇头指针,食物指针
snake *q ;//遍历蛇的时候用到的指针
//所有函数的声明
void jiemian(); //显示刚进入开始界面函数
void interface(); //刚进入界面操作函数
int getch(); //键盘返回值不显示函数
void creatMap(); //游戏界面创建函数
void initSnake(); //初始化蛇身,并打印出来
void creatFood(); //随机出现食物函数
void snakeMove(); //蛇移动
void cantCrossWall(); //不让穿墙
void endGame(); //中止游戏
int biteSelf(); //咬到自己
void runGame();
//判断是否有按键按下
int kbhit(void);
int getch();
void alarm_us(int n);
interface.c
#include"head.h"
int kbhit(void)
{
struct termios oldt, newt;
int ch;
int oldf;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
ch = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf);
if(ch != EOF)
{
ungetc(ch, stdin);
return 1;
}
return 0;
}
int getch()
{
struct termios tm;
tcgetattr(0,&tm_old);
cfmakeraw(&tm);
tcsetattr(0,0,&tm);
int ch = getchar();
tcsetattr(0,0,&tm_old);
return ch;
}
void interface(){
int ch = getch();
if(ch == 48){
endGame();
}
if(ch == 49)
//开始游戏
{
creatMap();
initSnake();
creatFood();
runGame();
}
}
void jiemian(){
printf("---------------------------------------\n");
printf("| SNAKE 小游戏 |\n");
printf("| 按1.开始游戏 |\n");
printf("| 按2.游戏说明 |\n");
printf("| 按3.游戏设置 |\n");
printf("| 按4.查看排行榜 |\n");
printf("| 按0.退出 |\n");
printf("---------------------------------------\n");
}
int main(){
jiemian();
interface();
return 0;
}
creatMap.c
include"head.h"
void creatMap()
{
//打印边框
int i;
for(i=0;i<=WallX;i++)//打印上下边框
{
printf("\033[%d;%dH\033[43m \033[0m\n",10,i+10);
//设置坐标 设置颜色 传递参数
}
for(i=0;i<=WallX;i++)
{
printf("\033[%d;%dH\033[43m \033[0m\n",WallY+10,i+10);
}
for(i=0;i<WallY;i++)//打印左右边框
{
printf("\033[%d;%dH\033[43m \033[0m\n",i+10,10);
}
for(i=0;i<WallY;i++)
{
printf("\033[%d;%dH\033[43m \033[0m\n\n",i+10,WallX+10);
}
}
initsnake.c
#include"head.h"
snake *tail; //蛇尾指针
//初始化蛇的身体
void initSnake()
{
//从蛇尾开始,头插法,以x y设定开始的位置
tail = (snake*)malloc(sizeof(snake));
tail->x=20;
tail->y=15;
tail->next=NULL;
for(int i=1;i<=4;i++)//蛇初始长度为4
{
head=(snake*)malloc(sizeof(snake));
head->next=tail;
head->x=20+i;
head->y=15;
tail=head;
//表面上是把head指针的值赋给了tail
//其实是把tail节点的指针域指向了最后一个head节点
}
//所以这一步才能遍历整个蛇链表
//意思是当头节点的指针域指向的下一块内存不是NULL的时候
//(通俗的讲是头节点的下一个节点不为空)
while(tail!=NULL)
{
printf("\033[%d;%dH\033[47m \033[0m\n",tail->y,tail->x);
//相当与这一步,让在23行已经指向头节点的tail节点作为头节点
//开始遍历蛇链表,直到遍历到蛇尾节tail->next=NULL时
tail = tail->next;
}
}
creatFood.c
#include"head.h"
void creatFood()
{
snake *food1;
//为了防止每次产生的随机数相同,种子设置为time(NULL)
srand((unsigned)time(NULL));
food1 = (snake*)malloc(sizeof(snake));
//food的范围是: 1.多少就对范围的max+min取余 2.min
//在对food进行判断之前,先对其进行初始化
food1->x = rand()%54+11;
while((food1->x%2)!=0)
{
food1->x = rand()%54+11;
}
food1->y = rand()%19+11;
q=head;
while(q)
{
//判断蛇身是否与食物重合
if(q->x==food1->x&&q->y==food1->y)
{
free(food1);
food1=NULL;
creatFood();
return ;
}
q=q->next; //遍历蛇身
}
printf("\033[%d;%dH\033[43m \033[0m\n",food1->y,food1->x);
food = food1;
}
runGame.c
#include"head.h"
void alarm_us(int n)
{
struct itimerval value;
//定时器启动的初始值
value.it_value.tv_sec = 0;
value.it_value.tv_usec = n;
//定时器启动后的间隔时间值
value.it_interval.tv_sec = 0;
value.it_interval.tv_usec = n;
setitimer(ITIMER_REAL,&value,NULL);
}
void runGame()
{
while(1)
{
if(kbhit())
{
//snakeMove();
int ch = getch();
if(ch==38&&status!=D)
status=U;
else if(ch==40&&status!=U)
status=D;
else if(ch==39&&status!=R)
status=L;
else if(ch==37&&status!=L)
status=R;
sleep(10);
snakeMove();
}
}
}
snakeMove.c
#include"head.h"
void endGame()
{
exit(0);
}
void cantCrossWall()
{
if(head->x==10||head->x==WallX+10||head->next==0||head->y==WallY+10)
{
//endGamestatus=1;
endGame();
}
}
int biteSelf()
{
snake *self;
self=head->next;
while(self!=NULL)
{
if(self->x==head->x||self->y==head->y)
return 1;
self=self->next;
}
return 0;
}
void snakeMove()
{
cantCrossWall();
// initSnake();
snake *nexthead = (snake*)malloc(sizeof(snake));
switch(status)
{
case U: nexthead->x=head->x; nexthead->y=head->y-1;
break;
case D: nexthead->x=head->x ;nexthead->y=head->y+1;
break;
case L: nexthead->x=head->x-1; nexthead->y=head->y;
break;
case R: nexthead->x=head->x+1; nexthead->y=head->y;
break;
}
if(nexthead->x==food->x&&nexthead->y==food->y)
{
//吃到一口
nexthead->next=head;
//表面是把nexthead指针值赋给head,其实是把head的指针域的地址指向原来的nexthead
head = nexthead;
//score=score+add;
initSnake();
creatFood();
}
else //没有吃到食物的时候
{
if(biteSelf()==1)
{
endGame();
}
else{
nexthead->next=head;
head=nexthead;
q=head;
//输出新的蛇头
printf("\033[%d;%dH\33[47m \033[0m",q->y,q->x);
//消除蛇的尾巴
while(q->next->next!=NULL)
{
q=q->next;
}
printf("\033[%d;%dH\33[40m \033[0m",q->next->y,q->next->x);
free(q->next);
q->next=NULL;
}
}
}