Pathfinding gesamt

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

Kabelbinder

Sieger des WM-Contest 2006

Betreff: Pathfinding gesamt

BeitragSa, Apr 14, 2007 13:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Auf das Prinzip dafür bin ich vorgestern oder so gekommen.
Das Programm geht im Grunde vor wie ein Suchtrupp. Es erkundet die gesamte Karte.
Sämtliche Pfade, die man gehen könnte werden erfasst und anschließend wir der kürzeste rausgesucht.

Probleme bekommt das Konzept wenn große Flächen durchsucht werden müssen denn durch solche Flächen kann man ja verschiedenst Pfade gehen. Ein besonderes Problem sind Wege, die zwei Tiles breit sind.

Die Maps könnt ihr selber erstellen:
Linke Maustaste : Grün (belaufbar)
Rechte " : Rot (nicht belaufbar)
Enter : Start setzen (blau)
rechtes Strg : Ziel setzen (gelb)

Die Maximallänge und maximalanzahl der Pfade kann man auch einstellen.
Im Debugmodus werden viele Sachen ausgegeben, darum ist es da ziemlich langsam. Ihr solltet es besser ohne Debug starten:

Code: [AUSKLAPPEN]
AppTitle "Pathfinding gesamt"
Graphics 640,480,16,2
SetBuffer BackBuffer()

Const max = 1500
Const le = 102

Dim map(15,11)

Dim path(max,le,4)

Global num,mx,my,startx,starty,zielx,ziely,ziel,mog

Function draw()
For y = 0 To 11
For x = 0 To 15

Select map(x,y)
Case 0
Color 180,0,0
Case 1
Color 0,180,0
End Select
Rect x*40,y*40,40,40

Color 0,0,0
Rect x*40,y*40,40,40,0
Next
Next

Color 0,0,180
Oval startx+10,starty+10,20,20

Color 180,180,0
Oval zielx+10,ziely+10,20,20

;Pfad zum Ziel zeichnen
Color 250,0,200
If ziel = -1 Then
Text 0,0,"Nicht möglich"
Else
For j = 0 To path(ziel,0,4)-1
Rect path(ziel,j,1)*40+19,path(ziel,j,2)*40+19,3,3
Next
EndIf

End Function

Function fill()
Repeat
mx = MouseX()
my = MouseY()

If MouseDown(1) Then map(mx/40,my/40)=1
If MouseDown(2) Then map(mx/40,my/40)=0
If KeyDown(28) Then
startx = mx/40*40
starty = my/40*40
EndIf
If KeyDown(157) Then
zielx = mx/40*40
ziely = my/40*40
EndIf
draw()

Flip
Cls
Until KeyHit(1)
FlushKeys()
End Function

Function doppelpunkt(x,y,p)
zwei = 0
For l = 0 To path(p,0,4)-1
If (path(p,l,1)=x) And (path(p,l,2)=y) Then
zwei = 1
Exit
EndIf
Next

Return zwei
End Function

Function create_path(x,y)
path(num,0,3)=1
path(num,0,1)=x
path(num,0,2)=y
path(num,0,4)=1

If num < max Then num = num + 1
End Function

Function addpoint(x,y,p)
If path(p,0,3)=1 Then

path(p,path(p,0,4),3)=1
path(p,path(p,0,4),1)=x
path(p,path(p,0,4),2)=y
path(p,0,4)=path(p,0,4)+1
 If path(p,0,4)>le Then
 path(p,0,4)=le
 discard_path(p)
 EndIf

EndIf
End Function

Function copy_path(n)
For b = 0 To le
For c = 1 To 4
path(num,b,c)=path(n,b,c)
Next
Next

If num < max Then num = num + 1
End Function

Function kill_path(pat)
For z = pat To max-1
For b = 0 To le
For c = 1 To 4
path(z,b,c)=path(z+1,b,c)
Next
Next
Next
num = num - 1
End Function

Function discard_path(pat)
path(pat,0,3)=2
End Function

Function pfadfinden(pa)
dirs = 0
o = 0
u = 0
l = 0
r = 0
pt = path(pa,0,4)-1
px=path(pa,pt,1)
py=path(pa,pt,2)

;Bei Ziel angekommen kann man aufhören
If (path(pa,pt,1)=zielx/40) And (path(pa,pt,2)=ziely/40) Then
discard_path(pa)
EndIf

If path(pa,0,3)=1 Then

