Écriture de labyrinthe

Soyez le premier à donner votre avis sur cette source.

Snippet vu 6 335 fois - Téléchargée 36 fois

Contenu du snippet

un simple code qui créé un bmp représentant un labyrinthe récursif. libre à vous ensuite de créer le moteur 3d pour vous déplacer dedans (je l'ai fait, c'est trop chouette !!). il faut juste spécifier en dur dans le code la largeur et la hauteur du labyrinthe désiré et hop !

le labyrinthe créé n'a qu'une seule sortie

attention à ne pas spécifier des tailles trop importantes, votre pile a toutes les chances d'exploser et votre mémoire a toutes le chances d'être pleine ! mais en dessous de 4 millions de pixels, aucun problème.

la capture d'écran est en jpg alors excusez le mauvais rendu, ce format n'aime pas vraiment les fortes variations de couleur. le capture d'écran représente le labyrinthe 128*128, il est bien assez compliqué.

Source / Exemple :


#include <stdio.h>
#include <stdlib.h>

#define CTOI(C)   (*(int*)&C) 
#define ABS(n) (n<=0)?-n:n

int complement(unsigned int nb)
{
    switch(nb%4)
    {
        case 0 : return 0;
        default : return 4-nb%4;
    }       
}    

void set(unsigned char *data, 
         unsigned long i,
         unsigned long j,
         unsigned char r,
         unsigned char g,
         unsigned char b,
         unsigned long ligne_size)
{
     data[j*ligne_size+i*3]=b;
     data[j*ligne_size+i*3+1]=g;
     data[j*ligne_size+i*3+2]=r;
}    

void draw_line(unsigned char *data,    // les deux points doivent être sur une même "ligne"
               unsigned long x1,       //  et dessine un couloir
               unsigned long y1,
               unsigned long x2,
               unsigned long y2,
               unsigned long ligne_size)
{
    //printf("%d %d %d %d\n",x1,y1,x2,y2);
    unsigned long i;
    if (x1==x2)
        {
             if (y1>y2)
             for (i=y2; i<y1; i++)
                 set(data,x1,i,1,67,188,ligne_size);
             else
             for (i=y1; i<y2; i++)
                 set(data,x1,i,1,67,188,ligne_size);           
        }
    else    // y1==y2
        {
             if (x1>x2)
             for (i=x2; i<x1; i++)
                 set(data,i,y1,1,67,188,ligne_size);
             else
             for (i=x1; i<x2; i++)
                 set(data,i,y1,1,67,188,ligne_size);            
        }    
}    

void draw_labyrinthe(unsigned char *data, 
                     unsigned long departx,
                     unsigned long departy,
                     unsigned long coin1x,
                     unsigned long coin1y,
                     unsigned long coin2x,
                     unsigned long coin2y,
                     unsigned long ligne_size)
{
    // condition d'arrêt
    if ((ABS(coin1x-coin2x)>3) && (ABS(coin1y-coin2y)>3))
      { 
        // on se déplace au milieu de la zone    
        draw_line(data, departx, departy, (int)((coin1x+coin2x)/2), (int)((coin1y+coin2y)/2),ligne_size);
        if (departy==(int)((coin1y+coin2y)/2))
           {
               draw_labyrinthe(data,(int)((coin1x+coin2x)/2), (int)((coin1y+coin2y)/2), coin1x, coin1y, coin2x, (int)((coin1y+coin2y)/2), ligne_size);  //bas
               draw_labyrinthe(data,(int)((coin1x+coin2x)/2), (int)((coin1y+coin2y)/2), coin1x, (int)((coin1y+coin2y)/2), coin2x, coin2y, ligne_size);  // haut
           }    
        else
           {
               draw_labyrinthe(data, (int)((coin1x+coin2x)/2), (int)((coin1y+coin2y)/2), coin1x, coin1y, (int)((coin1x+coin2x)/2), coin2y, ligne_size);  //gauche
               draw_labyrinthe(data, (int)((coin1x+coin2x)/2), (int)((coin1y+coin2y)/2), (int)((coin1x+coin2x)/2), coin1y, coin2x, coin2y, ligne_size);  //droite
           }    
      }
}    

