当前位置:文档之家› 电脑鼠走迷宫仿真程序eMouse

电脑鼠走迷宫仿真程序eMouse

/*******************************************************************************
** 程序名称: 电脑鼠模拟环境 V5.0
** 功能描述: 电脑鼠走迷宫的模拟软件,探索迷宫速度超快,迅速找到终点;
注意:迷宫中心是终点。
本程序使用Win-TC编译,图形界面。
下载本程序后将后缀名改为.c,即可在Win-TC下编译。
** 程序作者: 宋元瑞
** 修改日期: 2010年10月1日
*******************************************************************************/
#include
#include
#include
#include
typedef unsigned long int uint32;
#define closegr closegraph
#define ESC 0x011b
#define BLANK 14624
#define UP 0x01 /*上有墙*/
#define DOWN 0x02
#define LEFT 0x04
#define RIGHT 0x08
#define X 25 /* 迷宫单位规格,实物18 */
/*#define W 20 迷宫宽度WIDE,实物16.8 */
/*#define L 25 迷宫长度LENGTH,实物18 */
#define N 16 /* 迷宫规格16×16,实物同 */
#define Xfore 120 /* 迷宫x离屏幕边缘的距离 */
#define Yfore 40 /* 迷宫y离屏幕边缘的距离 */
#define menuWidth 120 /*菜单的宽度*/
#define menuHight 25 /*菜单的高度*/
/*#define Z 1.5 屏幕放大1.5倍 */
int first=1;
int mousex,mousey; /*鼠标的坐标 */
volatile int xnow=15,ynow=0; /*电脑鼠的当前x,y坐标*/
int stepnum=0;
int start=0;
int temptime=0;
uint32 gezi[16][16];/*每个格子的信息存储器,16个x16个y,用一个32位二进制数的后四位表示墙壁信息(只用这4位)*/
/* 0001=UP
0010=DOWN
0100=LEFT
1000=RIGHT
将这些数字与gezi[][]的值进行&运算,即可获得墙壁信息

0001=UP
____
| |
0100=LEFT| ↓ |1000=RIGHT
|____|

0010=DOWN
*/
uint32 mouse[16][16]; /*用于电老鼠在循迹时接收gezi传过来的墙壁信息,并保存。(只用后四位,探测后的墙壁信息供shortroad分析)*/
uint32 shortroad[16][16];/*存储等高线值*/
uint32 road[16][16];/*电脑鼠探测到的区域*/
int menuXa=0,menuYa1=65,menuYa2=100,menuYa3=200;/*左侧菜单的坐标*/
int menu1=1,menu2=0;/*初始化菜单有效性,menu1为1(有效),menu2为0(无效)*/

union REGS regs; /

*鼠标中断*/

