Labyrinthe en mode console simple

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Labyrinthe en mode console simple

Message par Huitbit »

Image

Code : Tout sélectionner

;********************************************
;*labyrinthe en mode console simple(pas graphique)   *
;*purebasic version 4                                               *
;********************************************
;déclarations
Global  x_case.l, y_case.l, x_case_max.l, y_case_max.l, compteur_case_sol_visite.l , max_compteur_case_sol_visite.l,a.f,x_new.l,y_new.l
x_case_max=70
y_case_max=22
max_compteur_case_sol_visite=x_case_max*y_case_max*0.25
compteur_case_sol_visite=0
Enumeration
#case_mur
#case_sol
#case_sol_visite
#case_bordure
#entree
#sortie
EndEnumeration
Structure laby
valeur.b
tuile.s
EndStructure
Global Dim kaz.laby(x_case_max,y_case_max)
Global Dim memo_x_case.l(x_case_max,y_case_max)
Global Dim memo_y_case.l(x_case_max,y_case_max)
Global Dim nombre_possibilites.l(x_case_max,y_case_max)


Procedure.l initialisation()
;remplissage du tableau kaz(x_case,y_case)
For j=0 To y_case_max
    For i= 0 To x_case_max  
       If i % 2 = 1 And j % 2 = 1 
           kaz(i,j)\valeur=#case_sol
       ElseIf i=0 Or i=x_case_max Or j=0 Or j=y_case_max
           kaz(i,j)\valeur=#case_bordure
       Else     
           kaz(i,j)\valeur=#case_mur
       EndIf
    Next i
Next j
;choix d'une case de départ
Repeat
    x_case=1+Random(x_case_max-2)
    y_case=1+Random(y_case_max-2)
Until  x_case%2=1 And y_case%2=1 
 EndProcedure
 
 Procedure.l possibilite(xp.l,yp.l)
 nombre_possibilites(xp,yp)=0
If xp>0 And (yp-2)>0 And  xp<x_case_max And (yp-2)<y_case_max And kaz(xp,yp-2)\valeur=#case_sol
    nombre_possibilites(xp,yp)=nombre_possibilites(xp,yp)+1
EndIf 
If (xp+2)>0 And yp>0 And  (xp+2)<x_case_max And yp<y_case_max And kaz(xp+2,yp)\valeur=#case_sol
    nombre_possibilites(xp,yp)=nombre_possibilites(xp,yp)+1
EndIf 
If xp>0 And (yp+2)>0 And  xp<x_case_max And (yp+2)<y_case_max And kaz(xp,yp+2)\valeur=#case_sol
    nombre_possibilites(xp,yp)=nombre_possibilites(xp,yp)+1
EndIf 
If (xp-2)>0 And yp>0 And  (xp-2)<x_case_max And yp<y_case_max And kaz(xp-2,yp)\valeur=#case_sol
    nombre_possibilites(xp,yp)=nombre_possibilites(xp,yp)+1
EndIf 
 EndProcedure
 
Procedure.l construction(x.l,y.l)
If  memo_x_case(x,y)=0
    memo_x_case(x,y)=x
    memo_y_case(x,y)=y
    kaz(memo_x_case(x,y),memo_y_case(x,y))\valeur=#case_sol_visite
    compteur_case_sol_visite=compteur_case_sol_visite+1
EndIf
 x_new_old=memo_x_case(x,y)
 y_new_old=memo_y_case(x,y)
Repeat
    Repeat
        a=Random(3)*#PI*0.5 ;angle â choix de la direction du foret
        x_new=x_new_old+2*Cos(a)
        y_new=y_new_old+2*Cos(a+#PI/2)
    Until   x_new>0 And y_new>0 And x_new<x_case_max And y_new<y_case_max And kaz(x_new,y_new)\valeur=#case_sol
    kaz(x_new,y_new)\valeur=#case_sol_visite
    memo_x_case(x_new,y_new)=x_new
    memo_y_case(x_new,y_new)=y_new
    x_cloison.l=(x_new_old+x_new)*0.5
    y_cloison.l=(y_new_old+y_new)*0.5
    kaz(x_cloison,y_cloison)\valeur=#case_sol_visite
    compteur_case_sol_visite=compteur_case_sol_visite+1
    possibilite(x_new,y_new)
    x_new_old=x_new
    y_new_old=y_new
Until nombre_possibilites(x_new_old,y_new_old)=0
possibilite(memo_x_case(x,y),memo_y_case(x,y))
If nombre_possibilites(memo_x_case(x,y),memo_y_case(x,y))>0 
    construction(memo_x_case(x,y),memo_y_case(x,y)) 
EndIf
EndProcedure

;programme principal
initialisation()
Repeat
construction(x_case,y_case)
If compteur_case_sol_visite<>max_compteur_case_sol_visite
    Repeat
        x_case=1+Random(x_case_max-2)
        y_case=1+Random(y_case_max-2)
        possibilite(x_case,y_case )
    Until  x_case%2=1 And y_case%2=1    And  kaz(x_case,y_case)\valeur=#case_sol_visite And nombre_possibilites(x_case,y_case )>0
 EndIf
Until  compteur_case_sol_visite=max_compteur_case_sol_visite
;création de l'entrée et de la sortie
kaz(0,1+2*Random(y_case_max*0.5-1))\valeur=#entree
kaz(x_case_max,1+2*Random(y_case_max*0.5-1))\valeur=#sortie

OpenConsole()
Delay(1)
For j=0 To y_case_max
   For i= 0 To x_case_max
       Select kaz(i,j)\valeur
           Case #case_mur
           kaz(i,j)\tuile=Chr(219)  
           Case #case_sol
           kaz(i,j)\tuile=Chr(255) 
           Case #case_sol_visite
           kaz(i,j)\tuile=Chr(250) 
           Case #case_bordure
           kaz(i,j)\tuile=Chr(177) 
           Case #entree
           kaz(i,j)\tuile="E"
           Case #sortie
           kaz(i,j)\tuile="S"
       EndSelect
       Print(kaz(i,j)\tuile)
   Next i
   PrintN("")
Next j
Input()
CloseConsole()
End
Après avoir lu un article de wikipedia, j'ai voulu mettre ça en application!
Un labyrinthe vrai est un labyrinthe où toutes les cellules sont connectées.
Comme le mode console est tendance en ce moment :lol: ...
J'ai donc crée un bâtiment avec des pièces isolées(procedure initialisation), puis choisi une pièce de départ.
Ensuite je passe de pièces en pièces tant que c'est possible( procédure construction).
Quand ce n'est plus possible, je reviens à la pièce de départ(récursivité!), si ce n'est toujours pas possible, je me raccorde n'importe où sur un couloir(programme principal) et je continue.

Remarque:
je pense qu'on peut faire sans récursivité mais comme je trouve ça étonnant...
Si quelqu'un a déjà essayé, ça m'intèresse de voir un code "propre" et optimisé!


Question: j'utilise la procédure "possibilité" pour tester les pièces voisines, cette dernière me renvoie la variable "nombre_possibilites"
C'est un peu lourd :? Est-ce possible de ce débarrasser de cet intermédiaire?

Idée: quand la matrice est calculée, on peut mettre des tiles originaux pour faire des cartes de voeux! Comme ça si le texte est creux au recto, on s'amuse au verso :lol: !

Hasta la vista!

Encore félicitation à tous ceux qui postent régulièrement et qui assurent la longévité de ce forum! :BIG:
Elevé au MSX !