je suis en train de faire un algo pour générer des labyrinthes, et je me retrouve bloqué par une ou deux erreurs bizarres ;'(
Le problème de ces erreurs est qu'elle ne sont pas systématiques, et que je n'ai pas réussi à mettre en évidence ce qui la provoquais.
le code est un peu long, mais je ne peux pas en enlever plus pour que le programme fonctionne normalement.
voici le code :
Code : Tout sélectionner
If InitSprite() = 0 Or InitKeyboard() = 0
End
EndIf
#w0 = 50
#h0 = 50
#d = 5
#w = (#w0 + 1) * #d
#h = (#h0 + 1) * #d
If OpenWindow(0, 0, 0, #d * #w0 + 1, #d * #h0 + 1 + 20, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
ProgressBarGadget(0, 0, WindowHeight(0) - 20, WindowWidth(0), 20, 0, 100)
If OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0) - 20, 0, 0, 0)
EndIf
EndIf
KeyboardMode(1)
; Dim laby(#w, #h)
Procedure Hazard(*point.POINT) ; retourne le point suivant, ou (-1, -1) si il n'est pas possible de trouver un point libre autour du point courant
fin = 0
a0 = 0
a1 = 0
a2 = 0
a3 = 0
NewList tab()
AddElement(tab())
tab() = 0
AddElement(tab())
tab() = 1
AddElement(tab())
tab() = 2
AddElement(tab())
tab() = 3
Repeat
SelectElement(tab(), Random(ListSize(tab()) - 1))
a = tab()
DeleteElement(tab())
If a = 0
If *point\x > 0
If Point(*point\x - #d, *point\y) = 0
*point\x = *point\x - #d
fin = 1
EndIf
EndIf
ElseIf a = 1
If *point\y > 0
If Point(*point\x, *point\y - #d) = 0
*point\y = *point\y - #d
fin = 1
EndIf
EndIf
ElseIf a = 2
If *point\x < #w - #d - 1
If Point(*point\x + #d, *point\y) = 0
*point\x = *point\x + #d
fin = 1
EndIf
EndIf
ElseIf a = 3
If *point\y < #h - #d - 1
If Point(*point\x, *point\y + #d) = 0
*point\y = *point\y + #d
fin = 1
EndIf
EndIf
EndIf
Until fin = 1 Or ListSize(tab()) = 0
If ListSize(tab()) = 0 And fin = 0
*point\x = -1
*point\y = -1
EndIf
EndProcedure
;{ initialisation
x = 0
y = -#d
debut = 0
mode = 0
ordre = 0
stop = 0
solve = 0
chrono = ElapsedMilliseconds()
start.POINT\x = 1
start.POINT\y = 1
goal.POINT\x = #d * ((#w - 1) / #d) - #d + 1
goal.POINT\y = #d * ((#h - 1) / #d) - #d + 1
nb_mur = 0
nb_max_mur = (#w0 - 1) * (#h0 - 1)
; ((pos_x - 1 + #d) / #d) * #d + 1 = x
;}
NewList carte.point()
Dim MemCarte(#w0, #h0)
;{ remplissage de la liste des positions : carte()
Repeat
event = WindowEvent()
ExamineKeyboard()
y + #d
If y > #h - #d - 1
y = 0
x + #d
EndIf
If x > #w - #d - 1
debut = 1
Else
AddElement(carte())
carte()\x = x
carte()\y = y
MemCarte(x / #d, y / #d) = @carte() ; récupéraiton des adresses mémoires de tout les éléments de la ligne chainée
SetGadgetState(0, 100 * ListSize(carte()) / #w0 / #h0)
EndIf
If KeyboardReleased(#PB_Key_Escape) : event = #PB_Event_CloseWindow : EndIf
Until event = #PB_Event_CloseWindow Or debut = 1
If event = #PB_Event_CloseWindow : End : EndIf
;}
x = 0
y = 0
Debug ListSize(carte())
Debug #w0 * #h0
Repeat
event = WindowEvent()
ExamineKeyboard()
;{ relance et recherche
If mode = 0 And ordre = 0 And stop = 0; relance
; selectionne un element de la liste au hazard et démarre un mur à partir des positions stockées dans la liste
;########################################
SelectElement(carte(), Random(ListSize(carte()) - 1)) ; Erreur beaucoup plus rare que l'autre : [ERREUR] Accès mémoire invalide. (erreur de lecture à l'adresse 1)
;########################################
x = carte()\x
y = carte()\y
mode = 1
EndIf
;}
;{ dessin et construction du labyrinthe
If stop = 0
If StartDrawing(ScreenOutput())
If debut = 1 ; tour blanc de l'ecran (contour du labyrinthe), nécessaire pour contenir les murs formés
LineXY(0, 0, #d * #w0, 0, #White)
LineXY(0, 0, 0, #d * #h0, #White)
LineXY(0, #d * #h0, #d * #w0, #d * #h0, #White)
LineXY(#d * #w0, 0, #d * #w0, #d * #h0, #White)
EndIf
; on cherche le point suivant du mur
point.POINT\x = x
point.POINT\y = y
Hazard(@point)
If point\x = -1 And point\y = -1 ; pas de point possibles --> le mur n'a nul part ou grandir --> on en crée un autre mais avant il faut supprimer la position courante (bloquée) de la liste des choix
mode = 0
ChangeCurrentElement(carte(), MemCarte(x / #d, y / #d)) ; on met l'element courant à l'élement qui a les bonnes coordonées (doit être en rapport avec le bug.
Debug "---"
Debug ListSize(carte())
Debug MemCarte(x/#d, y/#d)
Debug carte()
Debug "#"
Debug carte()\x
Debug carte()\y
Debug x
Debug x / #d
Debug y
Debug y / #d
;###########################
DeleteElement(carte(), 1) ; BUG étrange : [ERREUR] Accès mémoire invalide. (erreur de lecture à l'adresse 8)
;###########################
SetGadgetState(0, 100 * (#w0 * #h0 - ListSize(carte())) / #w0 / #h0) ; affichage de la progression
If ListSize(carte()) = 0 ; 1ère étape finie ^^, le reste viendras quand le bug seras corrigé
Debug nb_mur
Debug nb_max_mur
Debug StrD(100 * nb_mur / nb_max_mur, 1) + " %"
Debug #w0
Debug #h0
chrono = ElapsedMilliseconds() - chrono
Debug "stop - labyrinthe généré en : " + StrD(chrono / 1000, 3) + " s"
stop = 1
EndIf
Else ; sinon, on dessine le mur, et on passe au point suivant
LineXY(x, y, point\x, point\y, #White)
nb_mur + 1
x = point\x
y = point\y
EndIf
Box(start\x, start\y, #d - 1, #d - 1, #Red) ; position de départ (code qui s'en occupe supprimé pour la longueur)
Box(goal\x, goal\y, #d - 1, #d - 1, #Green) ; position d'arrivé
StopDrawing()
EndIf
EndIf
;}
FlipBuffers()
Until event = #PB_Event_CloseWindow Or KeyboardReleased(#PB_Key_Escape)
End