put_exit(unsigned char *data, unsigned long largeur, unsigned long hauteur,unsigned long ligne_size)
{
    unsigned long x=rand()%largeur;
    while ((data[(hauteur-2)*ligne_size+x*3]!=1) && 
          (data[(hauteur-2)*ligne_size+x*3+1]!=67) && 
          (data[(hauteur-2)*ligne_size+x*3+2]!=188))
          x++;
    //printf("%d %d", x, hauteur-1);
    set(data, x, hauteur-1, 1,67,188, ligne_size);
}    

int main(int argc, char **argv)
{
    unsigned int largeur=2000, hauteur=2000;
    
    FILE *fichier=fopen("labyrinthe.bmp", "w");
    unsigned char header[54]={0};
    unsigned long ligne_size=largeur*3+complement(largeur*3);
    unsigned long datasize=hauteur* ligne_size;
    //printf("%ld", datasize);
   
    header[0]='B';
    header[1]='M';
    CTOI(header[2])=54+datasize;
    CTOI(header[10])=54;
    CTOI(header[14])=40;
    CTOI(header[18])=largeur;
    CTOI(header[22])=hauteur;
    CTOI(header[26])=1;
    CTOI(header[28])=24;
    CTOI(header[34])=datasize;
    fwrite(&header,1,54,fichier);
    
    char *data=(char*)calloc(datasize,1);
    if (data==NULL) return 1;
    
    /* on colorie tout en 2,150,20*/
    unsigned int i,j;
    for (j=0; j<hauteur; j++)
      for (i=0; i<largeur; i++)
         set(data, i,j,2,150,20, ligne_size);
    
    srand(2);
    draw_labyrinthe(data, (int)largeur/2, 1, 0, hauteur, largeur, 1, ligne_size);
    
    set(data, (int)largeur/2, 1, 1,100,188, ligne_size);
    put_exit(data,largeur,hauteur, ligne_size);
    
    fwrite(data, 1, largeur*hauteur*3, fichier); 
    free(data);
    
    fclose(fichier);
    return 0;   
}

A voir également

Ajouter un commentaire

Commentaires

Messages postés
51
Date d'inscription
lundi 7 juin 2004
Statut
Membre
Dernière intervention
15 juillet 2005

comment appelles-tu un espace où tout se ressemble et dont il est plutôt difficile de sortir. moi j'appelle ça un labyrinthe, fractal si tu veux. en considérant le vert comme un mur et le bleu comme un couloir.

mais si tu veux corcer la chose, tu peux toujours rajouter un brin d'aléa pour la probabilité de croisement ou pour la longueur des couloirs.

mais personnellement je préfère les labyrinthes réguliers, c'est d'autant plus rageant quant on n'arrive pas à en sortir, même si c'est vrai qu'un prog de 10 lignes peut résoudre ce labyrinthe.
Messages postés
15
Date d'inscription
mardi 3 août 2004
Statut
Membre
Dernière intervention
3 janvier 2007

Ca n'a rien d'un labyrinthe... le motif est toujours le même... Ce serait plutôt des fractals

La construction d'un labyrinthe ne se fait pas du tout de cette façon.
Messages postés
3011
Date d'inscription
jeudi 26 septembre 2002
Statut
Membre
Dernière intervention
27 novembre 2004
7
oui, remarque importante pour les specif de ta fonction


"évidemment le type de put_exit est void, tlm l'avait compris, même mon compilo."

non, tout le monde a compris que c'etait void, mais ton compilo a compris que c'etait int
ton code ne devrai pas compiler normalement a cause de ces quelques incoherences
Messages postés
51
Date d'inscription
lundi 7 juin 2004
Statut
Membre
Dernière intervention
15 juillet 2005

srand(2), oui c'était recherché.
évidemment le type de put_exit est void, tlm l'avait compris, même mon compilo.

en itératif, tu peux essayer, je n'essaierais même pas.

juste un truc, ça marche beaucoup mieux pour des dimensions puissances de 2, aspect récursif oblige.
Messages postés
3011
Date d'inscription
jeudi 26 septembre 2002
Statut
Membre
Dernière intervention
27 novembre 2004
7
c'etait donc pour faire ca ;)
pour de la generation d'image c'est pas mal

si tu met srand(2); tu auras la meme sequence de nombres à chaque execution

tu as oublié de preciser le type retour de put_exit et ne cast pas le calloc

pour la recursivité, tu as vu le probeme, mais si ca tient jusqu'a 4 millions de pixel alors ca va

ca peu se retranscire facilemnt en iteratif ?

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.