;Wo ist ein freier Weg?
If px>0 Then
 If map(px-1,py)<>0 Then
 dirs = dirs + 1
 l = 1
 EndIf
EndIf
If px<15 Then
 If map(px+1,py)<>0 Then
 dirs = dirs + 1
 r = 1
 EndIf
EndIf
If py>0 Then
 If map(px,py-1)<>0 Then
 dirs = dirs + 1
 o = 1
 EndIf
EndIf
If py<11 Then
 If map(px,py+1)<>0 Then
 dirs = dirs + 1
 u = 1
 EndIf
EndIf

;War ich da schon?
If l = 1 Then
 If doppelpunkt(px-1,py,pa)=1 Then
 l = 0
 dirs = dirs - 1
 EndIf
EndIf
If r = 1 Then
 If doppelpunkt(px+1,py,pa)=1 Then
 r = 0
 dirs = dirs - 1
 EndIf
EndIf
If o = 1 Then
 If doppelpunkt(px,py-1,pa)=1 Then
 o = 0
 dirs = dirs - 1
 EndIf
EndIf
If u = 1 Then
 If doppelpunkt(px,py+1,pa)=1 Then
 u = 0
 dirs = dirs - 1
 EndIf
EndIf

;Kein Ausweg
If dirs = 0 Then
DebugLog "Kein Ausweg"
discard_path(pa)
EndIf

;Ein Ausweg
If dirs = 1 Then
DebugLog "Ein Ausweg"
If l = 1 Then addpoint(px-1,py,pa)
If r = 1 Then addpoint(px+1,py,pa)
If o = 1 Then addpoint(px,py-1,pa)
If u = 1 Then addpoint(px,py+1,pa)
EndIf

;Zwei Auswege
If dirs = 2 Then
 DebugLog "Zwei Auswege"
 
 ;Einen neuen Pfad eröffnen
     If l = 1 Then
  copy_path(pa)
  addpoint(px-1,py,num-1)
  l = 0
 ElseIf r = 1 Then
  copy_path(pa)
  addpoint(px+1,py,num-1)
  r = 0
 ElseIf o = 1 Then
  copy_path(pa)
  addpoint(px,py-1,num-1)
  o = 0
 ElseIf u = 1 Then
  copy_path(pa)
  addpoint(px,py+1,num-1)
  u = 0
  EndIf

 ;In die andere verbleibende Richtung weitergehen
 If l = 1 Then addpoint(px-1,py,pa)
 If r = 1 Then addpoint(px+1,py,pa)
 If o = 1 Then addpoint(px,py-1,pa)
 If u = 1 Then addpoint(px,py+1,pa)
EndIf

;Drei Auswege
If dirs = 3 Then
 DebugLog "Drei Auswege"
 
 ;Zwei neue Pfade eröffnen
 For m = 1 To 2
     If l = 1 Then
  copy_path(pa)
  addpoint(px-1,py,num-1)
  l = 0
 ElseIf r = 1 Then
  copy_path(pa)
  addpoint(px+1,py,num-1)
  r = 0
 ElseIf o = 1 Then
  copy_path(pa)
  addpoint(px,py-1,num-1)
  o = 0
 ElseIf u = 1 Then
  copy_path(pa)
  addpoint(px,py+1,num-1)
  u = 0
  EndIf
 Next

 ;In die andere verbleibende Richtung weitergehen
 If l = 1 Then addpoint(px-1,py,pa)
 If r = 1 Then addpoint(px+1,py,pa)
 If o = 1 Then addpoint(px,py-1,pa)
 If u = 1 Then addpoint(px,py+1,pa)
EndIf

;Vier Auswege
If dirs = 4 Then
 DebugLog "Vier Auswege"
 
 ;Drei neue Pfade eröffnen nach oben, rechts und unten
  copy_path(pa)
  addpoint(px+1,py,num-1)
  r = 0
  copy_path(pa)
  addpoint(px,py-1,num-1)
  o = 0
  copy_path(pa)
  addpoint(px,py+1,num-1)
  u = 0

 ;selbst nach links weitergehen
 addpoint(px-1,py,pa)
EndIf

EndIf

End Function

Function invade()
num = 0
ziel = -1

create_path(startx/40,starty/40)

