About Monkey 2 › Forums › Monkey 2 Code Library › Brute Force Pathfinding
This topic contains 1 reply, has 2 voices, and was last updated by
cocon 1 year, 3 months ago.
-
AuthorPosts
-
January 6, 2018 at 3:54 pm #12706
I wanted to try and see if this would work.
What I did here is create a pathfinding routine that works by creating every possible path starting at size 0 growing until the path is found. Because it grows, the first valid path will be the shortest. It seems to work on my laptop on small maps. 8×8 size.
I find it difficult to explain how it works but maybe the code will speak for itself.
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187#Import "<std>"#Import "<mojo>"Using std..Using mojo..' Large maps require super CPU!! (2020)Global mapwidth:Int=8Global mapheight:Int=8Global tilewidth:Int,tileheight:IntGlobal maxpathlen:Int=25Global path:Int[] = New Int[maxpathlen]Global map:Int[,]Class MyWindow Extends WindowField sx:Int,sy:IntField ex:Int,ey:IntField ms:IntField pathed:Bool=FalseMethod New()tilewidth=Width/mapwidthtileheight=Height/mapheightsx = 2sy = 2ex = 7ey = 7map = New int[mapwidth,mapheight]End MethodMethod OnRender( canvas:Canvas ) OverrideApp.RequestRender() ' Activate this methoddrawgrid(canvas)If pathed = True Then drawpath(canvas)If Keyboard.KeyReleased(Key.Space)path = New Int[maxpathlen]For Local i:Int=0 Until maxpathlenpath[i]=-1Nextms = Millisecs()RepeatLocal s:Bool=pathfound()If s=True ThenPrint Millisecs()-mspathed = TrueExitEnd Ifincpath()' timeout after xxxxx millisecsIf ms+10000<Millisecs() ThenPrint "failed - timeout"pathed=FalseExitEnd IfForeverEnd IfLocal tx:Int=Mouse.X/tilewidthLocal ty:Int=Mouse.Y/tileheightIf Mouse.ButtonReleased(MouseButton.Middle)If tx=sx And ty=sy Or tx=ex And ty=syElseIf map[tx,ty] = 1map[tx,ty] = 0Elsemap[tx,ty] = 1End IfEnd ifEnd IfIf Mouse.ButtonReleased(MouseButton.Left)If map[tx,ty] = 0sx = txsy = typathed=FalseEnd IfEnd IfIf Mouse.ButtonReleased(MouseButton.Right)If map[tx,ty] = 0ex = txey = typathed=FalseEnd IfEnd Ifcanvas.Color = Color.Blackcanvas.DrawText("LMB(start)/RMB(end)/SPACE(findpath)MMB(wall)",0,0)If Keyboard.KeyReleased(Key.Escape) Then App.Terminate()End MethodMethod pathfound:Bool()Local cx:Int=sxLocal cy:Int=syFor Local i:Int=maxpathlen-1 Until 0 Step -1Select path[i]Case 0'upcy-=1Case 1'rightcx+=1Case 2'downcy+=1Case 3'leftcx-=1Default'exitReturn FalseEnd SelectIf cx<0 Or cx>=mapwidth Or cy<0 Or cy>=mapheight Then Return FalseIf map[cx,cy] = 1 Then Return FalseIf ex = cx And ey = cy ThenReturn TrueEndifNextReturn FalseEnd MethodMethod incpath()path[maxpathlen-1]+=1For Local i:Int=maxpathlen-1 Until 1 Step-1If path[i] > 3 Thenpath[i] = 0path[i-1] += 1EndifNextEnd MethodMethod drawgrid(canvas:Canvas)For Local y:Int=0 Until mapheightFor Local x:Int=0 Until mapwidthcanvas.Color = Color.Blackcanvas.DrawRect(x*tilewidth,y*tileheight,tilewidth,tileheight)canvas.Color = Color.Whitecanvas.DrawRect(x*tilewidth+1,y*tileheight+1,tilewidth-1,tileheight-1)If map[x,y] = 1 Thencanvas.Color = Color.Magentacanvas.DrawRect(x*tilewidth,y*tileheight,tilewidth,tileheight)End IfIf x=sx And y = sy Thencanvas.Color = Color.Greencanvas.DrawRect(x*tilewidth,y*tileheight,tilewidth,tileheight)canvas.Color = Color.Redcanvas.DrawText("start LMB",x*tilewidth,y*tileheight)End IfIf x=ex And y = ey Thencanvas.Color = Color.Yellowcanvas.DrawRect(x*tilewidth,y*tileheight,tilewidth,tileheight)canvas.Color = Color.Redcanvas.DrawText("end RMB",x*tilewidth,y*tileheight)End IfNextNextEnd MethodMethod drawpath(canvas:Canvas)canvas.Color = Color.RedLocal cx:Int=sxLocal cy:Int=syFor Local i:Int=maxpathlen-1 Until 0 Step -1Select path[i]Case 0'upcy-=1Case 1'rightcx+=1Case 2'downcy+=1Case 3'leftcx-=1End Selectcanvas.DrawCircle(cx*tilewidth+tilewidth/2,cy*tileheight+tileheight/2,10)If ex = cx And ey = cy ThenReturnEndifNextEnd MethodEnd ClassFunction Main()New AppInstanceNew MyWindowApp.Run()End FunctionHere a emscripten page showing the code.
https://cromdesi.home.xs4all.nl/emscripten/bruteforcepathfinding/Untitled1.html
January 6, 2018 at 7:31 pm #12714Good one, it can be combined it with my multi loops here, this will allow the CPU to rest a few times.
-
AuthorPosts
You must be logged in to reply to this topic.