1.A*算法描述
2.A*算法实现
struct father
{
int fx;int fy;
};//用于保存父区域
struct father fathers[12][12];
int openlist[12][12];
int closelist[12][12];
int F[12][12];
int G[12][12];
int H[12][12];
int block[12][12];
void turn(int x,int y,int cx,int cy)
{
fathers[x][y].fx=cx;
fathers[x][y].fy=cy;
}
void cal(int x,int y,int cx,int cy)
{
int add;
if(x+y==cx+cy||x-y==cx-cy)
add=14;
else
add=10;
int amount=G[cx][cy]+add;
if(amount<G[x][y])
{
turn(x,y,cx,cy);
G[x][y]=amount;
F[x][y]=amount+H[x][y];
}
}
void testing(int x,int y,int cx,int cy)//即(2)的第三步的操作
{
if(block[x][y]==1||closelist[x][y]==1)
return;
else
{
if(openlist[x][y]==0)
{
openlist[x][y]=1;
turn(x,y,cx,cy);
}
else
{
cal(x,y,cx,cy);
}
}
}
int abs(int x)
{
return x>0?x:(-x);
}//返回的是某数的绝对值
void Astar(int x,int y,int dx,int dy)//(x,y)即初始位置, (dx,dy)为目标位置
{
int i,j;
int v,w;
for(v=1;v<=10;v++)
for(w=1;w<=10;w++)
H[v][w]=abs(dx-v)*10+abs(dy-w)*10;
F[x][y]=-1;
G[x][y]=0;
openlist[x][y]=1;//即(1)步骤
while(1)//即(2)步骤
{
int i,j;int minf=50000,cx,cy;
for(i=1;i<=10;i++)
for(j=1;j<=10;j++)
{
if(openlist[i][j]==1)
{
if(F[i][j]<minf)
{
minf=F[i][j];
cx=i;
cy=j;
}
}
} //F值最小点(cx,cy);//即(2)的第一步
openlist[cx][cy]=0;
closelist[cx][cy]=1;//即(2)的第二步
testing(cx+1,cy,cx,cy);
testing(cx-1,cy,cx,cy);
testing(cx,cy+1,cx,cy);
testing(cx,cy-1,cx,cy);
testing(cx-1,cy-1,cx,cy);
testing(cx-1,cy+1,cx,cy);
testing(cx+1,cy-1,cx,cy);
testing(cx+1,cy+1,cx,cy); //均为(2)的第三步
if(openlist[dx][dy]==1)//即为(2)的第四步
break;
}
}
3.构造蛇身队列的实现
typedef struct queue{
int x;
int y;
struct queue *next;
}queue ,*ptr;//定义了一个队列,神奇的是,front->next 指向蛇尾,rear指向蛇头
queue q;
ptr front;
ptr rear;
int count;
int tt=0;
void enterq(int m,int n)
{
queue *e;
e=(struct queue *)malloc(sizeof(struct queue));
e->x=m;
e->y=n;
e->next=NULL;
rear->next=e;
rear=e;
count++;
}
void leaveq()
{
front->next=front->next->next;
count--;
if(count==0)
rear=front;
}
4.在本实例中,记“$”所在位置为(remainofx,remainofy)//为什么是remain后面有说明,可以理解为(remainofx,remainofy)为大目标,(xx,yy)为当前的小目标
5.在非蛇身区域设点的实现
void set()
{
if(flag==1)
{
int fff,i,j;
do
{
srand((unsigned)time(NULL));
i=rand()%10+1;
j=rand()%10+1;
ptr p=front->next;
fff=0;
while(p!=NULL)
{
if(p->x==i&&p->y==j)
fff=1;
p=p->next;
}
}
while(fff==1);
remainofx=i;remainofy=j;
}
else
return ;
}
6.输入某字符后对蛇身队列的操作
void f(char c)
{
int tmpx=rear->x;
int tmpy=rear->y;
leaveq();
if(c=='w')
enterq(tmpx,tmpy+1);
if(c=='s')
enterq(tmpx,tmpy-1);
if(c=='a')
enterq(tmpx-1,tmpy);
if(c=='d')
enterq(tmpx+1,tmpy);
flag=0;
}//这个是假如蛇下一步没吃到的话,对队列的操作
void eatenf(char c)
{
int tmpx=rear->x;
int tmpy=rear->y;
if(c=='w')
enterq(tmpx,tmpy+1);
if(c=='s')
enterq(tmpx,tmpy-1);
if(c=='a')
enterq(tmpx-1,tmpy);
if(c=='d')
enterq(tmpx+1,tmpy);
if(rear->x==remainofx&&rear->y==remainofy)
{
flag=1;
}
set();
}//这个是假如蛇下一步吃到的话,对队列的操作
7.打表实现
int map[120][120];
int wjudge;//这个是是否胜利判断
void display()
{
int i,j;
for(i=0;i<12;i++)
for(j=0;j<12;j++)
map[i][j]=0;
ptr p=front;
p=p->next;
map[remainofx][remainofy]=3;
map[rear->x][rear->y]=2;
while(p!=rear)
{
map[p->x][p->y]=1;
p=p->next;
}
printf("\n\n\n");
printf("\t\t\t\t************\n");
for(j=10;j>=1;j--)
{
printf("\t\t\t\t*");
for(i=1;i<=10;i++)
{
if(map[i][j]==3)
printf("$");
if(map[i][j]==2)
printf("H");
if(map[i][j]==1)
printf("O");
if(map[i][j]==0)
printf(" ");
}
printf("*\n");
}
printf("\t\t\t\t************\n\n");
int gg=0;
for(i=1;i<=10;i++)
for(j=1;j<=10;j++)
if(map[i][j]==0||map[i][j]==3)
gg=1;
if(gg==0)
wjudge=1;
}//用于打表
8.游戏是否结束判断
int gameoverjudge()
{
ptr p=front->next;
if(rear->x<1||rear->x>10||rear->y<1||rear->y>10)
return 1;
while(p!=rear)
{
if(p->x==rear->x&&p->y==rear->y)
return 1;
p=p->next;
}
return 0;
}
9.头是否碰到自身判断
int CollisionWithItselfTest(char c)
{
if(c=='w')
if(rear->y==10) return 1;
if(c=='s')
if(rear->y==1) return 1;
if(c=='a')
if(rear->x==1) return 1;
if(c=='d')
if(rear->x==10) return 1;
ptr p=front->next;
if(c=='w')
{
while(p!=rear)
{
if(p->x==rear->x&&p->y==rear->y+1)
return 1;
p=p->next;
}
}
if(c=='s')
{
while(p!=rear)
{
if(p->x==rear->x&&p->y==rear->y-1)
return 1;
p=p->next;
}
}
if(c=='a')
{
while(p!=rear)
{
if(p->x==rear->x-1&&p->y==rear->y)
return 1;
p=p->next;
}
}
if(c=='d')
{
while(p!=rear)
{
if(p->x==rear->x+1&&p->y==rear->y)
return 1;
p=p->next;
}
}
return 0;
}
10.最简单的求距离最短走法实现
char whereGoNext()
{
ptr p;
p=front->next;
while(p->next!=rear)
p=p->next;//p为头前一个坐标地址
char movable[5]={"wsad"};
int distance[4];
distance[0]=(xx-(rear->x))*(xx-(rear->x))+(yy-(rear->y+1))*(yy-(rear->y+1));
distance[1]=(xx-(rear->x))*(xx-(rear->x))+(yy-(rear->y-1))*(yy-(rear->y-1));
distance[2]=(xx-(rear->x-1))*(xx-(rear->x-1))+(yy-(rear->y))*(yy-(rear->y));
distance[3]=(xx-(rear->x+1))*(xx-(rear->x+1))+(yy-(rear->y))*(yy-(rear->y));
if(rear->x==p->x&&rear->y+1==p->y)
distance[0]=99;
if(rear->x==p->x&&rear->y-1==p->y)
distance[1]=99;
if(rear->x-1==p->x&&rear->y==p->y)
distance[2]=99;
if(rear->x+1==p->x&&rear->y==p->y)
distance[3]=99;
int b=0;
for(;b<4;b++)
if(CollisionWithItselfTest(movable[b])==1)
distance[b]=99;
int which;
int i=0;int min=10000;
for(;i<4;i++)
{
if(distance[i]<min)
{
min=distance[i];
which=i;
}
}
return movable[which];
}
11.对蛇身队列操作的选择
int functionselecter(char c)
{
if(c=='w')
if(rear->y+1==remainofy&&rear->x==remainofx)
return 0;
if(c=='s')
if(rear->y-1==remainofy&&rear->x==remainofx)
return 0;
if(c=='a')
if(rear->y==remainofy&&rear->x-1==remainofx)
return 0;
if(c=='d')
if(rear->y==remainofy&&rear->x+1==remainofx)
return 0;
return 1;
}
12.蛇头与”$”是否相邻判断
int adjacent()
{
int rx=rear->x;int ry=rear->y;
if(rx+1==xx&&ry==yy)
return 1;
if(rx+1==xx&&ry-1==yy)
return 1;
if(rx+1==xx&&ry+1==yy)
return 1;
if(rx==xx&&ry+1==yy)
return 1;
if(rx==xx&&ry-1==yy)
return 1;
if(rx-1==xx&&ry==yy)
return 1;
if(rx-1==xx&&ry+1==yy)
return 1;
if(rx-1==xx&&ry-1==yy)
return 1;
return 0;
}
13.通过递归进行判断:是否头与”$”间有通道(未考虑蛇身移动后有空位情况)
int indicator;
int mmmap[12][12];
int color[12][12];
int THEX;int THEY;
void approachable(int x,int y)
{
if(x==THEX&&y==THEY)
{
indicator=1;
return;
}
if(x==0||y==0||x==11||y==11)
return ;
if(color[x+1][y]==0&&x<=9&&mmmap[x+1][y]==0)
{color[x+1][y]=1;
approachable(x+1,y);
}
if(color[x-1][y]==0&&x>=2&&mmmap[x-1][y]==0)
{
color[x-1][y]=1;
approachable(x-1,y);
}
if(color[x][y+1]==0&&y<=9&&mmmap[x][y+1]==0)
{
color[x][y+1]=1;
approachable(x,y+1);
}
if(color[x][y-1]==0&&y>=2&&mmmap[x][y-1]==0)
{
color[x][y-1]=1;
approachable(x,y-1);
}
}
14.将不能走到的点进行标记
void mark()
{
int i,j;
for(i=0;i<12;i++)
for(j=0;j<12;j++)
color[i][j]=0;
for(i=0;i<12;i++)
for(j=0;j<12;j++)
mmmap[i][j]=0;
ptr p=front->next;
while(p!=rear)
{
mmmap[p->x][p->y]=1;
p=p->next;
}
}
15.对困境部分进行改进(即当无通道时,将下一步的目标(xx,yy)设置为蛇可触及的且离”$”最远的四个直角边界点)(当上述设置失效(比如四点都被占了或蛇仍然无法走到),则设置下一步的目标(xx,yy)为头的上下左右中的任一空位)
void function()
{
int i,j;
int map[12][12];
for(i=0;i<12;i++)
for(j=0;j<12;j++)
map[i][j]=0;
ptr p=front->next;
int d[6];
d[1]=(remainofx-1)*(remainofx-1)+(remainofy-1)*(remainofy-1);
d[2]=(remainofx-10)*(remainofx-10)+(remainofy-1)*(remainofy-1);
d[3]=(remainofx-10)*(remainofx-10)+(remainofy-10)*(remainofy-10);
d[4]=(remainofx-1)*(remainofx-1)+(remainofy-10)*(remainofy-10);int in[6];int nn;for(nn=1;nn<=4;nn++)in[nn]=1;
indicator=0;
THEX=1;THEY=1;approachable(rear->x,rear->y);
if(indicator==0)
in[1]=0;
indicator=0;
THEX=10;THEY=1;approachable(rear->x,rear->y);
if(indicator==0)
in[2]=0;
indicator=0;
THEX=10;THEY=10;approachable(rear->x,rear->y);
if(indicator==0)
in[3]=0;
indicator=0;
THEX=1;THEY=10;approachable(rear->x,rear->y);
if(indicator==0)
in[4]=0;
indicator=0;
int a,b;int max=-1;
for(a=1;a<=4;a++)
{
if(in[a]==1)
{
if(d[i]>max)
{
max=d[i];
b=a;
}
}
}
if(max!=-1)
{
if(b==1)
{
xx=1;yy=1;return ;
}
if(b==2)
{
xx=10;yy=1;return;
}
if(b==3)
{
xx=10;yy=10;return ;
}
if(b==4)
{
xx=1;yy=10;return ;
}
}
else{
while(p!=rear)
{
map[p->x][p->y]=1;
p=p->next;
}
if(map[rear->x-1][rear->y]==0&&rear->x>=2)
{
xx=xx-1;return ;
}
if(map[rear->x+1][rear->y]==0&&rear->x<=9)
{
xx=xx+1;return ;
}
if(map[rear->x][rear->y+1]==0&&rear->y<=9)
{
yy=yy+1;return ;
}
if(map[rear->x][rear->y-1]==0&&rear->y>=2)
{
yy=yy-1;return ;
}
}
}
16.鉴于有时A*算法对近在眼前的目标反而运算慢,所以这里让蛇对近在眼前的目标直接吃掉
int QuickGet()
{
int rx=rear->x;
int ry=rear->y;
if(rx+1==remainofx&&ry==remainofy)
return 1;
if(rx==remainofx&&ry+1==remainofy)
return 1;
if(rx==remainofx&&ry-1==remainofy)
return 1;
if(rx-1==remainofx&&ry==remainofy)
return 1;
return 0;
}
17.主函数
int main()
{
memset(block,0,sizeof(block));
int bb;
for(bb=0;bb<=11;bb++)
block[0][bb]=1;
for(bb=0;bb<=11;bb++)
block[bb][0]=1;
for(bb=0;bb<=11;bb++)
block[11][bb]=1;
for(bb=0;bb<=11;bb++)
block[bb][11]=1;//将四周设为A*中不可到达
count=1;
wjudge=0;
front=&q;
rear =&q;
q.next=NULL;
int x;
for(x=1;x<=5;x++)
enterq(x,10);//入队操作
flag=1;
set();
display();
while(1)
{
DWORD start=GetTickCount();
system("CLS");
mark();
indicator=0;
THEX=remainofx;THEY=remainofy;
memset(block,0,sizeof(block));
ptr qa=front->next;
while(qa!=rear)
{
block[qa->x][qa->y]=1;
qa=qa->next;
}
approachable(rear->x,rear->y);
if(QuickGet()!=0)
{
xx=remainofx;
yy=remainofy;
}
else
{
if(indicator==0)
{
function();
indicator=0;
}
else{
int i,j;
for(i=1;i<=10;i++)
for(j=1;j<=10;j++)
{
fathers[i][j].fx=i;
fathers[i][j].fy=j;
}
for(i=1;i<=10;i++)
for(j=1;j<=10;j++)
{
block[i][j]=0;
}
memset(openlist,0,sizeof(openlist));
memset(closelist,0,sizeof(closelist));
memset(F,0,sizeof(F));
memset(G,0,sizeof(G));
memset(H,0,sizeof(H));
ptr p=front->next;
while(p!=rear)
{
block[p->x][p->y]=1;
p=p->next;
}
Astar(rear->x,rear->y,remainofx,remainofy);
xx=remainofx;yy=remainofy;
while((fathers[xx][yy].fx==rear->x&&fathers[xx][yy].fy==rear->y)!=1&&(adjacent()==0))//这里的意思就是,通过父区域的回溯,从(remainofx,remainofy)开始,使(xx,yy)为蛇下一个移动的目标
{
int tx=fathers[xx][yy].fx;
int ty=fathers[xx][yy].fy;
xx=tx;
yy=ty;
}
}
}
char c=whereGoNext();
switch(c)
{
case 'w':functionselecter(c)==1?f('w'):eatenf('w');break;
case 's':functionselecter(c)==1?f('s'):eatenf('s');break;
case 'a':functionselecter(c)==1?f('a'):eatenf('a');break;
case 'd':functionselecter(c)==1?f('d'):eatenf('d');break;
default:continue;
}
if(gameoverjudge()==1)
{
display();
printf("\n\t\t\t\tGAMEOVER!!!!!!\n");
break;
}
if(wjudge==1)
{
printf("\n\t\t\t\tWIN!!\n");
break;
}
else
display();
DWORD end=GetTickCount();
int time=end - start;
if(time>=200)
continue;
else
Sleep(200-time);//使每次更新的间隔都大概为0.2秒
}
}
18.汇总
#include <stdio.h>
#include <malloc.h>
#include <time.h>
#include <memory.h>
#include <windows.h>
int flag;
int xx,yy;
int remainofx,remainofy;
struct father
{
int fx;int fy;
};//用于保存父区域
struct father fathers[12][12];
int openlist[12][12];
int closelist[12][12];
int F[12][12];
int G[12][12];
int H[12][12];
int block[12][12];
void turn(int x,int y,int cx,int cy)
{
fathers[x][y].fx=cx;
fathers[x][y].fy=cy;
}
void cal(int x,int y,int cx,int cy)
{
int add;
if(x+y==cx+cy||x-y==cx-cy)
add=14;
else
add=10;
int amount=G[cx][cy]+add;
if(amount<G[x][y])
{
turn(x,y,cx,cy);
G[x][y]=amount;
F[x][y]=amount+H[x][y];
}
}
void testing(int x,int y,int cx,int cy)//即(2)的第三步的操作
{
if(block[x][y]==1||closelist[x][y]==1)
return;
else
{
if(openlist[x][y]==0)
{
openlist[x][y]=1;
turn(x,y,cx,cy);
}
else
{
cal(x,y,cx,cy);
}
}
}
int abs(int x)
{
return x>0?x:(-x);
}//返回的是某数的绝对值
void Astar(int x,int y,int dx,int dy)//(x,y)即初始位置, (dx,dy)为目标位置
{
int i,j;
int v,w;
for(v=1;v<=10;v++)
for(w=1;w<=10;w++)
H[v][w]=abs(dx-v)*10+abs(dy-w)*10;
F[x][y]=-1;
G[x][y]=0;
openlist[x][y]=1;//即(1)步骤
while(1)//即(2)步骤
{
int i,j;int minf=50000,cx,cy;
for(i=1;i<=10;i++)
for(j=1;j<=10;j++)
{
if(openlist[i][j]==1)
{
if(F[i][j]<minf)
{
minf=F[i][j];
cx=i;
cy=j;
}
}
} //F值最小点(cx,cy);//即(2)的第一步
openlist[cx][cy]=0;
closelist[cx][cy]=1;//即(2)的第二步
testing(cx+1,cy,cx,cy);
testing(cx-1,cy,cx,cy);
testing(cx,cy+1,cx,cy);
testing(cx,cy-1,cx,cy);
testing(cx-1,cy-1,cx,cy);
testing(cx-1,cy+1,cx,cy);
testing(cx+1,cy-1,cx,cy);
testing(cx+1,cy+1,cx,cy); //均为(2)的第三步
if(openlist[dx][dy]==1)//即为(2)的第四步
break;
}
}
typedef struct queue{
int x;
int y;
struct queue *next;
}queue ,*ptr;//定义了一个队列,神奇的是,front->next 指向蛇尾,rear指向蛇头
queue q;
ptr front;
ptr rear;
int count;
int tt=0;
void enterq(int m,int n)
{
queue *e;
e=(struct queue *)malloc(sizeof(struct queue));
e->x=m;
e->y=n;
e->next=NULL;
rear->next=e;
rear=e;
count++;
}
void leaveq()
{
front->next=front->next->next;
count--;
if(count==0)
rear=front;
}
void set()
{
if(flag==1)
{
int fff,i,j;
do
{
srand((unsigned)time(NULL));
i=rand()%10+1;
j=rand()%10+1;
ptr p=front->next;
fff=0;
while(p!=NULL)
{
if(p->x==i&&p->y==j)
fff=1;
p=p->next;
}
}
while(fff==1);
remainofx=i;remainofy=j;
}
else
return ;
}
void f(char c)
{
int tmpx=rear->x;
int tmpy=rear->y;
leaveq();
if(c=='w')
enterq(tmpx,tmpy+1);
if(c=='s')
enterq(tmpx,tmpy-1);
if(c=='a')
enterq(tmpx-1,tmpy);
if(c=='d')
enterq(tmpx+1,tmpy);
flag=0;
}//这个是假如蛇下一步没吃到的话,对队列的操作
void eatenf(char c)
{
int tmpx=rear->x;
int tmpy=rear->y;
if(c=='w')
enterq(tmpx,tmpy+1);
if(c=='s')
enterq(tmpx,tmpy-1);
if(c=='a')
enterq(tmpx-1,tmpy);
if(c=='d')
enterq(tmpx+1,tmpy);
if(rear->x==remainofx&&rear->y==remainofy)
{
flag=1;
}
set();
}//这个是假如蛇下一步吃到的话,对队列的操作
int map[120][120];
int wjudge;//这个是是否胜利判断
void display()
{
int i,j;
for(i=0;i<12;i++)
for(j=0;j<12;j++)
map[i][j]=0;
ptr p=front;
p=p->next;
map[remainofx][remainofy]=3;
map[rear->x][rear->y]=2;
while(p!=rear)
{
map[p->x][p->y]=1;
p=p->next;
}
printf("\n\n\n");
printf("\t\t\t\t************\n");
for(j=10;j>=1;j--)
{
printf("\t\t\t\t*");
for(i=1;i<=10;i++)
{
if(map[i][j]==3)
printf("$");
if(map[i][j]==2)
printf("H");
if(map[i][j]==1)
printf("O");
if(map[i][j]==0)
printf(" ");
}
printf("*\n");
}
printf("\t\t\t\t************\n\n");
int gg=0;
for(i=1;i<=10;i++)
for(j=1;j<=10;j++)
if(map[i][j]==0||map[i][j]==3)
gg=1;
if(gg==0)
wjudge=1;
}//用于打表
int gameoverjudge()
{
ptr p=front->next;
if(rear->x<1||rear->x>10||rear->y<1||rear->y>10)
return 1;
while(p!=rear)
{
if(p->x==rear->x&&p->y==rear->y)
return 1;
p=p->next;
}
return 0;
}
int CollisionWithItselfTest(char c)
{
if(c=='w')
if(rear->y==10) return 1;
if(c=='s')
if(rear->y==1) return 1;
if(c=='a')
if(rear->x==1) return 1;
if(c=='d')
if(rear->x==10) return 1;
ptr p=front->next;
if(c=='w')
{
while(p!=rear)
{
if(p->x==rear->x&&p->y==rear->y+1)
return 1;
p=p->next;
}
}
if(c=='s')
{
while(p!=rear)
{
if(p->x==rear->x&&p->y==rear->y-1)
return 1;
p=p->next;
}
}
if(c=='a')
{
while(p!=rear)
{
if(p->x==rear->x-1&&p->y==rear->y)
return 1;
p=p->next;
}
}
if(c=='d')
{
while(p!=rear)
{
if(p->x==rear->x+1&&p->y==rear->y)
return 1;
p=p->next;
}
}
return 0;
}
char whereGoNext()
{
ptr p;
p=front->next;
while(p->next!=rear)
p=p->next;//p为头前一个坐标地址
char movable[5]={"wsad"};
int distance[4];
distance[0]=(xx-(rear->x))*(xx-(rear->x))+(yy-(rear->y+1))*(yy-(rear->y+1));
distance[1]=(xx-(rear->x))*(xx-(rear->x))+(yy-(rear->y-1))*(yy-(rear->y-1));
distance[2]=(xx-(rear->x-1))*(xx-(rear->x-1))+(yy-(rear->y))*(yy-(rear->y));
distance[3]=(xx-(rear->x+1))*(xx-(rear->x+1))+(yy-(rear->y))*(yy-(rear->y));
if(rear->x==p->x&&rear->y+1==p->y)
distance[0]=99;
if(rear->x==p->x&&rear->y-1==p->y)
distance[1]=99;
if(rear->x-1==p->x&&rear->y==p->y)
distance[2]=99;
if(rear->x+1==p->x&&rear->y==p->y)
distance[3]=99;
int b=0;
for(;b<4;b++)
if(CollisionWithItselfTest(movable[b])==1)
distance[b]=99;
int which;
int i=0;int min=10000;
for(;i<4;i++)
{
if(distance[i]<min)
{
min=distance[i];
which=i;
}
}
return movable[which];
}
int functionselecter(char c)
{
if(c=='w')
if(rear->y+1==remainofy&&rear->x==remainofx)
return 0;
if(c=='s')
if(rear->y-1==remainofy&&rear->x==remainofx)
return 0;
if(c=='a')
if(rear->y==remainofy&&rear->x-1==remainofx)
return 0;
if(c=='d')
if(rear->y==remainofy&&rear->x+1==remainofx)
return 0;
return 1;
}
int adjacent()
{
int rx=rear->x;int ry=rear->y;
if(rx+1==xx&&ry==yy)
return 1;
if(rx+1==xx&&ry-1==yy)
return 1;
if(rx+1==xx&&ry+1==yy)
return 1;
if(rx==xx&&ry+1==yy)
return 1;
if(rx==xx&&ry-1==yy)
return 1;
if(rx-1==xx&&ry==yy)
return 1;
if(rx-1==xx&&ry+1==yy)
return 1;
if(rx-1==xx&&ry-1==yy)
return 1;
return 0;
}
int indicator;
int mmmap[12][12];
int color[12][12];
int THEX;int THEY;
void approachable(int x,int y)
{
if(x==THEX&&y==THEY)
{
indicator=1;
return;
}
if(x==0||y==0||x==11||y==11)
return ;
if(color[x+1][y]==0&&x<=9&&mmmap[x+1][y]==0)
{color[x+1][y]=1;
approachable(x+1,y);
}
if(color[x-1][y]==0&&x>=2&&mmmap[x-1][y]==0)
{
color[x-1][y]=1;
approachable(x-1,y);
}
if(color[x][y+1]==0&&y<=9&&mmmap[x][y+1]==0)
{
color[x][y+1]=1;
approachable(x,y+1);
}
if(color[x][y-1]==0&&y>=2&&mmmap[x][y-1]==0)
{
color[x][y-1]=1;
approachable(x,y-1);
}
}
void mark()
{
int i,j;
for(i=0;i<12;i++)
for(j=0;j<12;j++)
color[i][j]=0;
for(i=0;i<12;i++)
for(j=0;j<12;j++)
mmmap[i][j]=0;
ptr p=front->next;
while(p!=rear)
{
mmmap[p->x][p->y]=1;
p=p->next;
}
}
void function()
{
int i,j;
int map[12][12];
for(i=0;i<12;i++)
for(j=0;j<12;j++)
map[i][j]=0;
ptr p=front->next;
int d[6];
d[1]=(remainofx-1)*(remainofx-1)+(remainofy-1)*(remainofy-1);
d[2]=(remainofx-10)*(remainofx-10)+(remainofy-1)*(remainofy-1);
d[3]=(remainofx-10)*(remainofx-10)+(remainofy-10)*(remainofy-10);
d[4]=(remainofx-1)*(remainofx-1)+(remainofy-10)*(remainofy-10);int in[6];int nn;for(nn=1;nn<=4;nn++)in[nn]=1;
indicator=0;
THEX=1;THEY=1;approachable(rear->x,rear->y);
if(indicator==0)
in[1]=0;
indicator=0;
THEX=10;THEY=1;approachable(rear->x,rear->y);
if(indicator==0)
in[2]=0;
indicator=0;
THEX=10;THEY=10;approachable(rear->x,rear->y);
if(indicator==0)
in[3]=0;
indicator=0;
THEX=1;THEY=10;approachable(rear->x,rear->y);
if(indicator==0)
in[4]=0;
indicator=0;
int a,b;int max=-1;
for(a=1;a<=4;a++)
{
if(in[a]==1)
{
if(d[i]>max)
{
max=d[i];
b=a;
}
}
}
if(max!=-1)
{
if(b==1)
{
xx=1;yy=1;return ;
}
if(b==2)
{
xx=10;yy=1;return;
}
if(b==3)
{
xx=10;yy=10;return ;
}
if(b==4)
{
xx=1;yy=10;return ;
}
}
else{
while(p!=rear)
{
map[p->x][p->y]=1;
p=p->next;
}
if(map[rear->x-1][rear->y]==0&&rear->x>=2)
{
xx=xx-1;return ;
}
if(map[rear->x+1][rear->y]==0&&rear->x<=9)
{
xx=xx+1;return ;
}
if(map[rear->x][rear->y+1]==0&&rear->y<=9)
{
yy=yy+1;return ;
}
if(map[rear->x][rear->y-1]==0&&rear->y>=2)
{
yy=yy-1;return ;
}
}
}
int QuickGet()
{
int rx=rear->x;
int ry=rear->y;
if(rx+1==remainofx&&ry==remainofy)
return 1;
if(rx==remainofx&&ry+1==remainofy)
return 1;
if(rx==remainofx&&ry-1==remainofy)
return 1;
if(rx-1==remainofx&&ry==remainofy)
return 1;
return 0;
}
int main()
{
memset(block,0,sizeof(block));
int bb;
for(bb=0;bb<=11;bb++)
block[0][bb]=1;
for(bb=0;bb<=11;bb++)
block[bb][0]=1;
for(bb=0;bb<=11;bb++)
block[11][bb]=1;
for(bb=0;bb<=11;bb++)
block[bb][11]=1;//将四周设为A*中不可到达
count=1;
wjudge=0;
front=&q;
rear =&q;
q.next=NULL;
int x;
for(x=1;x<=5;x++)
enterq(x,10);//入队操作
flag=1;
set();
display();
while(1)
{
DWORD start=GetTickCount();
system("CLS");
mark();
indicator=0;
THEX=remainofx;THEY=remainofy;
memset(block,0,sizeof(block));
ptr qa=front->next;
while(qa!=rear)
{
block[qa->x][qa->y]=1;
qa=qa->next;
}
approachable(rear->x,rear->y);
if(QuickGet()!=0)
{
xx=remainofx;
yy=remainofy;
}
else
{
if(indicator==0)
{
function();
indicator=0;
}
else{
int i,j;
for(i=1;i<=10;i++)
for(j=1;j<=10;j++)
{
fathers[i][j].fx=i;
fathers[i][j].fy=j;
}
for(i=1;i<=10;i++)
for(j=1;j<=10;j++)
{
block[i][j]=0;
}
memset(openlist,0,sizeof(openlist));
memset(closelist,0,sizeof(closelist));
memset(F,0,sizeof(F));
memset(G,0,sizeof(G));
memset(H,0,sizeof(H));
ptr p=front->next;
while(p!=rear)
{
block[p->x][p->y]=1;
p=p->next;
}
Astar(rear->x,rear->y,remainofx,remainofy);
xx=remainofx;yy=remainofy;
while((fathers[xx][yy].fx==rear->x&&fathers[xx][yy].fy==rear->y)!=1&&(adjacent()==0))//这里的意思就是,通过父区域的回溯,从(remainofx,remainofy)开始,使(xx,yy)为蛇下一个移动的目标
{
int tx=fathers[xx][yy].fx;
int ty=fathers[xx][yy].fy;
xx=tx;
yy=ty;
}
}
}
char c=whereGoNext();
switch(c)
{
case 'w':functionselecter(c)==1?f('w'):eatenf('w');break;
case 's':functionselecter(c)==1?f('s'):eatenf('s');break;
case 'a':functionselecter(c)==1?f('a'):eatenf('a');break;
case 'd':functionselecter(c)==1?f('d'):eatenf('d');break;
default:continue;
}
if(gameoverjudge()==1)
{
display();
printf("\n\t\t\t\tGAMEOVER!!!!!!\n");
break;
}
if(wjudge==1)
{
printf("\n\t\t\t\tWIN!!\n");
break;
}
else
display();
DWORD end=GetTickCount();
int time=end - start;
if(time>=200)
continue;
else
Sleep(200-time);//使每次更新的间隔都大概为0.2秒
}
}
19.演示