`Basic Setup
randomize timer()
sync on
sync rate 0
autocam off
disable escapekey
 
`Variables
repeat
   print "Must be odd."
   sync
   input "Width: ",width
until width>3 and width/2<>width/2.0
repeat
   print "Must be odd."
   sync
   input "Height: ",height
until height>3 and height/2<>height/2.0
`width=201
`height=201
depth=32
maxpoints=20
maxpathlen=width*height
`Setup for path finding
type node
   g as integer
   h as integer
   pdx as integer
   pdy as integer
   state as integer
endtype
global dim blocks(maxpoints/2,width,height) as node
 
`Setup for storing positions
type position
   x as integer
   y as integer
endtype
dim pos(maxpoints,2) as position
dim path_positions_list(maxpoints/2,maxpathlen) as position
 
`Setup for drawing
make memblock 1,width*height*depth*4+12
write memblock dword 1,0,width
write memblock dword 1,4,height
write memblock dword 1,8,depth
for x=1 to width-2
   for y=1 to height-2
      write memblock dword 1,(y*width+x)*4+12,rgb(255,255,255)
   next y
next x
for x=0 to width-1
   write memblock dword 1,x*4+12,rgb(0,0,0)
   write memblock dword 1,((height-1)*width+x)*4+12,rgb(0,0,0)
next x
for y=0 to height-1
   write memblock dword 1,y*width*4+12,rgb(0,0,0)
   write memblock dword 1,(y*width+width-1)*4+12,rgb(0,0,0)
next y
make image from memblock 1,1
sprite 1,0,0,1
size sprite 1,screen width(),screen height()
 
`Draw
repeat
   sync
   mclick=mouseclick()
   px=x
   py=y
   x=mousex()*(width+0.0)/screen width()
   y=mousey()*(height+0.0)/screen height()
   if mclick=1
      if clicking=1
         if px=x
            if py>y
               lowy=y
               highy=py
            else
               lowy=py
               highy=y
            endif
            for iy=lowy to highy
               write memblock dword 1,(iy*width+x)*4+12,rgb(0,0,0)
            next i
         else
            if abs((py-y+0.0)/(px-x+0.0))=<1
               m#=(py-y+0.0)/(px-x+0.0)
               if px>x
                  lowx=x
                  highx=px
               else
                  lowx=px
                  highx=x
               endif
               for ix=lowx to highx
                  iy=m#*(ix-x)+y
                  write memblock dword 1,(iy*width+ix)*4+12,rgb(0,0,0)
               next ix
            else
               m#=(px-x+0.0)/(py-y+0.0)
               if py>y
                  lowy=y
                  highy=py
               else
                  lowy=py
                  highy=y
               endif
               for iy=lowy to highy
                  ix=m#*(iy-y)+x
                  write memblock dword 1,(iy*width+ix)*4+12,rgb(0,0,0)
               next iy
            endif
         endif
      else
         write memblock dword 1,(y*width+x)*4+12,rgb(0,0,0)
      endif
      clicking=1
   endif
   if mclick=2 and clicking=0
      if checks/2=checks/2.0
         write memblock dword 1,(y*width+x)*4+12,rgb(255,0,0)
         inc p
         pos(p,1).x=x
         pos(p,1).y=y
      else
         write memblock dword 1,(y*width+x)*4+12,rgb(0,255,0)
         pos(p,2).x=x
         pos(p,2).y=y
      endif
      inc checks
      clicking=2
   endif
   if mclick=0
      clicking=0
   endif
   if spacekey()=1 and mazemade=0
      create_maze(width,height)
      mazemade=1
   endif
   make image from memblock 1,1
   if escapekey()=1
      end
   endif
until returnkey()=1 and checks=>2 and checks/2.0=checks/2
 
`Define world for path finding
for x=0 to width-1
   for y=0 to height-1
      if memblock dword (1,(y*width+x)*4+12)=rgb(0,0,0)
         blocks(0,x,y).state=1
      else
         blocks(0,x,y).state=-1
      endif
   next y
next x
 
dim success(p) as boolean
 
`Find path
for i=1 to p
   success(i)=find_path(i,pos(i,1).x,pos(i,1).y,pos(i,2).x,pos(i,2).y,width,height)
next i
 