;Wiederholen alle Pfade beendet wurden
Repeat
active = 0
For pf = 0 To max
;Wenn der erste Punkt existiert existiert aus der Pfad
If path(pf,0,3)=1 Then
DebugLog "Pfad "+Str$(pf)+":"
pfadfinden(pf)
active = active + 1
EndIf
Next

DebugLog ""
Until active = 0

mog = 0
short = 0
leng = 999
For i = 0 To max
If (path(i,0,3)=2) And (path(i,0,4)>0) Then
pl = path(i,0,4)

If (path(i,pl-1,1)=zielx/40) And (path(i,pl-1,2)=ziely/40) Then
 If pl<leng Then
 leng = pl
 short = i
 mog = 1
 EndIf
EndIf
EndIf
Next

If mog = 1 Then ziel = short
DebugLog "Ziel : "+Str$(ziel)

End Function

fill()

invade()
Repeat

draw()

Flip
Cls
Until KeyHit(1)
End
<Wing Avenger Download> ◊◊◊ <Macrophage Download>

StepTiger

BeitragSa, Apr 14, 2007 14:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Also bei mir hat es auch ganz gut mit 2 Strecken geklappt. A* ist trotzdem wahrscheinlich wesentlich schneller.
Noch gestern standen wir am Abgrund, doch heute sind wir schon einen Schritt weiter.
Computer:
AMD Sempron 3000+; ATI Radeon 9800 Pro; 512 MB DDR RAM 400Mhz; Asus E7N8X-E Deluxe; Samsung 200GB HD 5.4ns acces t
Gewinner: BP Code Compo #2
Π=3.141592653589793238...<--- und das aus dem kopf Laughing
Seit der Earthlings-Diskussion überzeugter Fleisch(fr)esser.

Smily

BeitragSa, Apr 14, 2007 15:50
Antworten mit Zitat
Benutzer-Profile anzeigen
afaik funktionier das Pathfinding-Tut auf blitzbase.de nach dem gleichen Prinzip.

Allerdings wird da bei wegen, die sich wahrscheinlich nicht lohnen auch nicht weitergesucht

Edit hab da mal was ausgegraben:

Code: [AUSKLAPPEN]
Type node
   Field x
   Field y
   Field parent
   Field cost
End Type

Type todo
   Field id
End type

Global sx = 50
Global sy = 50
Global fs = 20
Global stx = 20
Global sty = 25
Global zix = 30
Global ziy = 25
ftimer = CreateTimer(10)
Dim feld(sx,sy)

For y = 20 To 30
   feld(25,y) = 1
Next

Graphics (sx+1)*fs, (sy+1)*fs,16, 2
ClsColor 100,100,100
Repeat
notfound = 0
If stx = zix And sty = ziy Then ende("Ziel Erreicht")
createnode(stx,sty,0,0)
todo.todo = First todo
node.node = First node
Repeat
   If KeyHit(57) Then s = 1
   If KeyHit(1) Then End
   If s
      If best() = 0 Then notfound = 1 Exit
      todo.todo = object.todo(best())
      node.node = Object.node(todo\id)
      
      For difx = -1 To 1
         For dify = -1 To 1
            If Not nodeexist(node\x+difx,node\y+dify)
               If Not feld(node\x+difx,node\y+dify) createnode(node\x+difx,node\y+dify,todo\id,node\cost+abs(difx)+abs(dify))
            end if
         Next
      Next
      
      Delete todo.todo
   Else
      Gosub drawscreen
      Flip
   End If
   Until nodeexist(zix,ziy)
   
   Gosub drawscreen
   id = nodeexist(zix,ziy)
   node.node = Object.node(id)
   Color 255,0,0
   If notfound Then ende("Es gibt keinen Weg")
   If Not notfound
      Repeat
         node2.node = Object.node(node\parent)
         If Handle(node2) Line node\x*fs + fs/2,node\y*fs + fs/2, node2\x*fs + fs/2,node2\y*fs + fs/2
         oldnode.node = node.node
         node.node = node2.node
      Until node\x = stx And node\y = sty
   End if
   WaitTimer ftimer
   Flip
   stx = oldnode\x
   sty = oldnode\y
   Delete Each node
   Delete Each todo
Forever