/*******************************************************************************
** BGI初始化函数 initgr
*******************************************************************************/
void initgr(void)
{
int gd = DETECT, gm = 0; /* 和gd = VGA,gm = VGAHI是同样效果 */
registerbgidriver(EGAVGA_driver);/*注册BGI驱动后可以不需要.BGI文件的支持运行*/
initgraph(&gd, &gm, "");
setbkcolor(BLACK);
}
/*******************************************************************************
**鼠标函数 drawmouse
*******************************************************************************/
void drawmouse(int x,int y,int fl)
{
int *buf;
int size;
if(x<=5)/*防止鼠标到达屏幕上边界时候出错,以免程序异常退出(异常原因:getimage函数找不到屏幕外的图像来保存)*/
{x=5;}
if(x>=630)
{x=630;}
if(y<5)
{y=5;}


size=imagesize(x-5,y-5,x+15,y+15);/* 让内存分配大点 */
buf=malloc(size);

if (first==0)/*后续运行时*/
{
if(fl==0)/*后续运行的第一部分运行时*/
{delay(10000);
putimage(x-5,y-5,buf,COPY_PUT);
free(buf);
}
}

if(fl==1)/*每次运行的第二部分运行时*/
{
getimage(x-5,y-5,x+5,y+5,buf);
setcolor(RED);
setfillstyle(11,YELLOW);
line(x,y-5,x,y+5); /* 十字形鼠标 */
line(x-5,y,x+5,y);
free(buf);
first=0;/*如果是首次运行,结束标记首次运行,进入后续运行标记*/
}
}
/*******************************************************************************
**画初始迷宫函数 ground
*******************************************************************************/
int ground(int xbegin,int ybegin,int xend,int yend)
{
int i,j;
cleardevice();
xbegin=Xfore+xbegin;xend=Xfore+xend;/*对4个边界点增加边界距离*/
ybegin=Yfore+ybegin;yend=Yfore+yend;

setbkcolor(LIGHTBLUE);

setfillstyle(1,LIGHTRED); /*画出四周边框 */
bar(xbegin-1,ybegin-1,xend+1,yend+1);
setfillstyle(1,WHITE);
bar(xbegin+2,ybegin+2,xend-2,yend-2);

setlinestyle(0,0,3); /* 3点宽实心线*/
setcolor(LIGHTRED);
for(i=1;i{
line(xbegin,ybegin+i*25,xend,ybegin+i*25);
}
for(i=1;i{
line(xbegin+i*25,ybegin,xbegin+i*25,yend);
}
/*画菜单*/
setcolor(YELLOW);
outtextxy(menuXa+30,menuYa1+10,"off wall");
outtextxy(menuXa+30,menuYa2+10,"put wall");
setfillstyle(1,WHITE);
setcolor(WHITE);
fillellipse(menuXa+16,menuYa1+13,5,5);
fillellipse(menuXa+16,menuYa2+13,5,5);
setcolor(LIGHTRED);
/*画autoWall按钮*/
setfillstyle(1,DARKGRAY);
bar(menuXa+25,menuYa3,menuXa+95,menuYa3+30);
setfillstyle(1,YELLOW);
bar(menuXa+22,menuYa3-3,menuXa+92,menuYa3+27);
outtextxy(menuXa+26,menuYa3+8,"AutoWall");
/*画MouseGo按钮*/
setfillstyle(1,DARKGRAY);
bar(menuXa+25,me

nuYa3+45,menuXa+95,menuYa3+45+30);
setfillstyle(1,YELLOW);
bar(menuXa+22,menuYa3+45-3,menuXa+92,menuYa3+45+27);
outtextxy(menuXa+30,menuYa3+45+8,"MouseGo");
/*画GetShort按钮*/
setfillstyle(1,DARKGRAY);
bar(menuXa+25,menuYa3+45+45,menuXa+95,menuYa3+45+45+30);
setfillstyle(1,YELLOW);
bar(menuXa+22,menuYa3+45+45-3,menuXa+92,menuYa3+45+45+27);
outtextxy(menuXa+27,menuYa3+45+45+8,"GetShort");
}
/*******************************************************************************
** 在第n位写0的子函数 write0
*******************************************************************************/
void write0(int place,uint32 *p)/*传值引用参数*p */
{
(*p)=(*p)&(~(1<}
/*******************************************************************************
** 在第n位写1的子函数 write1
*******************************************************************************/
void write1(int place,uint32 *p)/*传值引用参数*p */
{
(*p)=(*p)|(1<}
/*******************************************************************************
**在第n位读0、1的子函数 read;返回值为0或1
*******************************************************************************/
uint32 read(int place,uint32 it)
{
return(((it>>place)&1));
}
/*******************************************************************************
**在第n位开始读4个位上0、1的子函数 readng;返回值为读取的4个位上的值
*******************************************************************************/
uint32 read4(int beginplace,uint32 it)
{
return(((it>>beginplace)&0x0f));
}
/*******************************************************************************
** 检查(后四位)有无墙壁的子函数 seewall;返回值为UP DOWN RIGHT LEFT
*******************************************************************************/
int seewall(uint32 it,int which)
{
if(which==UP)
{if((it&UP)==UP) {return(UP); } else {return(0);}}
if(which==DOWN)
{if((it&DOWN)==DOWN) {return(DOWN); } else {return(0);}}
if(which==LEFT)
{if((it&LEFT)==LEFT) {return(LEFT); } else {return(0);}}
if(which==RIGHT)
{if((it&RIGHT)==RIGHT) {return(RIGHT);} else {return(0);}}
}
/*******************************************************************************
** ifbranch():查询该格点是否为分支点,是返回1,否返回0
*******************************************************************************/
int ifbranch(it)
{
int nowalls=0;
if(0==read(0,it)) {nowalls++;}
if(0==read(1,it)) {nowalls++;}
if(0==read(2,it)) {nowalls++;}
if(0==read(3,it)) {nowalls++;}
if(nowalls>1)
{return(1);}
else
{return(0);}
}
/*******************************************************************************
** 检测当前格子是否还有未探测的分支,若有就返回二进制相应位上的1,没有返回0
*******************************************************************************/
uint32 h

avenewroad(uint32 it)
{/*返回值说明:二进制第一位上的1——A墙,第二位上的1——B墙
第三位上的1——C墙,第四位上的1——D墙
(第0位上的1不用)*/
/*备注:无需预防迷宫边界格点+-会超出迷宫的情况,因为边界点使0==read(x,it)不成立*/
uint32 newroad=0;
if(0==read(0,it) && 0==read4(4,mouse[xnow][ynow-1]))/*如果A面无墙,并且上面的格子没有来自的方向(未被探测)*/
{newroad=1<<1;/*printf("1-%d,",read4(4,mouse[xnow][ynow-1]));*/}
if(0==read(1,it) && 0==read4(4,mouse[xnow][ynow+1]))
{newroad=newroad|(1<<2);/*printf("2-%d,",read4(4,mouse[xnow][ynow-1]));*/}
if(0==read(2,it) && 0==read4(4,mouse[xnow-1][ynow]))
{newroad=newroad|(1<<3);/*printf("3-%d,",read4(4,mouse[xnow][ynow-1]));*/}
if(0==read(3,it) && 0==read4(4,mouse[xnow+1][ynow]))
{newroad=newroad|(1<<4);/*printf("4-%d,",read4(4,mouse[xnow][ynow-1]));*/}
/*printf("%d ",newroad);*/
return(newroad);
}
/*******************************************************************************
** 标记探测到的上下左右的某一方面有墙壁,分别标记第0 1 2 3位为1
*******************************************************************************/
uint32 touchwall(int whichside,uint32 *it)
{
switch(whichside)/*哪一个方面有墙*/
{
case 0:write1(0,it);
break;
case 1:write1(1,it);
break;
case 2:write1(2,it);
break;
case 3:write1(3,it);
break;
default:
break;
}
}
/*******************************************************************************
** 在beginplace开始的位写ng个0
*******************************************************************************/
void writeng0(int beginplace,int ng,uint32 *it)
{
switch(ng)
{
case 1: write0(beginplace ,it);
break;
case 2: write0(beginplace ,it);
write0(beginplace+1,it);
break;
case 3: write0(beginplace ,it);
write0(beginplace+1,it);
write0(beginplace+2,it);
break;
case 4: write0(beginplace ,it);
write0(beginplace+1,it);
write0(beginplace+2,it);
write0(beginplace+3,it);
break;
default:break;
}
}
/*******************************************************************************
** 横墙函数 heng
*******************************************************************************/
int heng(int x,int y,int show)/*show=1表示画墙,show=0表示去墙*/
{
int xx=0,yy=0;
setlinestyle(0,0,3); /* 3点宽实心线*/
if(show==1)
{setcolor(LIGHTRED);gezi[x][y]|=DOWN; /* | 0010本gezi画下墙信息*/
gezi[x][y+1]|=UP; /* | 0001下邻格画上墙信息*/
}
if(show==0)
{setcolor(WHITE);gezi[x][y]&=~DOWN; /* & 1101本gezi去下墙信息*/
gezi[x][y+1]&=~UP;

/* & 1110下邻格去上墙信息*/
}
if(show==2)/*TEST*/
{
setcolor(GREEN);
}

/*以下两行相当于电脑鼠通过传感器探测到墙壁信息*/
mouse[x][y]=mouse[x][y]&gezi[x][y];
mouse[x][y+1]=mouse[x][y+1]&gezi[x][y+1];

xx=(x)*X+Xfore;
yy=(y+1)*X+Yfore;
if(show==2)
line(xx+2,yy,xx+X-2-15,yy);
else
line(xx+2,yy,xx+X-2,yy);/*设置本gezi下面的横墙*/
/*printf("x=%d,y=%d;;",xx,yy);*/
}

/*******************************************************************************
** 竖墙函数 shu
*******************************************************************************/
int shu(int x,int y,int show)/*show=1表示画墙,show=0表示去墙*/
{
int xx=0,yy=0;
setlinestyle(0,0,3); /* 3点宽实心线*/
if(show==1)
{setcolor(LIGHTRED);gezi[x][y]|=RIGHT; /* | 1000本gezi画右墙信息*/
gezi[x+1][y]|=LEFT; /* | 0100右邻格画左墙信息*/
}
if(show==0)
{setcolor(WHITE);gezi[x][y]&=~RIGHT; /* & 0111本邻格去右墙信息*/
gezi[x+1][y]&=~LEFT; /* & 1011右邻格去左墙信息*/
}
if(show==2)/*TEST*/
{
setcolor(GREEN);
}

/*以下两行相当于电脑鼠通过传感器探测到墙壁信息*/
mouse[x][y]=mouse[x][y]&gezi[x][y];
mouse[x+1][y]=mouse[x+1][y]&gezi[x+1][y];

xx=(x+1)*X+Xfore;
yy=(y)*X+Yfore;
if(show==2)
line(xx,yy+2,xx,yy+X-2-15);
else
line(xx,yy+2,xx,yy+X-2);/*设置本gezi右面的竖墙*/
/*printf("x=%d,y=%d;;",xx,yy);*/
}
/*******************************************************************************
** test():检测相邻gezi墙壁信息是否统一协调
*******************************************************************************/
void test(void)
{
int i,j;
for(i=0;i<=14;i++) /*i-x,j-y*/
{
for(j=0;j<=14;j++)
{
if(DOWN==seewall(gezi[i][j],DOWN))
{
if(UP!=seewall(gezi[i][j+1],UP)) /*判断上墙是否空*/
{printf("-X(%d,%d)-",i,j);heng(i,j,2);}
}
if(RIGHT==seewall(gezi[i][j],RIGHT))
{
if(LEFT!=seewall(gezi[i+1][j],LEFT)) /*判断左墙是否空*/
{printf("*Y(%d,%d)*",i,j);shu(i,j,2);}
}
}
}
}
/*******************************************************************************
** 自动生成迷宫
*******************************************************************************/
void autoMG(void)
{
int x,y,k;
int r=0;/*随机数变量*/

randomize();
ground(0,0,X*N,X*N); /*画初始化迷宫*/

menu1=1;menu2=0;
setfillstyle(1,DARKGRAY);setcolor(DARKGRAY);
fillellipse(menuXa+16,menuYa1+13,2,2);/*选择menu1*/

/* 所有gezi、mouse、map初始化 */
for(x=0;x<16;x++)
{
for(y=0;y<16;y++)
{
gezi[x][y] =0x000F; /* 四周满墙 */
mouse[x][y] =0x000F; /* 老鼠探测信息初始化为满墙 */

road[x][y] =0x000F; /* 电脑鼠探测的区域初始化为满*/
shortroad[x][y]=255; /*其等高线值全部初始化为255 */
}
}

setfillstyle(1,BLUE);
bar(Xfore+X*8-2,Yfore+X*8-2,Xfore+X*8+2,Yfore+X*8+2);/*终点标记物*/
heng(7,7,0);heng(8,7,0);/*终点处理*/
shu(7,7,0); shu(7,8,0);

/*先随机开49个路,增大随机性(但由于后面1/4的墙壁要被开掉,所以,这里概率上只用12个随机开路)*/
for(k=0;k<7;k++)
{
x=random(15);
y=random(15);
heng(x,y,0);
}
for(k=0;k<7;k++)
{
x=random(15);
y=random(15);
shu(x,y,0);
}

heng(7,7,0);heng(8,7,0);/*终点处理*/
shu(7,7,0);;shu(7,8,0);

/*逐个开路*/
for(x=15;x>=0;x--)
for(y=0;y<=15;y++)
{
r=random(4)+1;/*产生四面墙壁开那一面的随即数——1,2,3,4 */
switch(r)
{
case 1:/*开上墙*/
if(y>=1)
{if(seewall(gezi[x][y],UP)==UP)
{heng(x,y-1,0);break;}/*注意break的位置*/
}
/*else:第0行 或 上墙已开的,改为开下墙(无break;)*/
case 2:/*开下墙*/
if(y<=14)
{if(seewall(gezi[x][y],DOWN)==DOWN)
{heng(x,y,0);break;}
}
else if(15==y)/*第15行,改为开上墙*/
{if(seewall(gezi[x][y],UP)==UP)
{heng(x,y-1,0);break;}
}
/*else:没开成功的,转入下面开墙(无break;)*/
case 3:/*开左墙*/
if(x>0)
{if(seewall(gezi[x][y],LEFT)==LEFT)
{shu(x-1,y,0);break;}
}
/*else:第0列 或 左墙已开的,改为开下墙(无break;)*/
case 4:/*开右墙*/
if(x<=14)
{if(seewall(gezi[x][y],RIGHT)==RIGHT)
{shu(x,y,0);break;}
}
else if(15==x)/*开左墙*/
{if(seewall(gezi[x][y],LEFT)==LEFT) /*如果左已开,无效*/
{ shu(x-1,y,0);break;}
}
default:break;
}
/*bug说明:当出现“回”字行通路的时候,回出现死胡同——这些小bug出现的概率不大,不再代码中处理;一旦遇到,重新生成迷宫即可*/
}/* end for */
for(x=1;x<=15;x++)
for(y=1;y<=15;y++)
{
if( (0==seewall(gezi[x-1][y-1],RIGHT))
&&(0==seewall(gezi[x-1][y-1],DOWN ))
&&(0==seewall(gezi[x][y-1] ,DOWN ))
&&(0==seewall(gezi[x-1][y] ,RIGHT))
)
{/*判断是否为孤独点,判断的基点是右下方的格子 gotoxy(0,0);printf("***%d %d***",x,y);
printf("%d,%d,%d,%d..",read(1,gezi[x-1][y-1]),read(3,gezi[x-1][y-1]),read(1,gezi[x][y-1]),re

ad(3,gezi[x-1][y]));*/
shu(x-1,y,1);
/*break; break;*/
}
}

heng(7,7,0);heng(8,7,0);/*终点处理*/
shu(7,7,0) ;shu(7,8,0);

/*防止终上方的孤独点*/
x=8;y=7;
if( (0==seewall(gezi[x-1][y-1],RIGHT))
&&(0==seewall(gezi[x-1][y-1],DOWN ))
&&(0==seewall(gezi[x][y-1] ,DOWN ))
&&(0==seewall(gezi[x-1][y] ,RIGHT))
)
{heng(x,y-1,1);}
/*防止终点下方的孤独点*/
x=8;y=9;
if( (0==seewall(gezi[x-1][y-1],RIGHT))
&&(0==seewall(gezi[x-1][y-1],DOWN ))
&&(0==seewall(gezi[x][y-1] ,DOWN ))
&&(0==seewall(gezi[x-1][y] ,RIGHT))
)
{shu(x-1,y,1);}

/* 所有mouse初始化 */
for(x=0;x<16;x++)
{
for(y=0;y<16;y++)
{mouse[x][y]=0x000F; /* 老鼠探测信息初始化为满墙*/}
}

test();/**/
start=0;
temptime=0;
}
/*******************************************************************************
** showmouse(x,y)画探路时的电脑鼠,及其路径痕迹
*******************************************************************************/
void showmouse(int x,int y,int color)
{
int xx=0,yy=0;
xx=(x)*X+Xfore+4;
yy=(y)*X+Yfore+4;
setcolor(YELLOW);
if(0==color) /*回退时用的颜色 */
{setfillstyle(1,DARKGRAY);}
else if(1==color)/*初次探测时用的颜色*/
{setfillstyle(1,YELLOW);}
bar(xx,yy,xx+X-8,yy+X-8);
}
/*******************************************************************************
** setxynow: 改写当前坐标
*******************************************************************************/
void setxynow(int fx)
{/*fx为前进方向标记变量,1234——上下左右*/
if (1==fx)
{ynow--;}
else if(2==fx)
{ynow++;}
else if(3==fx)
{xnow--;}
else if(4==fx)
{xnow++;}
road[xnow][ynow]=gezi[xnow][ynow];/*电脑鼠探测得当前gezi的墙壁信息*/
}
/*******************************************************************************
**runback():Mouse返航
**函数动作:把返航回来的路设为墙壁;
** mx,my回退入上一格子坐标,直至回到有未探测分支的分支点;
** 将mouse在屏幕上画出来;
*******************************************************************************/
void runback(uint32 it)
{
/*mx,my为电脑鼠当前所处位置的坐标(全局变量)*/
/*while(0==havenewroad(it))当没有发现新的未探测路径时,一直回退*/
{
if (1==read(4,it)) /*如果最初来自方向A */
{
setxynow(1); /*向上回退 */
/*heng(xnow,ynow,1); 来自向上返航,下面放墙*/
showmouse(xnow,ynow,0);
}
else if(1==read(5,it))
{
setxynow(2);
/*heng(xnow,ynow-1,1);来自向下返航,上面放墙*/
showmouse(xnow,ynow,0);
}
else if(1==read(6,it))
{
setxynow(3);
/*shu(xnow,ynow,1); 来自向左返航,右面放墙*/
showmouse(xnow,ynow,0);
}

else if(1==read(7,it))
{
setxynow(4);
/*shu(xnow-1,ynow,1); 来自向右返航,左面放墙*/
showmouse(xnow,ynow,0);
}
}
}
/*******************************************************************************
**step:走一步
**返回值说明:1234代表方向上下左右,走成功了返回相应方向值,不成功返回0
*******************************************************************************/
int step(int fx,uint32 it)/*fx表示方向ABCD-1234*/
{
/*-----------以下代码标记为分支点的格子-------------------------------------*/
if(1==ifbranch(it))/*检测是否为分支点*/
{
write1(8,&it); /*标记分支点*/
}
/*-----------以下代码使Mouse移动--------------------------------------------*/
if(0!=havenewroad(it))/*如果有未探测的相邻联通的格子*/
{
if(1==fx)/*方向为A*/
{
if(1==read(1,havenewroad(it)))/*上面有未被探测的通路*/
{/*确保为首次探测;注意:由于坐标已变,故这里不再用it,而用mouse[][]*/
if(1)
{
setxynow(1); /*上走*/
write1(5,&mouse[xnow][ynow]); /*标记最初来自下方 */
showmouse(xnow,ynow,1);
return(1);
}
else
{return(0);}
}
else
{return(0);}
}
else if(2==fx)
{
if(1==read(2,havenewroad(it)))
{
if(1)
{
setxynow(2);
write1(4,&mouse[xnow][ynow]);
showmouse(xnow,ynow,1); /*printf("(%d %d):%d ",xnow,ynow,mouse[xnow][ynow]);*/
return(1);
}
else
{return(0);}
}
else
{return(0);}
}
else if(3==fx)
{
if(1==read(3,havenewroad(it)))
{
if(1)/*--------------PROBLEM--------------*/
{
setxynow(3);
write1(7,&mouse[xnow][ynow]);
showmouse(xnow,ynow,1);
return(1);
}
else
{return(0);}
}
else
{return(0);}
}
else if(4==fx)
{
if(1==read(4,havenewroad(it)))
{
if(1)
{
setxynow(4);
write1(6,&mouse[xnow][ynow]);
showmouse(xnow,ynow,1);
return(1);
}
else
{return(0);}
}
else
{return(0);}
}
}
else/*如果没有未探测的联通邻格*/
{/*printf("back ");*/
runback(it);/*回退*/
}
}
/*******************************************************************************
** MouseGo:探路

,寻找终点 【可改进点:把下面重复的代码改为一个子函数】
*******************************************************************************/
void MouseGo(uint32 it)
{
if(xnow>=8 && ynow<=7)/*右上角1/4区域*/
{
if(xnow-8<=7-ynow)/*上半区*/
{
if(0==step(2,it))/*(1)向下走,不成功则执行下面的语句.注意:此处step()函数已执行*/
{
if(0==step(3,it))
{
if(0==step(1,it))
{step(4,it);}
}
}
}
else/*下半区*/
{
if(0==step(3,it))
{
if(0==step(2,it))
{
if(0==step(4,it))
{step(1,it);}
}
}
}
}
else if(xnow>=8 && ynow>=8)/*右下角1/4区域*/
{
if(xnow-8>=ynow-8)/*上半区*/
{
if(0==step(3,it))
{
if(0==step(1,it))
{
if(0==step(2,it))
{step(4,it);}
}
}
}
else/*下半区*/
{
if(0==step(1,it))
{
if(0==step(3,it))
{
if(0==step(2,it))
{step(4,it);}
}
}
}
}
else if(xnow<=7 && ynow<=7)/*左上角1/4区域*/
{
if(7-xnow<=7-ynow)/*上半区*/
{
if(0==step(2,it))
{
if(0==step(4,it))
{
if(0==step(3,it))
{step(1,it);}
}
}
}
else/*下半区*/
{
if(0==step(2,it))
{
if(0==step(4,it))
{
if(0==step(3,it))
{step(1,it);}
}
}
}
}
else if(xnow<=7 && ynow>=8)/*左下角1/4区域*/
{
if(7-xnow>=ynow-8)/*上半区*/
{
if(0==step(4,it))
{
if(0==step(1,it))
{
if(0==step(2,it))
{step(3,it);}
}
}
}
else/*下半区*/
{
if(0==step(1,it))
{
if(0==step(4,it))
{
if(0==step(3,it))
{step(2,it);}
}
}
}
}
}
/*******************************************************************************
** 寻找最短路径getshort()
*******************************************************************************/
void getshort(void)
{
char string[10];
int x,y,xx,yy;
int ups=255,downs=255,lefts=255,rights=255;/*四个存储可能的等高线值的变量*/
x=15;y=0;/*回到起点*/

shortroad[15][0]=0;
road[15][0]=gezi[15][0];
setcolor(BLUE);
spri

ntf(string,"%d",shortroad[x][y]);
setfillstyle(1,LIGHTGREEN);
bar(Xfore+x*X+5,Yfore+y*X+9,Xfore+x*X+X-5,Yfore+y*X+X-8);
outtextxy(Xfore+x*X+5,Yfore+y*X+10,string);
/*printf("%d %d %d %d;",x,y,(0==seewall(road[x][y],DOWN)),(shortroad[x][y+1]>shortroad[x][y]));*/
for(xx=15;xx>=0;xx--)
for(yy=0;yy<=15;yy++)
{
x=xx;y=yy;
while((0==seewall(road[x][y],UP)) && (shortroad[x][y-1]>shortroad[x][y]))/*上面无墙,且等高值大于本gezi*/
{
shortroad[x][y-1]=shortroad[x][y]+1;/*等高值上走*/
y--;
sprintf(string,"%d",shortroad[x][y]);
bar(Xfore+x*X+5,Yfore+y*X+9,Xfore+x*X+X-5,Yfore+y*X+X-8);
outtextxy(Xfore+x*X+5,Yfore+y*X+10,string);
}
x=xx;y=yy;
while((0==seewall(road[x][y],DOWN)) && (shortroad[x][y+1]>shortroad[x][y]))/*下面无墙,且等高值大于本gezi*/
{/*outtextxy(Xfore+x*X+5,Yfore+y*X+10,"a ");*/
shortroad[x][y+1]=shortroad[x][y]+1;/*等高值下走*/
y++;
sprintf(string,"%d",shortroad[x][y]);
bar(Xfore+x*X+5,Yfore+y*X+9,Xfore+x*X+X-5,Yfore+y*X+X-8);
outtextxy(Xfore+x*X+5,Yfore+y*X+10,string);
}
x=xx;y=yy;
while((0==seewall(road[x][y],LEFT)) && (shortroad[x-1][y]>shortroad[x][y]))/*左面无墙,且等高值大于本gezi*/
{
shortroad[x-1][y]=shortroad[x][y]+1;/*等高值左走*/
x--;
sprintf(string,"%d",shortroad[x][y]);
bar(Xfore+x*X+5,Yfore+y*X+9,Xfore+x*X+X-5,Yfore+y*X+X-8);
outtextxy(Xfore+x*X+5,Yfore+y*X+10,string);
}
x=xx;y=yy;
while((0==seewall(road[x][y],RIGHT)) && (shortroad[x+1][y]>shortroad[x][y]))/*右面无墙,且等高值大于本gezi*/
{
shortroad[x+1][y]=shortroad[x][y]+1;/*等高值右走*/
x++;
sprintf(string,"%d",shortroad[x][y]);
bar(Xfore+x*X+5,Yfore+y*X+9,Xfore+x*X+X-5,Yfore+y*X+X-8);
outtextxy(Xfore+x*X+5,Yfore+y*X+10,string);
}
/*printf("%d %d;",x,y);*/
}
temptime++;
if(temptime>=10)
{
if(shortroad[7][7]{
x=7;y=7;
}
else if(shortroad[7][8]{
x=7;y=8;
}
else if(shortroad[8][7]{
x=8;y=7;
}
else if(shortroad[8][8]{
x=8;y=8;
}/*printf("%d %d %d;",x,y,shortroad[x][y]);*/
for(xx=0;xx<=shortroad[x][y]+255;xx++)
{
ups=255;downs=255;lefts=2

55;rights=255;
if(0==seewall(road[x][y],UP) && (shortroad[x][y-1]{ups=shortroad[x][y-1]+1;}
if(0==seewall(road[x][y],DOWN) && (shortroad[x][y+1]{downs=shortroad[x][y+1]+1;}
if(0==seewall(road[x][y],LEFT) && (shortroad[x-1][y]{lefts=shortroad[x-1][y]+1;}
if(0==seewall(road[x][y],RIGHT) && (shortroad[x+1][y]{rights=shortroad[x+1][y]+1;}

setcolor(LIGHTRED);
setlinestyle(1,3,3);/*标记最短路径*/
rectangle(Xfore+x*X+5,Yfore+y*X+9,Xfore+x*X+X-5,Yfore+y*X+X-8);
if(x==15 && y==0) break;
if(ups<=downs &&ups<=lefts &&ups<=rights)/*取等高线最小值*/
{y--;}
else if(downs<=ups && downs<=lefts && downs<=rights)
{y++;}
else if(lefts<=ups && lefts<=downs && lefts<=rights)
{x--;}
else if(rights<=ups && rights<=downs && rights<=lefts)
{x++;}
}
}

}
/*******************************************************************************
** 响应鼠标左右键单击 MouseClick
*******************************************************************************/
void MouseClick(void)
{
int i,j;
setcolor(DARKGRAY);
if(regs.x.bx==1)/*菜单按钮响应鼠标左键单击*/
{
if(mousex>menuXa && mousexmenuYa1 &&mousey{menu1=1;menu2=0;/*printf("menu1 ");*/
setfillstyle(1,DARKGRAY);
fillellipse(menuXa+16,menuYa1+13,2,2);/*选择menu1*/
setfillstyle(1,WHITE);
setcolor(WHITE);
fillellipse(menuXa+16,menuYa2+13,2,2);/*取消选择menu2*/
}/*单击menu1*/
if(mousex>menuXa && mousexmenuYa2 &&mousey{menu1=0;menu2=1;/*printf("menu2 ");*/
setfillstyle(1,DARKGRAY);
fillellipse(menuXa+16,menuYa2+13,2,2);/*选择menu2*/
setfillstyle(1,WHITE);
setcolor(WHITE);
fillellipse(menuXa+16,menuYa1+13,2,2);/*取消选择menu1*/
}/*单击menu2*/
if(mousex>menuXa+25&&mousexmenuYa3&&mousey{
autoMG();/*重新生成迷宫*/
}
if(mousex>menuXa+25&&mousexmenuYa3+45&&mousey{
if(start==0)
{
xnow=15;ynow=0;
for(i=0;i<16;i++)
{
for(j=0;j<16;j++)
{
mouse[i][j]=gezi[i][j];
}
} /*老鼠探测信息*/
start=1;
}

/*while(!(((xnow==7)||(xnow==8))&&((ynow==7)||(ynow==8))))已修改为正常代码*/

/*for(i=0;i<16;i++)*/
/*for(j=0;j<16;j++)*/
{MouseGo(mouse[xnow][ynow]);}/*启动探路*/
}
if(mousex>menuXa+25&&mousexmenuYa3+45+45&&mousey{
getshort();/*寻找最短路径*/
}
}
if(mousex>Xfore&&mousex<(Xfore+X*N)&&mousey>Yfore&&mousey<(Yfore+X*N))/* 对迷宫范围内的鼠标左右键单击处理 */
{
if(regs.x.bx==1)/*响应鼠标左键单击,设置横墙*/
{
/* 画墙 */
i=(mousex-Xfore)/X;
j=(mousey-Yfore)/X;
if(menu1==1&&menu2==0)
{heng(i,j,0);}/* 左单击,menu1,去横墙 */
if(menu1==0&&menu2==1)
{heng(i,j,1);}/* 左单击,menu2,画横墙 */
}
if(regs.x.bx==2)/*响应鼠标右键单击,设置竖墙*/
{
/* 去墙 */
i=(mousex-Xfore)/X;
j=(mousey-Yfore)/X;
if(menu1==1&&menu2==0)
{shu(i,j,0);}/* 左单击,menu2,去竖墙 */
if(menu1==0&&menu2==1)
{shu(i,j,1);}/* 左单击,menu2,画竖墙 */
}
}
setlinestyle(0,0,1);
}
/*******************************************************************************
**主函数 main
*******************************************************************************/
int main()
{
int i,j; /* 循环变量 */
initgr(); /* BGI初始化 */
ground(0,0,X*N,X*N); /*画初始化迷宫*/

/* 所有gezi、mouse、map初始化 */
for(i=0;i<16;i++)
{
for(j=0;j<16;j++)
{
gezi[i][j] =0x000F; /*四周满墙 */
mouse[i][j]=0x000F; /*老鼠探测信息初始化为满墙 */
shortroad[i][j]=255; /*其等高线值全部初始化为255*/
}
}

/*
在这里读取文件里存储的迷宫环境
*/
autoMG();/*生成迷宫*/
showmouse(xnow,ynow,1);


while(1)
{
regs.x.ax=3;
int86(0x33,®s,®s);
drawmouse(mousex,mousey,0);
mousex=regs.x.cx;
mousey=regs.x.dx;

MouseClick();/*鼠标单击处理*/

drawmouse(mousex,mousey,1);/*画鼠标形状*/

if(kbhit())/* 退出程序 */
{
if(bioskey(0)==ESC) break; /* 按下ESC退出程序 */
if(bioskey(0)==BLANK)continue; /* 按下BLANK继续程序 */
}

}

getch(); /* 暂停一下,看看前面绘图代码的运行结果 */
closegr(); /* 恢复TEXT屏幕模式 */
return 0;
}


相关主题
文本预览
相关文档 最新文档