home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
047.lha
/
maze.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-11-20
|
9KB
|
397 lines
/* Original code by Eddie Shields from C64 */
/* Solve routine by David Flynn */
/* Intuition interface and rest by Charles J Carter */
/* Usage:
* Run Maze
* click LEFT mouse button on Make Maze; do NOT use front back gadget now
* When Maze is finished use front back gadget to get to CLI
* Run Lens
* Use front back gadget to get back to Maze; click left button to make active
* Object is to get from upper left hand corner to lower right hand corner
* Use cursor keys or Keypad 2,4,6,8 to move to next junction;
* Use Solve Maze to automatically solve maze; good for demo
* Use Quit or Close gadget to Quit
*/
#include <exec/types.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfxbase.h>
extern unsigned short rand();
extern long time();
#define DEPTH 2L
#define WIDTH 640L
#define HEIGHT 200L
#define TOP 8L
struct RastPort *rp;
long x,y;
int list[8];
#define INTUITION_REV 0L
#define GRAPHICS_REV 0L
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct NewWindow NewWindow = {
0,0,
640,200,
0,
1,
CLOSEWINDOW | MOUSEBUTTONS | RAWKEY,
WINDOWCLOSE | SMART_REFRESH | ACTIVATE |
WINDOWDEPTH | REPORTMOUSE | BORDERLESS,
NULL,
NULL,
(unsigned char *)" AMY MAZE | Quit | Make Maze | Solve Maze |",
NULL,
NULL,
0, 0,
640, 200,
WBENCHSCREEN,
};
/******************/
/* Main */
/******************/
extern struct IntuitionBase *OpenLibrary();
extern struct Window *OpenWindow();
extern struct IntuiMessage *GetMsg();
struct Window *win;
main(argc,argv)
int argc;
char *argv[];
{
struct IntuiMessage *NewMessage;
ULONG class;
USHORT code;
USHORT pix;
int dir,mx,my;
SHORT KeepGoing = TRUE;
IntuitionBase = OpenLibrary("intuition.library", INTUITION_REV);
if( IntuitionBase == NULL )
exit(FALSE);
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",GRAPHICS_REV);
if( GfxBase == NULL )
exit(FALSE);
if(( win = OpenWindow(&NewWindow) ) == NULL)
exit(FALSE);
rp=win->RPort;
while(KeepGoing)
{
Wait( 1L << win->UserPort->mp_SigBit);
while(NewMessage=GetMsg(win->UserPort))
{
class = NewMessage->Class;
code = NewMessage->Code;
mx = NewMessage->MouseX;
my = NewMessage->MouseY;
ReplyMsg( NewMessage );
if (class==CLOSEWINDOW) KeepGoing = FALSE;
if (class==MOUSEBUTTONS && code==SELECTUP)
{
if(my<TOP)
{
if(mx>115&&mx<368)
{
if (mx<172) KeepGoing = FALSE;
else if (mx<266) domaze();
else if (mx<368) solvemaze();
}
}
}
if (class==RAWKEY)
{
switch(code)
{
case 0x4c: case 0x3e: /* up */
if((pix=readpixel(rp->BitMap,x,y-1))==0)
{
SetAPen(rp,2L);
update(3);
writepixel(rp,x,y);
while((dir=findpath())!=-1)
{
update(dir);
writepixel(rp,x,y);
}
}
else if(pix==2||pix==1)
{
SetAPen(rp,1L);
writepixel(rp,x,y);
update(3);
}
break;
case 0x4d: case 0x1e: /* down */
if((pix=readpixel(rp->BitMap,x,y+1))==0)
{
SetAPen(rp,2L);
update(1);
writepixel(rp,x,y);
while((dir=findpath())!=-1)
{
update(dir);
writepixel(rp,x,y);
}
}
else if(pix==2||pix==1)
{
SetAPen(rp,1L);
writepixel(rp,x,y);
update(1);
}
break;
case 0x4f: case 0x2d: /* left */
if((pix=readpixel(rp->BitMap,x-1,y))==0)
{
SetAPen(rp,2L);
update(0);
writepixel(rp,x,y);
while((dir=findpath())!=-1)
{
update(dir);
writepixel(rp,x,y);
}
}
else if(pix==2||pix==1)
{
SetAPen(rp,1L);
writepixel(rp,x,y);
update(0);
}
break;
case 0x4e: case 0x2f: /* right */
if((pix=readpixel(rp->BitMap,x+1,y))==0)
{
SetAPen(rp,2L);
update(2);
writepixel(rp,x,y);
while((dir=findpath())!=-1)
{
update(dir);
writepixel(rp,x,y);
}
}
else if(pix==2||pix==1)
{
SetAPen(rp,1L);
writepixel(rp,x,y);
update(2);
}
break;
default:
break;
}
}
if((x==WIDTH-4)&&(y==HEIGHT-4)) domaze();
}
}
CloseWindow(win);
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
}
domaze()
{
long i;
srand((unsigned short)time());
SetDrMd(rp,JAM1);
SetRast(rp,3L);
RethinkDisplay();
SetAPen(rp,0L);
Move(rp,0L,TOP);
Draw(rp,WIDTH-2,TOP);
Draw(rp,WIDTH-2,HEIGHT-2);
Draw(rp,0L,HEIGHT-2);
Draw(rp,0L,TOP);
Move(rp,WIDTH-1,TOP);
Draw(rp,WIDTH-1,HEIGHT-1);
Draw(rp,0L,HEIGHT-1);
x = 2; y = TOP+2;
writepixel(rp,x,y);
do { sketch(); } while (backtrack());
SetAPen(rp,2L);
x = 2; y = TOP+2;
writepixel(rp,x,y);
}
solvemaze()
{
x = 2; y = TOP+2;
writepixel(rp,x,y);
while (solve()) backsolve();
}
sketch()
{
int dir;
SetAPen(rp,1L);
while ((dir = finddir())!=-1)
{
update(dir); writepixel(rp,x,y);
update(dir); writepixel(rp,x,y);
}
}
backtrack()
{
int dir;
SetAPen(rp,0L);
while (finddir() == -1)
{
if((dir = finddirback()) == -1) return(0);
writepixel(rp,x,y); update(dir);
writepixel(rp,x,y); update(dir);
}
return(1);
}
solve()
{
int dir;
SetAPen(rp,2L);
while ((dir = finddirsolve()) != -1)
{
update(dir); writepixel(rp,x,y);
update(dir); writepixel(rp,x,y);
if((x==WIDTH-4)&&(y==HEIGHT-4)) return(0);
}
return(1);
}
backsolve()
{
int dir;
SetAPen(rp,1L);
while (finddirsolve() == -1)
{
dir=finddirbacksolve();
writepixel(rp,x,y); update(dir);
writepixel(rp,x,y); update(dir);
}
}
finddir()
{
UWORD c = 0;
if(readpixel(rp->BitMap,x-2,y)==3) {list[c++]=0;list[c++]=0;list[c++]=0;}
if(readpixel(rp->BitMap,x,y+2)==3) list[c++]=1;
if(readpixel(rp->BitMap,x+2,y)==3) {list[c++]=2;list[c++]=2;list[c++]=2;}
if(readpixel(rp->BitMap,x,y-2)==3) list[c++]=3;
if(c==0)return(-1);
return(list[rand()%c]);
}
finddirback()
{
if(readpixel(rp->BitMap,x-1,y)==1) return(0);
if(readpixel(rp->BitMap,x,y+1)==1) return(1);
if(readpixel(rp->BitMap,x+1,y)==1) return(2);
if(readpixel(rp->BitMap,x,y-1)==1) return(3);
return(-1);
}
finddirsolve()
{
UWORD c = 0;
if(!readpixel(rp->BitMap,x-1,y)) list[c++]=0;
if(!readpixel(rp->BitMap,x,y+1)) list[c++]=1;
if(!readpixel(rp->BitMap,x+1,y)) list[c++]=2;
if(!readpixel(rp->BitMap,x,y-1)) list[c++]=3;
if(c==0)return(-1);
return(list[rand()%c]);
}
findpath()
{
UWORD c = 0;
if(!readpixel(rp->BitMap,x-1,y)) list[c++]=0;
if(!readpixel(rp->BitMap,x,y+1)) list[c++]=1;
if(!readpixel(rp->BitMap,x+1,y)) list[c++]=2;
if(!readpixel(rp->BitMap,x,y-1)) list[c++]=3;
if(c!=1)return(-1);
return(list[0]);
}
finddirbacksolve()
{
if(readpixel(rp->BitMap,x-1,y)==2) return(0);
if(readpixel(rp->BitMap,x,y+1)==2) return(1);
if(readpixel(rp->BitMap,x+1,y)==2) return(2);
if(readpixel(rp->BitMap,x,y-1)==2) return(3);
return(-1);
}
update(a)
int a;
{
if(a==0)--x; /* left */
else if(a==1)y++; /* down */
else if(a==2)x++; /* right */
else if(a==3)--y; /* up */
}
readpixel(bm,x,y)
struct BitMap *bm;
long x,y;
{
int color,p,bv;
UBYTE **plane;
UBYTE bit;
long offset;
offset = (x>>3)+(y*bm->BytesPerRow);
bit = 0x80>>(x&0x07);
plane = (UBYTE**)bm->Planes;
bv = 1;
color = 0;
for(p=bm->Depth;p;--p,bv<<=1,plane++)
if(*(*plane+offset)&bit) color+=bv;
return(color);
}
writepixel(rp,x,y)
struct RastPort *rp;
long x,y;
{
struct BitMap *bm;
int color,p,bv;
UBYTE **plane;
UBYTE bit;
long offset;
bm = rp->BitMap;
offset = (x>>3)+(y*bm->BytesPerRow);
bit = 0x80>>(x&0x07);
plane = (UBYTE**)&(bm->Planes[0]);
bv = 1;
color = rp->FgPen;
for(p=bm->Depth;p;--p,bv<<=1,plane++)
if(color&bv) *(*plane+offset)|=bit;
else *(*plane+offset)&=(~bit);
}