end
.drawscreen
   cls
   For x = 0 To sx
      For y = 0 To sy
         If feld(x,y) Color 0,0,0 Else Color 200,200,200
         If stx = x And sty = y Color 255,0,0
         If zix = x And ziy = y Color 0,0,255
         Rect x*fs,y*fs,fs-1,fs-1
         If rectsoverlap(mousex(), MouseY(), 1, 1, x*fs,y*fs,fs,fs)
          Color 0,128,0: Rect x*fs,y*fs,fs-1,fs-1, 0
          If Mousedown(1) feld(x,y) = 1
          If MouseDown(2) feld(x,y) = 0
         End if
      Next
   Next
  Color 0,0,0
;
   For node.node = Each node
      gescost = node\cost + Abs(node\x-zix) + Abs(node\y-ziy)
    node2.node = Object.node(node\parent)
    Color 128,128,128
    If Handle(node2) Line node\x*fs + fs/2,node\y*fs + fs/2, node2\x*fs + fs/2,node2\y*fs + fs/2
    Color 0,0,0
    Text node\x*fs + fs/2, node\y*fs + fs/2, node\cost,1,1

   next
   
return

Function createnode(x,y,p,c,atdt=1)
   node.node = New node
   node\x = x
   node\y = y
   node\parent = p
   node\cost = c
   If atdt
      todo.todo = New todo
      todo\id = Handle(node)
   End If
   Return Handle(node)
End Function

Function best()
   bestcost = 10^5
   For todo.todo = Each todo
      node.node = Object.node(todo\id)
      gescost = node\cost + Abs(node\x-zix) + Abs(node\y-ziy)
   If gescost < bestcost Then bestcost = gescost: ret = Handle(todo)
   Next
   Return ret
End Function

Function nodeexist(x,y)
   If x < 0 Return -1
   If y < 0 Return -1
   If x > sx Return -1
   If y > sy Return -1
   For node.node = Each node
      If node\x = x And node\y = y Return Handle(node)
   next
End Function

Function ende(t$)
   Notify t$ ;Falls kein b+. diese Zeile auskommentieren oder mit Print ersetzen
   End
End function
Lesestoff:
gegen Softwarepatente | Netzzensur | brain.exe | Unabhängigkeitserklärung des Internets

"Wir müssen die Rechte der Andersdenkenden selbst dann beachten, wenn sie Idioten oder schädlich sind. Wir müssen aufpassen. Wachsamkeit ist der Preis der Freiheit --- Keine Zensur!"
stummi.org

Dottakopf

Betreff: nice

BeitragSa, Apr 14, 2007 19:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Bei smilys varriante hab ich so komische grafikfehler (benutze B3D).
Aber abgesehen davon scheint dieses system echt verdammt schnell zu sein! Respekt...

Ich hab mir natürlich auch die version von kabelbinder angeguckt. Und wie er schon selbst sagte : Bei doppel pfaden usw. kann es schon dauern.

Hab mal zum Scherz alle Flächen begehbar gemacht. (als ob es ne riesen wiese wäre..) ---> nach 5 min berechnungszeit hab ichs dan aufgeben Laughing

Aber nochmal respekt an beide ! Ich kann sowas nichtmal ansatzweise ^^

mfg Dottakopf
Rechtschreibfehler gelten der allgemeinen Belustigung!

Kabelbinder

Sieger des WM-Contest 2006

BeitragSa, Apr 14, 2007 22:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Hattest du den Debug modus an?
Bei mir dauert es wenn man alles freiräumt vom einen bis zum anderen Ende etwa 3 Sekunden. Und ich glaube nicht dass mein Computer 100 mal schneller ist als deiner Laughing .

Das Prgramm hat eigentlich gar nicht so lange Berechnungszeiten nach 4-5 Sekunden ist das bei mir fertig. Im schlimmsten Fall halt ohne Ergebnis.

Das Spiel Tempel des Elementaren Bösen hat auch irgend so'n langsaman Pathfinder. Da klick man irgendwo hin dan dauert das 3 Sekunden und dann rücken deine Chars dahin.
<Wing Avenger Download> ◊◊◊ <Macrophage Download>

Dottakopf

Betreff: Huch jetzt gehts !!!

BeitragSo, Apr 15, 2007 14:47
Antworten mit Zitat
Benutzer-Profile anzeigen
lol ??

habs jetzt nochmal reinkopiert , alle flächen gefärbt und tatsächlich max 3sek. berechnungszeit... ! Komisch ^^

Könnte es daran liegen, dass ich den ganzen tag schon mit bb gearbeitet hatte. Und etweilige bilder Speicher gefressen/belegt haben ? (benutze kein Freeimage am schluss).

