第1个回答 2008-01-30
我正好收藏了一个,拿出来给你:(在TC下调试通过)
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <graphics.h>
#include <bios.h>
#include <conio.h>
#include <dos.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define F9 0x43
#define Esc 0x1b
#define Del 0x53
#define Home 0x47
#define End 0x4f
#define Space 0x20
#define Up 0x48
#define Down 0x50
#define Left 0x4b
#define Right 0x4d
#define Enter 0x0d
#define BKCOLOR LIGHTBLUE
#define WALLCOLOR RED
#define CURSORCOLOR BLUE
#define CIRCLECOLOR CYAN
#define ERRORCOLOR CYAN
#define TEXTCOLOR 14
#define STACK_INIT_SIZE 200
#define STACKINCREMENT 10
typedef int Boolean;
typedef int Status;
typedef struct {
int x;
int y;
} PosType;
typedef struct {
int ord;
PosType seat;
int di;
} SElemType;
typedef struct {
int td;
int foot;
int mark;
} MazeType;
typedef struct {
SElemType *base;
SElemType *top;
int stacksize;
} Stack;
int Maze[16][17];
MazeType maze[16][17];
PosType StartPlace;
PosType EndPlace;
void Paint(void);
void CreatMaze(void);
void DrawWall(int cx,int cy,int color);
void DrawCursor(int cx,int cy,int color);
void Refresh(void);
void Error(char *message);
Status InitStack(Stack *s);
Status DestroyStack(Stack *s);
Status ClearStack(Stack *s);
Boolean StackEmpty(Stack *s);
int StackLength(Stack *s);
Status Push(Stack *s,SElemType e);
SElemType Pop(Stack *s,SElemType e);
Status GetTop(Stack *s,SElemType *e);
Status StackTraverse(Stack *s,Status (* visit)(SElemType *se));
Boolean Pass(PosType curpos);
void MarkPrint(PosType seat);
void FootPrint(PosType curpos);
PosType NextPos(PosType seat,int di);
Status MazePath(PosType start,PosType end);
void Paint(void)
{
int i,j;
int gdriver=DETECT,gmode;
initgraph(&gdriver,&gmode,".\\");
setbkcolor(LIGHTBLUE);
setcolor(10);
outtextxy(190,10,"MazePath Game");
setcolor(RED);
for(i=30;i<=450;i+=30)
line(30,i,480,i);
for(j=30;j<=480;j+=30)
line(j,30,j,450);
rectangle(29,29,481,451);
rectangle(28,28,482,452);
rectangle(490,320,630,470);
setcolor(1);
outtextxy(500,100,"Complete:F9");
outtextxy(500,120,"Start:Home");
outtextxy(500,140,"End:End");
outtextxy(500,160,"Draw wall:Enter");
outtextxy(500,180,"Delete wall:Del");
outtextxy(500,200,"Exit:Esc");
outtextxy(500,300,"Message:");
for(i=0;i<16;i++)
for(j=0;j<17;j++)
Maze[j][i]=0;
for(i=0;i<17;i++)
{
Maze[0][i]=1;
Maze[15][i]=1;
}
for(i=0;i<16;i++)
{
Maze[i][0]=1;
Maze[i][16]=1;
}
} /* Paint */
void DrawCursor(int cx,int cy,int color)
{
setcolor(color);
rectangle(cx-7,cy-7,cx+7,cy+7);
} /* DrawCursor */
void DrawWall(int x,int y,int color)
{
void DrawCursor(int cx,int cy,int color);
register int i;
setcolor(color);
x*=30; y*=30;
for(i=y;i<=y+30;i++)
line(x,i,x+30,i);
for(i=x;i<=x+30;i++)
line(i,y,i,y+30);
DrawCursor(x+15,y+15,CURSORCOLOR);
} /* DrawWall */
void Refresh(void)
{
register int i,j;
setcolor(BKCOLOR);
for(i=1;i<=480;i++)
line(1,i,480,i);
for(j=1;j<=480;j++)
line(i,1,i,480);
setcolor(WALLCOLOR);
rectangle(29,29,481,451);
rectangle(28,28,482,452);
rectangle(30,30,480,450);
for(i=1;i<=15;i++)
for(j=1;j<=14;j++)
if(Maze[j][i]) {
DrawWall(i,j,WALLCOLOR);
DrawCursor(i*30+15,j*30+15,WALLCOLOR);
}
setcolor(CIRCLECOLOR);
circle(StartPlace.x*30+15,StartPlace.y*30+15,6);
circle(EndPlace.x*30+15,EndPlace.y*30+15,6);
setcolor(BKCOLOR);
for(i=491;i<=629;i++)
line(i,321,i,469);
setcolor(BROWN);
setfillstyle(SOLID_FILL,BROWN);
fillellipse(StartPlace.x*30+15,StartPlace.y*30+15,6,6);
setcolor(CYAN);
setfillstyle(SOLID_FILL,CYAN);
fillellipse(EndPlace.x*30+15,EndPlace.y*30+15,6,6);
} /* Refresh */
void CreatMaze(void)
{
void Error(char *message);
char c;
int i,j;
Boolean flag=TRUE;
int x=1,y=1;
Boolean start=FALSE,end=FALSE;
DrawCursor(45,45,CURSORCOLOR);
do
{
c=getch();
switch(c)
{
case Up: if(y>1) {
if(!Maze[y][x])
DrawCursor(x*30+15,y*30+15,BKCOLOR);
else DrawCursor(x*30+15,y*30+15,WALLCOLOR);
DrawCursor(x*30+15,(--y)*30+15,CURSORCOLOR); }
break;
case Down: if(y<14) {
if(!Maze[y][x])
DrawCursor(x*30+15,y*30+15,BKCOLOR);
else DrawCursor(x*30+15,y*30+15,WALLCOLOR);
DrawCursor(x*30+15,(++y)*30+15,CURSORCOLOR); }
break;
case Left: if(x>1) {
if(!Maze[y][x])
DrawCursor(x*30+15,y*30+15,BKCOLOR);
else DrawCursor(x*30+15,y*30+15,WALLCOLOR);
DrawCursor((--x)*30+15,y*30+15,CURSORCOLOR); }
break;
case Right: if(x<15) {
if(!Maze[y][x])
DrawCursor(x*30+15,y*30+15,BKCOLOR);
else DrawCursor(x*30+15,y*30+15,WALLCOLOR);
DrawCursor((++x)*30+15,y*30+15,CURSORCOLOR); }
break;
case Home: if(!start&&!Maze[y][x]) {
setcolor(6);
setfillstyle(SOLID_FILL,6);
fillellipse(x*30+15,y*30+15,6,6);
start=TRUE; StartPlace.x=x;StartPlace.y=y; }
break;
case End: if(!end&&!Maze[y][x]) {
setcolor(CYAN);
setfillstyle(SOLID_FILL,CYAN);
fillellipse(x*30+15,y*30+15,6,6);
end=TRUE; EndPlace.x=x; EndPlace.y=y; }
break;
case Esc: setcolor(TEXTCOLOR);
outtextxy(540,380,"exit");
sleep(1);
closegraph();
exit(1);
case F9: if(start&&end) { Refresh(); flag=FALSE; }
else
{
setcolor(TEXTCOLOR);
outtextxy(493,323," Error: ");
outtextxy(493,343," You must set ");
if(!start) outtextxy(493,363," startplace. ");
else outtextxy(493,363," endplace.");
}
break;
case Enter: if(!(x==StartPlace.x&&y==StartPlace.y)&&
!(x==EndPlace.x&&y==EndPlace.y))
{
DrawWall(x,y,WALLCOLOR);
Maze[y][x]=1;
}
break;
case Del: DrawWall(x,y,BKCOLOR); setcolor(4);
rectangle(x*30,y*30,x*30+30,y*30+30);
Maze[y][x]=0;
if(x==StartPlace.x&&y==StartPlace.y)
{
StartPlace.x=0;
StartPlace.y=0;
start=FALSE;
}
if(x==EndPlace.x&&y==EndPlace.y)
{
EndPlace.x=0;
EndPlace.y=0;
end=FALSE;
}
break;
default: break;
}
}
while(flag);
for(i=0;i<17;i++)
for(j=0;j<16;j++)
{
maze[j][i].td=1-Maze[j][i];
maze[j][i].mark=0;
maze[j][i].foot=0;
}
} /* CreatMaze */
void Error(char *message)
{
closegraph();
fprintf(stderr,"Error:%s\n",message);
exit(1);
} /* Error */
Status InitStack(Stack *s)
{
s->base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!s->base) Error("Overflow");
s->top=s->base;
s->stacksize=STACK_INIT_SIZE;
return OK;
} /* InitStack */
Status DestroyStack(Stack *s)
{
s->top=NULL;
s->stacksize=0;
free(s->base);
s->base=NULL;
return OK;
} /* DestroyStack */
Status ClearStack(Stack *s)
{
s->top=s->base;
s->stacksize=STACK_INIT_SIZE;
return OK;
} /* ClearStack */
Boolean StackEmpty(Stack *s)
{
if(s->top==s->base) return TRUE;
else return FALSE;
} /* StackEmpty */
int StackLength(Stack *s)
{
if(s->top>s->base) return (int)(s->top-s->base);
else return 0;
} /* StackLength */
Status Push(Stack *s,SElemType e)
{
if(s->top-s->base>=s->stacksize)
{
s->base=(SElemType *)realloc(s->base,
(s->stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!s->base) Error("Overflow");
s->top=s->base+s->stacksize;
s->stacksize+=STACKINCREMENT;
}
*s->top++=e;
return OK;
} /* Push */
SElemType Pop(Stack *s,SElemType e)
{
if(s->top==s->base) Error("Pop");
e=*--s->top;
return e;
} /* Pop */
Status GetTop(Stack *s,SElemType *e)
{
if(s->top==s->base) Error("GetTop");
*e=*(s->top-1);
return OK;
} /* GetTop */
/*Status StackTraverse(Stack *s,Status (* visit)(SElemType *se))
{
SElemType p;
int result;
if(s->top==s->base) return ERROR;
p=s->base;
while(!(p==s->top))
{
result=(*visit)(p);
p++;
}
return OK;
} */
Boolean Pass(PosType curpos)
{
if(maze[curpos.x][curpos.y].td==1&&
maze[curpos.x][curpos.y].foot==0&&maze[curpos.x][curpos.y].mark==0)
return TRUE;
else return FALSE;
} /* Pass */
void MarkPrint(PosType seat)
{
maze[seat.x][seat.y].mark=-1;
} /* MarkPrint */
void FootPrint(PosType curpos)
{
maze[curpos.x][curpos.y].foot=1;
} /* FootPrint */
PosType NextPos(PosType seat,int di)
{
switch(di)
{
case 1: seat.y++; return seat;
case 2: seat.x++; return seat;
case 3: seat.y--; return seat;
case 4: seat.x--; return seat;
default: seat.x=0; seat.y=0; return seat;
}
} /* NextPos */
Status MazePath(PosType start,PosType end)
{
PosType curpos;
int curstep;
SElemType e;
Stack *s=NULL,stack;
stack.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!stack.base) Error("Overflow");
stack.top=stack.base;
stack.stacksize=STACK_INIT_SIZE;
s=&stack;
curpos=start;
curstep=1;
do
{
if(Pass(curpos))
{
FootPrint(curpos);
e.ord=curstep; e.seat=curpos; e.di=1;
setcolor(BLUE);
circle(curpos.y*30+15,curpos.x*30+15,6);
delay(8000);
Push(s,e);
if(curpos.x==end.x&&curpos.y==end.y)
{
DestroyStack(s);
return TRUE;
}
curpos=NextPos(curpos,1);
curstep++;
}
else
{
if(!StackEmpty(s))
{
e=Pop(s,e);
while(e.di==4&&!StackEmpty(s))
{
MarkPrint(e.seat);
setcolor(BLUE);
circle(e.seat.y*30+15,e.seat.x*30+15,6);
delay(8000);
setcolor(BKCOLOR);
circle(e.seat.y*30+15,e.seat.x*30+15,6);
e=Pop(s,e);
curstep--;
}
if(e.di<4)
{
e.di++;
Push(s,e);
curpos=NextPos(e.seat,e.di);
}
}
}
}
while(!StackEmpty(s));
DestroyStack(s);
return FALSE;
} /* MazePath */
void main(void)
{
PosType start,end;
Paint();
CreatMaze();
start.x=StartPlace.y;
start.y=StartPlace.x;
end.x=EndPlace.y;
end.y=EndPlace.x;
if(MazePath(start,end))
{
setcolor(TEXTCOLOR);
outtextxy(520,380,"Path found");
}
else
{
setcolor(TEXTCOLOR);
outtextxy(500,380,"Path not found");
}
while(bioskey(1)==0);
}