Je vais essayer le tri par tas dès que mes neurones seront d'accord

@+
PS: le code n'est pas encore optimisé..., si vous avez des idées

J'ai déjà supprimé la structure H (intermédiaire de calcul)
Code : Tout sélectionner
;************************
;essai algorithme A* tri par tas
;ECHAP ou click droit pour quitter
;auteur Huitbit
;utilisation de l'article "Pathfinding A* pour les débutants
;gestion du chemin le plus proche
;********************************
Enumeration
#spr_ecran
#spr_decor
#spr_mur
#spr_depart
#spr_arrivee
#spr_souris
#list_open
#list_closed
#list_mur
#list_chemin
EndEnumeration
Structure infos
mur.b
id.w
parent.w
f.w
g.w
list.b
EndStructure
Structure liste
id.w
f.w
EndStructure
#x_max=64
#y_max=64
#x_depart=8
#y_depart=8
#x_arrivee=56
#y_arrivee=56
Global Dim map.infos(#x_max-1,#y_max-1)
Global Dim liste_ouverte.liste((#x_max-1)*(#y_max-1))
Global position_premier_element.w
;dessin de la carte********************************
Procedure.b initialisation()
CreateSprite(#spr_ecran,1280,1024)
;traitement de l'image decor
StartDrawing(SpriteOutput(#spr_decor))
For j=0 To 63
For i=0 To 63
If Red(Point(i,j))=0
map(i,j)\mur=1
map(i,j)\list=#list_mur
EndIf
Next i
Next j
StopDrawing()
;grille
StartDrawing(SpriteOutput(#spr_ecran))
For j=1 To 62
For i=1 To 62
Line(16,j*16,62*16,0,RGB(100,100,100))
Line(16*i,16,0,62*16,RGB(100,100,100))
Next i
Next j
StopDrawing()
;affichage des murs, départ et arrivée
UseBuffer(#spr_ecran)
For j=0 To 63
For i=0 To 63
If map(i,j)\mur=1
DisplaySprite(#spr_mur,i*16,j*16)
EndIf
Next i
Next j
DisplaySprite(#spr_depart,#x_depart*16,#y_depart*16)
DisplaySprite(#spr_arrivee,#x_arrivee*16,#y_arrivee*16)
UseBuffer(-1)
;ID des cases
For j=0 To 63
For i=0 To 63
map(i,j)\id=k
k+1
Next i
Next j
EndProcedure
;calcul deH**************
Procedure.w manhattan(x.b,y.b)
resultat_manhattan.w=(Abs(x-#x_arrivee)+Abs(y-#y_arrivee))*10
ProcedureReturn resultat_manhattan
EndProcedure
;construction du tas****************
Procedure.w ajout_dans_liste_ouverte(p.w)
k.w=p
f_a_placer.w =liste_ouverte(p)\f
id.w=liste_ouverte(p)\id
While k>=(position_premier_element+1) And f_a_placer< liste_ouverte(Int(k*0.5))\f
liste_ouverte(k)\f=liste_ouverte(Int(k*0.5))\f
liste_ouverte(k)\id=liste_ouverte(Int(k*0.5))\id
k=Int(k*0.5)
Wend
liste_ouverte(k)\f=f_a_placer
liste_ouverte(k)\id=id
EndProcedure
;remaniement du tas après suppression de la racine************************
Procedure.w reformer_tas(p.w)
travail.b=0; 0 : en cours, 1 : effectué
k.w=position_premier_element
f_a_replacer.w= liste_ouverte(position_premier_element)\f
id.w=liste_ouverte(position_premier_element)\id
While travail=0 And 2*k<=p
If 2*k =p
indice_grand.w=p
Else
If liste_ouverte(2*k)\f<=liste_ouverte(2*k+1)\f
indice_grand=2*k
Else
indice_grand=2*k+1
EndIf
EndIf
If f_a_replacer>liste_ouverte(indice_grand)\f
liste_ouverte(k)\f=liste_ouverte(indice_grand)\f
liste_ouverte(k)\id=liste_ouverte(indice_grand)\id
k=indice_grand
Else
travail=1
EndIf
Wend
liste_ouverte(k)\f=f_a_replacer
liste_ouverte(k)\id=id
EndProcedure
;recherche du chemin*******************************
Procedure .w pathfinding(x.b,y.b)
f_min.w=manhattan(x,y)
id_f_min.w=map(x,y)\id
;étape n°1 ajout de la case de départ à la liste ouverte
liste_ouverte(1)\id=map(x,y)\id
liste_ouverte(1)\f=manhattan(x,y)
map(x,y)\list=#list_open
;étape n°2 boucle de recherche
position.w=1
position_premier_element=1
Repeat
;étape n°2.a choix case en cours
x_temp.b=liste_ouverte(position_premier_element)\id%#x_max
y_temp.b=Int(liste_ouverte(position_premier_element)\id/#x_max)
;étape n°2.b passage de la case en cours à la liste fermée
map(x_temp,y_temp)\list=#list_closed
liste_ouverte(position_premier_element)\f=0
position_premier_element=position_premier_element+1
Swap liste_ouverte(position_premier_element)\f,liste_ouverte(position)\f
Swap liste_ouverte(position_premier_element)\id,liste_ouverte(position)\id
reformer_tas(position)
;étape n°2.c exploration des huit cases adjacentes
For i= -1 To 1
For j=-1 To 1
If map(x_temp+i,y_temp+j)\list=0
map(x_temp+i,y_temp+j)\parent=map(x_temp,y_temp)\id
map(x_temp+i,y_temp+j)\g=map(x_temp,y_temp)\g+10+Abs(i*j)*4
map(x_temp+i,y_temp+j)\f=manhattan(x_temp+i,y_temp+j)+map(x_temp+i,y_temp+j)\g
map(x_temp+i,y_temp+j)\list=#list_open
position=position+1
liste_ouverte(position)\f=map(x_temp+i,y_temp+j)\f
liste_ouverte(position)\id=map(x_temp+i,y_temp+j)\id
ajout_dans_liste_ouverte(position)
ElseIf map(x_temp+i,y_temp+j)\list=#list_open
If map(x_temp+i,y_temp+j)\g > map(x_temp,y_temp)\g + 10+Abs(i*j)*4
map(x_temp+i,y_temp+j)\parent=map(x_temp,y_temp)\id
map(x_temp+i,y_temp+j)\g=map(x_temp,y_temp)\g+10+Abs(i*j)*4
map(x_temp+i,y_temp+j)\f=manhattan(x_temp+i,y_temp+j)+map(x_temp+i,y_temp+j)\g
EndIf
EndIf
Next j
Next i
;sauvegarde du f_min de la carte au cas où il n'y ait pas de chemin possible
If map(x_temp,y_temp)\f<f_min And map(x_temp,y_temp)\f<>0
f_min=map(x_temp,y_temp)\f
id_f_min=map(x_temp,y_temp)\id
EndIf
Until map(#x_arrivee,#y_arrivee)\list=#list_closed Or liste_ouverte(position_premier_element)\f=0
;3. enregistrement du chemin
x_parent.b=0
y_parent.b=0
;3.a. cas où il y a un chemin
If x_temp=#x_arrivee And y_temp=#y_arrivee
Repeat
map(x_temp,y_temp)\list=#list_chemin
x_parent=map(x_temp,y_temp)\parent%#x_max
y_parent=Int(map(x_temp,y_temp)\parent / #x_max)
x_temp=x_parent
y_temp=y_parent
Until map(x_temp,y_temp)\parent=0
;3.b. chemin le plus proche
Else
x_temp=id_f_min%#x_max
y_temp=Int(id_f_min/#x_max)
Repeat
map(x_temp,y_temp)\list=#list_chemin
x_parent=map(x_temp,y_temp)\parent%#x_max
y_parent=Int(map(x_temp,y_temp)\parent / #x_max)
x_temp=x_parent
y_temp=y_parent
Until map(x_temp,y_temp)\parent=0
EndIf
EndProcedure
;programme principal***********************
InitSprite()
InitKeyboard()
InitMouse()
OpenScreen(1280,1024,32,"algo_A*")
UsePNGImageDecoder()
;****************carte à explorer*****************************
LoadSprite(#spr_decor,"decor_7.png")
;**********************************************************************
;création des sprites****************
CreateSprite(#spr_mur,16,16)
StartDrawing(SpriteOutput(#spr_mur))
Box(0,0,16,16,RGB(100,100,100))
StopDrawing()
CreateSprite(#spr_depart,16,16)
StartDrawing(SpriteOutput(#spr_depart))
Box(0,0,16,16,RGB(0,255,0))
StopDrawing()
CreateSprite(#spr_arrivee,16,16)
StartDrawing(SpriteOutput(#spr_arrivee))
Box(0,0,16,16,RGB(0,255,255))
StopDrawing()
CreateSprite(#spr_souris,16,16)
StartDrawing(SpriteOutput(#spr_souris))
Box(0,0,16,16,RGB(255,0,255))
Box(0,0,6,6,RGB(255,255,0))
StopDrawing()
initialisation()
;temps pris pour la recherche du chemin
depart_chrono.f=ElapsedMilliseconds()
pathfinding(#x_depart,#y_depart)
duree_pathfinding.f=ElapsedMilliseconds() - depart_chrono
Repeat
Delay(10)
x_souris.b=Int(MouseX()/16)
y_souris.b=Int(MouseY()/16)
DisplaySprite(#spr_ecran,0,0)
StartDrawing(ScreenOutput())
DrawingMode(#PB_2DDrawing_Transparent)
FrontColor(RGB(255,255,255))
DrawText(0,0,"F= "+Str( map(x_souris,y_souris)\f) +" >>>>>>>>>>>>>>>>>>>>>chemin trouvé en "+Str(duree_pathfinding)+" ms")
DrawText(0,16,"G= "+Str(map(x_souris,y_souris)\g))
DrawText(0,32,"H= "+Str(manhattan(x_souris,y_souris)))
DrawText(0,48,"ID "+Str(map(x_souris,y_souris)\id))
DrawText(0,64,"parent= "+Str(map(x_souris,y_souris)\parent)+" xp="+Str(map(x_souris,y_souris)\parent%#x_max)+" yp="+Str(Int(map(x_souris,y_souris)\parent / #x_max)))
Select map(x_souris,y_souris)\list
Case #list_closed
texte$="closed"
Case #list_open
texte$="open"
Case #list_mur
texte$="mur"
Case 0
texte$="##"
EndSelect
DrawText(0,80,"list= "+texte$)
For j=0 To #y_max-1
For i=0 To #x_max-1
Select map(i,j)\list
Case #list_closed
textebis$=" c"
FrontColor(RGB(0,0,255))
DrawText(i*16,j*16,textebis$)
Case #list_open
textebis$=" o"
FrontColor(RGB(0,255,0))
DrawText(i*16,j*16,textebis$)
Case #list_chemin
textebis$=" x"
FrontColor(RGB(255,0,0))
DrawText(i*16,j*16,textebis$)
EndSelect
Next i
Next j
StopDrawing()
DisplayTransparentSprite(#spr_souris,16*Int(MouseX()/16)+8,16*Int(MouseY()/16)+8)
FlipBuffers()
ExamineKeyboard()
ExamineMouse()
Until KeyboardPushed(#PB_Key_Escape) Or MouseButton(#PB_MouseButton_Right )
End
Aaaaaaaa Gauntlet ! ça c'était du jeu ! J'ai fait les 255 premiers niveau sur Macintosh (on croyait que ça serait finit a 256 mais non....), j'y ai aussi beaucoup joué sur Amstrad ...mais la plus belle version reste l'original en Arcade. Pour trouver les sprites ça doit être possible en chechant sur le web. Si j'ai le temps je vais essayer de les retrouver, je crois que je les avaient vu une fois.Huitbit a écrit :@Thyphoon
Merci! L'"objectif"est encore très loin mais j'ai tout mon temps!
Pour les sprites j'aimerais du "topview"
Exemple(jeu MSX2 Bastard)
Après retouche et passage à 16 couleurs:
Le problème c'est que c'est long à faire!
Je compte un jour faire mes personnages en 3D et mettre la caméra au dessus!
Facile à dire mais je suis plus à l'aise avec un crayon HB qu'avec une souris!
En attendant, je cherche des sprites qui me serviront pour des test!
Les Artistes de Nintendo sont impressionnants dans le maniement du pixel! (même avec du 8*8, ils arrivent à faire des trucs!!!)
Il y a un jeu que je compte essayer, c'est Gauntlet
(je vais chercher la version Atari car je crois me souvenir que c'était la meilleure!)
Je trouverai bien un émulateur!
Ci-dessous : sprites Gauntlet version Nintendo(source The shy guy's kingdom)
c'est ce genre de sprites que je cherche, mais c'est une denrée très rare!
Hasta la vista et joyeuses Pâques!
Hé hé Mame... ça c'est un emulateur. j'ai une borne d'arcade chez moi qui tourne sous Mame ! Et un Frontend fait maison en Purebasic...Huitbit a écrit :@Comtois
Merci! Pour le jeu, c'est pas pour tout de suite![]()
En ce moment je fais mumuse avec MAME (un émulateur de borne d'arcade).
J'ai découvert (ou redécouvert certains jeux)
Heureusement que je dois pas mettre des "coins"!!!!!
Gaunlet, Goulsh'n ghosts.....
@+
J'vais essayer de chopper ça =].Utilise le programme de Comtois pour comprendre le fonctionnement du A*!
Bon courage !