Es könnte aber auch sein, dass wieder ein virenscan im hintergrund geloffen ist.... Und ich merk des immer nicht ^^

~Edit~ hab noch mal a wengle rumgespielt, und da ist mir das aufgefallen:
https://www.blitzforum.de/upload/file.php?id=1428
Warum ist dieser weg nicht möglich ? Bin ich blind ?

mfg Dottakopf
Rechtschreibfehler gelten der allgemeinen Belustigung!

Christoph

BeitragSo, Apr 15, 2007 15:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Könnte es daran liegen, dass ich den ganzen tag schon mit bb gearbeitet hatte. Und etweilige bilder Speicher gefressen/belegt haben ? (benutze kein Freeimage am schluss).


äh.......nein Smile

soweit ich weiß erledigt BB das Freiräumen nach Beenden des Programms automatisch...

pixelshooter

BeitragSo, Apr 15, 2007 17:00
Antworten mit Zitat
Benutzer-Profile anzeigen
eig erledigt windows das, um jetzt kleinlich zu sein Wink
>> Musikerstellung, Grafik und Design: http://www.pixelshooter.net.tc

Christoph

BeitragSo, Apr 15, 2007 17:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Hauptsache, irgendetwas macht's Wink

FireballFlame

BeitragSo, Apr 15, 2007 23:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Schade ^^ ... gleich mal drauflosgebaut und er findet meinen Weg nicht -.-
user posted image

Kabelbinder

Sieger des WM-Contest 2006

BeitragDi, Apr 17, 2007 16:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie gesagt, das Programm hat Probleme mit großen Flächen. Verändere die Größe der Felder im Programm und es funktioniert.

Edit: @ FireballFlame: Ich hab's mal nachgebaut und die Feldgröße verändert. Hat aber trotzdem nicht geklappt. Diese Karte ist für das Prgramm scheinbar nicht zu lösen. Wenn man ein paar mehr Steine einbaut, funktioniert es:
user posted image

Firstdeathmaker

BeitragDi, Apr 17, 2007 17:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Hmm, ist aber noch ziemlich langsam, der Code. Ich hab so etwas ähnliches mal in BMax geschrieben, aber nach dem ersten A-Stern Versuch es soweit optimiert dass ich, wenn ich es nun mit deinem Code vergleiche auf folgendes komme:

Testumgebung
Debugmode: Aus
Mapsize: 15x11
Zufällige Hinderniserstellung mit garantiertem Lösungsweg
Durgänge: 1000

Zeit pro Durchgang
Dein Code: 16,801 ms
Mein Code: 0,085 ms

Mein Code bei einer Map von 80x60 auf 1000 Durchgänge pro Durchgang: 11,5 ms


Du siehst, noch viel Optimierungsbedarf.

Mein Code
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon
Gewinner des BCC #57 User posted image

StepTiger

BeitragDi, Apr 17, 2007 18:48
Antworten mit Zitat
Benutzer-Profile anzeigen
wie misst du bruchteile von millisekunden?
Noch gestern standen wir am Abgrund, doch heute sind wir schon einen Schritt weiter.
Computer:
AMD Sempron 3000+; ATI Radeon 9800 Pro; 512 MB DDR RAM 400Mhz; Asus E7N8X-E Deluxe; Samsung 200GB HD 5.4ns acces t
Gewinner: BP Code Compo #2
Π=3.141592653589793238...<--- und das aus dem kopf Laughing
Seit der Earthlings-Diskussion überzeugter Fleisch(fr)esser.
 

Krümel

BeitragDi, Apr 17, 2007 23:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe meinen Pathfinder nach etwas tuning auf ca 6 ms bei einer Mapgröße von 150 x 150 gebracht.
(auf AMD 1800 MHz)

zur Funktion:

Am Anfang des Codes (Nachdem der Pathfinder mit Include "FindPath.bb"
eingebunden ist) muss der Pathfinder mit
InitMap(MapWidth , MapHeight)
initialisiert werden.

die Funktion FindPath(StartX,StartY, EndX,EndY)
sucht nach dem kürzesten Weg zwischen "Start" und "End" und
gibt die Länge des gefundenen Pfades zurück, oder 0 wenn kein Pfad
möglich ist.

Der Pfad wird im Array PathX(PathLength) , PathY(PathLength) abgespeichert.

Folgenden Teil als "FindPath.bb" speichern:

