问题描述
- 多线程双线链表实现贪食蛇蛇身不长,怎么破
-
#include
#include
#include
#include
typedef struct node{
int* body;
struct node* p_prev;
struct node* p_next;
}node;
node head;
int move();
char dir;
int* SaveTailBody; //保存尾节点地址void show(int map[20][20],int x,int y)
{
for(y=0;y
{
for(x=0;x
{
if(x==0||x==19||y==0||y==19)
{
printf("*");
}
else if(map[x][y]==1)
{
printf("@");
}
else if(map[x][y]==2)
{
printf("O");
}
else
{
printf(" ");
}
}
printf("n");
}
}
void add_body(int map[20][20],int* p_x,int* p_y,int* p_ax,int* p_ay,node* p_head,node* p_tail,node* tailSave)
{
node* p_node=(node*)malloc(sizeof(node));
if(!p_node) perror("p_node"),exit(-1);
p_node->p_prev=NULL;
p_node->body=p_head->body;
p_node->p_next=p_head->p_next;
p_head->p_prev=NULL;
p_head->body=&map[*p_x][*p_y];
p_head->p_next=p_node;
p_node->p_prev=p_head;
/*p_head=p_head^p_tail; //异或交换两个节点的值
p_tail=p_head^p_tail;
p_head=p_head^p_tail;*/
}
int move(int map[20][20],int* p_x,int* p_y,int* p_ax,int* p_ay,node* p_head,node* p_tail)
{
switch(dir){
case 'a':
if(map[--*p_x][*p_y]==0){
SaveTailBody=p_tail->body;
SaveTailBody=0;
p_tail->body=p_tail->p_prev->body;
map[*p_x][*p_y]=1;
p_head->body=&map[*p_x][*p_y];
break;
}
++*p_x;
if(map[--*p_x][*p_y]==2){
map[*p_x][*p_y]=1;
// add_body(map,p_x,p_y,p_ax,p_ay,p_head,p_tail,tailSave);
node p_node=(node*)malloc(sizeof(node));
if(!p_node) perror("p_node"),exit(-1);
p_head->p_next->p_prev=p_node;
p_node->p_prev=p_head;
p_node->body=p_head->body;
p_node->p_next=p_head->p_next;
p_head->body=&map[*p_x][*p_y];
p_head->p_next=p_node;
break;
}
case 'd':
p_tail->body=0;
p_tail->body=p_tail->p_prev->body;
map[++*p_x][*p_y]=1;
p_head->body=&map[*p_x][*p_y];
break;
case 'w':
*p_tail->body=0;
p_tail->body=p_tail->p_prev->body;
map[*p_x][--*p_y]=1;
p_head->body=&map[*p_x][*p_y];
break;
case 's':
*p_tail->body=0;
p_tail->body=p_tail->p_prev->body;
map[*p_x][++*p_y]=1;
p_head->body=&map[*p_x][*p_y];
break;
}
}
void task(void* p){
while(1){
scanf("%s",&dir);
}
}
int main()
{
int map[20][20]={};
srand(time(0));
int x=0,y=0; //初始化蛇头坐标
int ax=0,ay=0; //初始化实食物坐标
x=rand()%18+1;y=rand()%18+1;
ax=rand()%18+1;
ay=rand()%18+1;
map[x][y]=1;
map[x+1][y]=1; //蛇尾坐标
map[ax][ay]=2;
int* p_x;int*p_y;
int* p_ax;int*p_ay;
p_x=&x;p_y=&y;
p_ax=&ax;p_ay=&ay;
node* p_head=(node*)malloc(sizeof(node));
if(!p_head) perror("p_head"),exit(-1);
node* p_tail=(node*)malloc(sizeof(node));
if(!p_tail) perror("p_tail"),exit(-1);
p_head->body=&map[x][y];
p_head->p_prev=NULL;
p_head->p_next=p_tail;
p_tail->body=&map[x+1][y];
p_tail->p_prev=p_head;
p_tail->p_next=NULL;
pthread_t id;
pthread_create(&id,0,task,0);
while(1){
show(map,x,y);
if(*p_x==0||*p_x==19||*p_y==0||*p_y==19){
printf("GAME OVERn");
exit(-1);
}
move(map,p_x,p_y,p_ax,p_ay,p_head,p_tail);
usleep(300000);
}
return 0;}
首先,描述一下功能
地图是一个二位数组,蛇是一个结构体的节点:
typedef struct node{
int* body;
struct node* p_prev;
struct node* p_next;
}node;
因为是双向链表所有有上一个跟下一个的指针。
食物在地图上的值是2:
map[ax][ay]=2;
蛇头是p_head,尾是p_tail;wasd是上下左右,多线程实现,按一下方向会不停走,直到方向改变或者撞墙。
问题来了:
吃到食物之后(向左吃到食物,就是a方向)
case 'a':
if(map[--*p_x][*p_y]==0){
SaveTailBody=p_tail->body;
SaveTailBody=0;
p_tail->body=p_tail->p_prev->body;
map[*p_x][*p_y]=1;
p_head->body=&map[*p_x][*p_y];
break;
}
++*p_x;
if(map[--*p_x][*p_y]==2){
map[*p_x][*p_y]=1;
// add_body(map,p_x,p_y,p_ax,p_ay,p_head,p_tail,tailSave);
node p_node=(node*)malloc(sizeof(node));
if(!p_node) perror("p_node"),exit(-1);
p_head->p_next->p_prev=p_node;
p_node->p_prev=p_head;
p_node->body=p_head->body;
p_node->p_next=p_head->p_next;
p_head->body=&map[*p_x][*p_y];
p_head->p_next=p_node;
break;
}
开辟了一个堆空间用来存储新增加的节点,食物的节点用来当蛇头(1是蛇,2是食物),把新增加的节点放在蛇头后面。
因为初始的蛇是两个节点,一个头一个尾,我把新节点加在头的位置或者尾的位置或者中间的位置都试过了,然并卵。
吃到食物之后确实增加了一个蛇身节点,显示也正确,但是走了两步之后蛇就开始走一步长一结,而且我把p_tail->p_prev->body(尾节点的上一个节点的body)打出来之后居然是0(1是蛇身,意思就是这个节点的位置应该是空的才对),我一直在纠结是不是指针操作出问题,已经来来回回看过好多遍了,实在找不到问题所在。