Problème avec DeleteElement() dans un algo de Labyrinthe
Publié : mer. 13/oct./2010 16:25
Bonjour à tous !
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 :
Les deux problèmes doivent être liés. Mais je ne vois vraiment pas.
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