Code: [AUSKLAPPEN]

;PATHFINDER

Global MapWidth%
Global MapHeight%

Dim Map%(0 , 0)
Dim PathDir%(0 , 0)
Dim tmpPathX(0) , tmpPathY(0) , tmpPathD(0)
Dim PathX%(0) , PathY%(0)

Dim DirX%(8) , DirY%(8), DirN(8,8)
For t=1 To 8
   Read DirX(t),DirY(t)
Next
For t=1 To 8
   For d=1 To 8
      Read DirN(t,d)
   Next
Next
Data 1,0, 0,1, -1,0, 0,-1, 1,1, -1,1, -1,-1, 1,-1
Data 1,2,4,5,8,3,6,7 , 1,2,3,5,6,0,0,0 , 2,3,4,6,7,0,0,0 , 1,3,4,7,8,0,0,0
Data 1,2,5,6,8,0,0,0 , 2,3,5,6,7,0,0,0 , 3,4,6,7,8,0,0,0 , 1,4,5,7,8,0,0,0

Function FindPath(EndX,EndY , StartX,StartY)
   If (StartX = EndX) And (StartY = EndY) Return 0

   Dim PathDir(MapWidth , MapHeight)
   
   tmpPathX(0) = StartX
   tmpPathY(0) = StartY
   tmpPathD(0) = 1
   dCnt = 8
   Repeat
      NewPathCnt = CurrentPathCnt
      For c = OldPathCnt To CurrentPathCnt
         For d=1 To dCnt
            Dir = DirN(tmpPathD(c) , d)
            x = tmpPathX(c) + DirX(Dir)
            y = tmpPathY(c) + DirY(Dir)
            If (x >= 0) And (x < MapWidth) And (y >= 0) And (y < MapHeight)
               If (PathDir(x,y) = 0) And (Map(x,y) = 0)
                  If Not ( (Dir>4 And (Map(tmpPathX(c) , y)<>0 Or Map(x , tmpPathY(c)) <> 0)) )
                     PathDir(x , y) = Dir
                     If (x = EndX) And (y = EndY)
                        Repeat
                           Dir = PathDir(EndX , EndY)
                           EndX = EndX - DirX(Dir)
                           EndY = EndY - DirY(Dir)
                           PathX(PathLength) = EndX
                           PathY(PathLength) = EndY
                           PathLength = PathLength + 1
                        Until (EndX = StartX) And (EndY = StartY)
                        Return PathLength - 1
                     EndIf
                     NewPathCnt = NewPathCnt + 1
                     tmpPathX(NewPathCnt) = x
                     tmpPathY(NewPathCnt) = y
                     tmpPathD(NewPathCnt) = Dir
                  EndIf
               EndIf
            EndIf
         Next
      Next
      If NewPathCnt = CurrentPathCnt Return -1
      dCnt = 5
      OldPathCnt = CurrentPathCnt+1
      CurrentPathCnt = NewPathCnt
   Forever
End Function

Function InitMap(width , height)
   MapWidth = width
   MapHeight = height
   Dim Map(MapWidth , MapHeight)
   Dim PathX(MapWidth * MapHeight) , PathY(MapWidth * MapHeight)
   Dim tmpPathX(MapWidth * MapHeight) , tmpPathY(MapWidth * MapHeight)   , tmpPathD(MapWidth * MapHeight)
End Function


und ein Test dazu:
Code: [AUSKLAPPEN]

Include "FindPath.bb"
SeedRnd MilliSecs()

Graphics 600,600,16,2
SetBuffer BackBuffer()

Const MapCellSize=4

InitMap(150,150)

Global StartX=0
Global StartY=0
Global EndX=(MapWidth-1 )
Global EndY=(MapHeight-1)