`Draw path
color as dword
for i=1 to p
   if success(i)=1
      color=rgb(rnd(255),rnd(255),rnd(255))
      for i2=1 to path_positions_list(i,0).x
         write memblock dword 1,(path_positions_list(i,i2).y*width+path_positions_list(i,i2).x)*4+12,color
      next i2
   endif
next i
make image from memblock 1,1
sync
wait key
end
 
function find_path(pathnum,startx,starty,endx,endy,width,height)
for x=1 to width
   for y=1 to height
      blocks(pathnum,x,y).state=blocks(0,x,y).state
   next y
next x
blocks(pathnum,startx,starty).state=0
blocks(pathnum,startx,starty).g=0
blocks(pathnum,startx,starty).h=(abs(startx-endx)+abs(starty-endy))*10
blocks(pathnum,startx,starty).pdx=0
blocks(pathnum,startx,starty).pdy=0
repeat
   lowestf=999999
   fx=0
   fy=0
   for x=1 to width
      for y=1 to height
         if blocks(pathnum,x,y).state=0
            tempf=blocks(pathnum,x,y).g+blocks(pathnum,x,y).h
            if tempf<lowestf
               lowestf=tempf
               fx=x
               fy=y
            endif
         endif
      next y
   next x
   if lowestf=999999
      exitfunction 0
   endif
   for a=-1 to 1
      for b=-1 to 1
         n=abs(a)+abs(b)
         diagonal=int(n/2)
         if n=1
            mv=10
         endif
         if n=2
            mv=14
         endif
         if fx+a>-1 and fy+b>-1 and fx+a<width and fy+b<height
            if (blocks(pathnum,fx+a,fy+b).state=1)+(blocks(pathnum,fx+a,fy+b).state=0 and blocks(pathnum,fx+a,fy+b).g<blocks(pathnum,fx,fy).g+mv)+(diagonal=1 and blocks(pathnum,fx+a,fy).state=1)+(diagonal=1 and blocks(pathnum,fx+a,fy).state=1 or blocks(pathnum,fx,fy+b).state=1)=0
               blocks(pathnum,fx+a,fy+b).state=0
               blocks(pathnum,fx+a,fy+b).h=(abs(fx+a-endx)+abs(fy+b-endy))*10
               blocks(pathnum,fx+a,fy+b).g=blocks(pathnum,fx,fy).g+mv
               blocks(pathnum,fx+a,fy+b).pdx=a
               blocks(pathnum,fx+a,fy+b).pdy=b
            endif
         endif
      next b
   next a
   blocks(pathnum,fx,fy).state=1
   if escapekey()=1
      end
   endif
until blocks(pathnum,endx,endy).state=0
nx=endx
ny=endy
pathlen=0
repeat
   inc pathlen
   blocks(pathnum,nx,ny).state=2
   nx=nx-blocks(pathnum,nx,ny).pdx
   ny=ny-blocks(pathnum,nx,ny).pdy
   if escapekey()=1
      end
   endif
until nx=startx and ny=starty
nx=endx
ny=endy
path_positions_list(pathnum,0).x=pathlen
for i=1 to pathlen
   path_positions_list(pathnum,pathlen-i+1).x=nx
   path_positions_list(pathnum,pathlen-i+1).y=ny
   nx=nx-blocks(pathnum,nx,ny).pdx
   ny=ny-blocks(pathnum,nx,ny).pdy
next i
endfunction 1
 
`For those with short attention spans
function create_maze(xtiles,ytiles)
max=(xtiles*ytiles)-((xtiles-2)*(ytiles-2)-((xtiles-3)/2)*(ytiles-3))+2
local dim maze(xtiles,ytiles) as boolean
for x=1 to xtiles
   maze(x,1)=1
   maze(x,ytiles)=1
next x
for y=1 to ytiles
   maze(1,y)=1
   maze(xtiles,y)=1
next y
counter=2*xtiles+2*ytiles-2
while counter<max and escapekey()=0
   x=rnd(xtiles-2)+1
   y=rnd(ytiles-2)+1
   if maze(x-1,y-1)=1 and maze(x-1,y)+maze(x,y-1)=0 or maze(x-1,y+1)=1 and maze(x-1,y)+maze(x,y+1)=0 or maze(x+1,y-1)=1 and maze(x+1,y)+maze(x,y-1)=0 or maze(x+1,y+1)=1 and maze(x+1,y)+maze(x,y+1)=0 or maze(x,y)=1 or x/2.0=x/2 and y/2.0=y/2 or maze(x-1,y)+maze(x+1,y)+maze(x,y-1)+maze(x,y+1)<>1
   else
      maze(x,y)=1
      inc counter
   endif
endwhile
for x=0 to xtiles-1
   for y=0 to ytiles-1
      if maze(x+1,y+1)=1
         write memblock dword 1,(y*xtiles+x)*4+12,rgb(0,0,0)
      endif
   next y
next x
undim maze(0)
endfunction