While Not KeyHit(1)

   Color 255,255,255
   For y=0 To MapHeight-1
   For x=0 To MapWidth-1
      If Map(x,y)<>0 Rect x * MapCellSize , y * MapCellSize , MapCellSize , MapCellSize
   Next
   Next
 
   MouseGridX=Floor(MouseX() / MapCellSize) : If MouseGridX > MapWidth-1  MouseGridX = MapWidth-1
   MouseGridY=Floor(MouseY() / MapCellSize) : If MouseGridY > MapHeight-1 MouseGridY = MapHeight-1

   If KeyDown(57)
      If (oldX <> MouseGridX Or oldY <> MouseGridY)
         oldX=MouseGridX
         oldY=MouseGridY
         map( MouseGridX , MouseGridY ) = Not map( MouseGridX , MouseGridY )
      EndIf   
   Else
      If MouseDown(1)
         StartX = MouseGridX
         StartY = MouseGridY
      EndIf
      If MouseDown(2)
         EndX = MouseGridX
         EndY = MouseGridY
      EndIf
   EndIf   

   ms = MilliSecs()
   PathLength=FindPath(StartX,StartY, EndX,EndY)
   AppTitle "Map: " + MapWidth + " x " + MapHeight + "  " + (MilliSecs() - ms) + " ms "
   If PathLength >= 0
      Color 0,0,255
      For t=0 To PathLength
         Rect (PathX(t) * MapCellSize) , (PathY(t) * MapCellSize) , MapCellSize , MapCellSize
      Next
   EndIf
   
   Color 0,255,0 :   Rect StartX * MapCellSize,StartY * MapCellSize , MapCellSize , MapCellSize
   Color 255,0,0 :   Rect EndX   * MapCellSize,EndY   * MapCellSize , MapCellSize , MapCellSize   
   
   Color 255,255,255
   Text 0, 0 , "Linke  Maustaste - Startpunkt setzen"
   Text 0,15 , "Rechte Maustaste - Endpunkt setzen"
   Text 0,30 , "Leertaste + Maus - Wand zeichnen"   
      
   Flip 0
   Cls
Wend
End

Firstdeathmaker

BeitragMi, Apr 18, 2007 10:11
Antworten mit Zitat
Benutzer-Profile anzeigen
@ Steptiger "wie misst du bruchteile von millisekunden?" :
Ich lasse die Pathfinding Funktion 1000 Mal durchlaufen und dividiere die benötigte Zeit durch 1000. Dadurch bekommt man die ungefähre Durchschnittszeit.

@ Krümel:
Was wäre wenn du die Pathfinding Methode selber tunen würdest?
Ich meine die A* Methode funktioniert ja nach dem Prinzip das man jede Menge Wege bekommt die möglich sind, aber warum sollte man nicht einfach nur nach dem richtigen Weg suchen und alle anderen von vornherein verwerfen, und das eben Rundenweise? Also dass die Methode auf der Startposition anfängt und dort auf allen angrenzenden freien Felder ein Objekt (Type) erstellt und diese Felder als besetzt markiert, welches dann in der nächsten Runde dasselbe wieder tut und sich selbst löscht. In den neu erstellten Objekten wird aber der bisherige Pfad übergeben. Sobald ein Objekt auf der Zielposition liegt, gibt es den in sich gespeicherten Pfad zurück und beendet die Funktion. Dadurch hat man automatisch den kürzesten Weg herausgefunden ohne das man alle wirklich möglichen Möglichkeiten durchprobieren muss.
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon
Gewinner des BCC #57 User posted image
 

Krümel

BeitragMi, Apr 18, 2007 19:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo, Firstdeathmaker!

Im grunde hast du genau das beschrieben, was meine Funktion auch macht.
Nur das ich keine Types benutze weil mir diese zu langsam sind (habs ausprobiert).

[...aber warum sollte man nicht einfach nur nach dem richtigen Weg suchen und alle anderen von vornherein verwerfen...]

Normalerweise kennst Du den richtigen Weg ja noch nicht. Deshalb sucht der A* (meiner auch) nach allen möglichen Wegen. Die Suche bricht allerdings sofort ab, wenn das Ziel erreicht ist weil das dann mit Sicherheit auch der kürzeste Weg ist.
Der A* Algorithmus arbeitet allerdings zusätzlich noch mit einer Kostenschätzung. Dabei wird mit einer Heuristik nach jedem Suchschritt "geschätzt" wie teuer der Weg zum Ziel ist.
Ich habe aber in meinen Versuchen gemerkt, dass diese Kostenschätzung nicht immer von Nutzen ist (sich teilweise sogar negativ auf die Suchzeit auswirkt) und habe sie daher weggelassen.

Kabelbinder

Sieger des WM-Contest 2006

BeitragFr, Apr 20, 2007 11:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hatte zuerst auch den Programm-Abbruch auf das finden des Ziels gesetzt. Allerdings hatte ich dann nicht unbedingt immer den kürzesten Weg...
<Wing Avenger Download> ◊◊◊ <Macrophage Download>

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group