générateur d'archipel caraïbe aléatoire

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

générateur d'archipel caraïbe aléatoire

Message par Huitbit »

Houba!

J'aime bien "Empire Earth" de Sierra (malgré les critiques!) alors je me suis dit que j'allais essayer de faire des cartes aléatoires.

La méthode employée n'est sûrement pas celle des pros mais ça marche très bien.

Bien sûr le code que je propose n'est que le début (je n'ai pas su mettre différents sprites), selon les valeurs des cases on mettra des bitmaps différents (mer, montagne, lac, terre..., et si c'est possible de superposer des sprites, on peut faire des plages, etc, on peut même prendre des sprites hexagonaux, mais au niveau IA c'est chaud pour un jeu(6 directions à traiter!)!).

On peut aussi détecter les grosses montagnes, les gros lacs... et affecter un sprites en fonction de la taille

On peut aussi forcer le hasard pour avoir plus de mer ou plus de terre...

Mais bon, pour l'instant je n'en suis quau début!

Le principe:

La chose à ne pas faire était de prendre le tableau complet puis de faire un méga random : c'est moche et ça n'a rien à voir avec un archipel!

J'ai pris un tableau (t1) de 35 cases (7 colonnes et 5 lignes) et parmi ces cases(elle mêmes diviséés en 64 cases cad 8*8), j'ai choisi celles qui seraient de la mer et celle qui seraient de la terre.

Ensuite j'ai traité les grandes cases de terre pour que ça ressemble à des côtes (conversion de décimaux aléatoires en binaires cad 46=01110100).

J'ai mis tout ça dans un tableau (t2) à 2D

Dernière étape: malgré les précautions prises, les îles ressemblent à des gruyère alors j'ai rajouté un détecteur pour boucher les trous!

Voilà le code (il est simple et commenté, il a l'air long mais c'est parce qu'il y a beaucoup de choses qui se répetent, je ne travaille que sur papier alors des fois je me rend pas compte!)


Code : Tout sélectionner

;****************déclaration des tableaux*************************************************

                     ;signification des valeurs des tableaux:
                     ;0:mer   1:terre    3:montagne     4:case visitée      5:bordure
                         
Dim rt1.l (4)        ; "random tableau1": choix de 5 nbres aléatoires compris entre 0 et 2^7  
Dim rst1.l (7)       ; "random soustableau1": choix de 8 nbres aléatoires compris entre 0 et 2^8
Dim t1.l(6,4,8,8)    ;tableau 1 :7*5 grandes cases divisées en cases 8*8
Dim t2.l (55,39)     ;tableau2 : 56*40 petites cases

Dim a1.l (55,39)     ;tableaux qui vont servir à la détection de la mer cad des "non-lacs"
Dim b1.l (55,39)
Dim a2.l (55,39)
Dim b2.l (55,39)

;*****déclaration de variables globales pour éviter que les procédures pédalent dans la choucroute!**

Global xst1,yst1,xt1,yt1,xt2,yt2

;************déclaration de la procédure test2 qui est appelée avant d'être écrite**************

Declare.l test2(x,y)

;**********************procédures appelées dans le programme principal**********************


Procedure.l test1(x,y) ;à partir d'une case "mer", on regarde si la case voisine
a1(x,y)=x               ;est une case "mer", si c'est le cas on continue le test en
b1(x,y)=y               ;appelant la procédure test2 ;sinon on passe  à la case suivante.
t2(a1(x,y),b1(x,y))=4   ;On dit qu'on a visité la case

If t2(a1(x,y),b1(x,y)-1)=0 
test2(a1(x,y),b1(x,y)-1)
EndIf

If t2(a1(x,y)+1,b1(x,y))=0 
test2(a1(x,y)+1,b1(x,y))
EndIf

If t2(a1(x,y),b1(x,y)+1)=0 
test2(a1(x,y),b1(x,y)+1)
EndIf

If t2(a1(x,y)-1,b1(x,y))=0 
test2(a1(x,y)-1,b1(x,y))
EndIf

EndProcedure



Procedure.l test2(x,y)  ;idem test1
a2(x,y)=x
b2(x,y)=y
t2(a2(x,y),b2(x,y))=4

If t2(a2(x,y),b2(x,y)-1)=0 
test1(a2(x,y),b2(x,y)-1)
EndIf

If t2(a2(x,y)+1,b2(x,y))=0 
test1(a2(x,y)+1,b2(x,y))
EndIf

If t2(a2(x,y),b2(x,y)+1)=0 
test1(a2(x,y),b2(x,y)+1)
EndIf

If t2(a2(x,y)-1,b2(x,y))=0 
test1(a2(x,y)-1,b2(x,y))
EndIf

EndProcedure



Procedure.l matrice() ;on rempli aléatoirement les cases 8*8

For yst1 = 0 To 7             ;choix d'un nombre compris entre 0 et 2^8 pour les 8 lignes de la case
  rst1(yst1)=Int(Random(256))
Next yst1

For xst1 = 0 To 7           ;transformation des décimaux choisis en nombres binaires
  For yst1 = 0 To 7
    psb= Pow(2,(7-xst1))
    If rst1(yst1)-psb >=0
    t1(xt1,yt1,xst1,yst1)=1
    rst1(yst1) = rst1(yst1)-psb
    EndIf
  Next yst1
Next xst1
EndProcedure



Procedure.l transfert()   ; on passe de la matrice 4 dimensions à celle à 2 dimensions 
For xt1 = 0 To 6
  For yt1 = 0 To 4
    For xst1 =0 To 7
      For yst1 = 0 To 7
        xt2=xst1+8*xt1
        yt2=yst1+8*yt1
        t2(xt2,yt2)=t1(xt1,yt1,xst1,yst1)
      Next yst1
    Next xst1
  Next yt1
Next xt1

EndProcedure  



Procedure.l mer()    ; on va détecter si il ya des cases vides qui ne sont pas liées à la mer (lacs)
yt2=1                 ;si c'est le cas, on bouchera les trous! 
For xt2 = 1 To 54
If t2(xt2,yt2)=0      
test1(xt2,yt2)
EndIf
Next xt2

yt2=38
For xt2 = 1 To 54
If t2(xt2,yt2)=0 
test1(xt2,yt2)
EndIf
Next xt2

xt2=1
For yt2 = 1 To 38
If t2(xt2,yt2)=0 
test1(xt2,yt2)
EndIf
Next yt2

xt2=54
For yt2 = 1 To 38
If t2(xt2,yt2)=0 
test1(xt2,yt2)
EndIf
Next yt2

For xt2=1 To 54
  For yt2 = 1 To 38
  If t2(xt2,yt2) =0 
  t2(xt2,yt2)=3
  EndIf
  Next yt2
Next xt2

EndProcedure  

;****************************************************************************************
;*******************************programmme principal***********************************


;***************** choix des grandes cases qui ne seront pas de la mer**********************
For yt1 = 0 To 4              
 rt1(yt1) =Int(Random(128))    ;choix de 5 nbres aléatoires compris entre 0 et 2^7  
Next yt1



For xt1 = 0 To 6                ;transformation des décimaux choisis en nombres binaires 
  For yt1 = 0 To 4              ; pour chacune des 5 lignes du tableau 7*5
    pb = Pow(2,(6-xt1))
    If rt1(yt1) - pb >=0 
    t1(xt1,yt1,0,0) = 1: rt1(yt1) = rt1(yt1) - pb
    
    EndIf
  Next yt1
Next xt1  



For xt1 = 0 To 6                ;traitement des cases choisies précédemment 
  For yt1 = 0 To 4
    If t1(xt1,yt1,0,0) = 1      ; si c'est de la mer (t1()=0, il n'y a rien à faire
    matrice()                   ;sinon la procedure matrice remplie aléatoirement la case8*8
    EndIf
  Next yt1
Next xt1


;****************************************************************************************

transfert() ; passage de la matrice 4 dimensions à celle à 2 dimensions 

;*********************************************************************************

; délimitation de la zone de travail sinon le détecteur de mer sort des limites! 
  
yt2 = 0
For xt2 =0 To 55
t2(xt2,yt2)=5
Next xt2

yt2 = 39
For xt2 =0 To 55
t2(xt2,yt2)=5
Next xt2

xt2 = 0
For yt2 =0 To 39
t2(xt2,yt2)=5
Next yt2

xt2 = 55
For yt2 =0 To 39
t2(xt2,yt2)=5
Next yt2

;************************************************************************************

mer() ;appel de la procédure mer pour "chasser les trous"

; *********** initialisation ********* 

InitMouse () 

; ******** ** pour le sprite ***************** 

InitSprite () 

; *************************************** 


OpenWindow (1, 1,1, 896, 640, 1 , "test" ) ; on ouvre une fenetre 
OpenWindowedScreen ( WindowID (1) , 0, 0, 896, 640, 1, 1, 1) ; on met un ecran dedans !! 

; *********** on va creer des sprites !! ***************** 

For i=1 To 2240    ;création de 56*40 sprites (on pourrait  en créér moins il y a de la mer
                    ; j'optimiserai ça plus tard!)
CreateSprite (i,16,16) ; on crée un sprite de 16*16 
StartDrawing ( SpriteOutput (i)) ; on va dessiner dedans un rond ! 
Circle (8,8, 8, $FF0000) ; le voila le beau rond 
StopDrawing () 

Next i


; ********* le sprite est terminé on va jouer avec !! ****** 
Repeat ; boucle principale 

Event= WaitWindowEvent () ; on regarde si quelqu'un a cliqué sur la croix pour quitter 

; ***************************************** 


ExamineMouse () 
If MouseButton (2) ; le bouton de souris droit fait quitter ! 
End 
EndIf 
i=0  ;index des sprites mis à 0

For xt2= 0 To 55
  For yt2 = 0 To 39
   
   
   i=i+1
   If t2(xt2,yt2)=1 Or t2(xt2,yt2)=3 ; si terre ou montagne afficher le rond
     DisplaySprite (i,xt2*16,yt2*16) ; et voila !
   EndIf
   
  
   
  Next yt2
Next xt2

; *************************************************** 
FlipBuffers () ; <---- ceci pour voir le dessin se faire +Lent !! 
ClearScreen (0, 0, 0) ; <--- ceci efface l'ecran !! 
Until Event= #PB_Event_CloseWindow 
Return 
Voilà, faites plusieurs tests(le hasard peut mal faire les choses!), vous verrez ça peut être réaliste (j'aurai dû mettre un bouton gadget pour éviter de relancer mais je SAIS PAS!)


Si quelqu'un a l'énergie pour jeter un coup d'oeil au code (il est simple (je suis débutant!) et suffisamment commenté(j'espère)).

J'aimerai savoir si il y a des trucs en trop

Est-ce que quelqu'un sait détecter les trous???? Moi je sais pas alors j'ai détecté les non-trous!

A+
Merci d'avance
Elevé au MSX !
AWEAR
Messages : 264
Inscription : ven. 28/oct./2005 8:20
Localisation : Mayotte ( 976 ), Océan Indien, France

Message par AWEAR »

Je n'ai pas bien eu le temps de tout comprendre, mais ce que tu pourrais faire pour les sprites c'est de remplacer

Code : Tout sélectionner

For i=1 To 2240    ;création de 56*40 sprites (on pourrait  en créér moins il y a de la mer 
                    ; j'optimiserai ça plus tard!) 
CreateSprite (i,16,16) ; on crée un sprite de 16*16 
StartDrawing ( SpriteOutput (i)) ; on va dessiner dedans un rond ! 
Circle (8,8, 8, $FF0000) ; le voila le beau rond 
StopDrawing () 

Next i 


; ********* le sprite est terminé on va jouer avec !! ****** 
Repeat ; boucle principale 

Event= WaitWindowEvent () ; on regarde si quelqu'un a cliqué sur la croix pour quitter 

; ***************************************** 


ExamineMouse () 
If MouseButton (2) ; le bouton de souris droit fait quitter ! 
End 
EndIf 
i=0  ;index des sprites mis à 0 

For xt2= 0 To 55 
  For yt2 = 0 To 39 
    
    
   i=i+1 
   If t2(xt2,yt2)=1 Or t2(xt2,yt2)=3 ; si terre ou montagne afficher le rond 
     DisplaySprite (i,xt2*16,yt2*16) ; et voila ! 
   EndIf 
par

Code : Tout sélectionner

i = 1  ;création de 1 sprite représentant de la terre
CreateSprite (i,16,16) ; on crée un sprite de 16*16 
StartDrawing ( SpriteOutput (i)) ; on va dessiner dedans un rond ! 
Circle (8,8, 8, $FF0000) ; le voila le beau rond 
StopDrawing () 



; ********* le sprite est terminé on va jouer avec !! ****** 
Repeat ; boucle principale 

Event= WaitWindowEvent () ; on regarde si quelqu'un a cliqué sur la croix pour quitter 

; ***************************************** 


ExamineMouse () 
If MouseButton (2) ; le bouton de souris droit fait quitter ! 
End 
EndIf 

For xt2= 0 To 55 
  For yt2 = 0 To 39 
    
    
   If t2(xt2,yt2)=1 Or t2(xt2,yt2)=3 ; si terre ou montagne afficher le rond 
     DisplaySprite (i,xt2*16,yt2*16) ; et voila ! 
   EndIf 
En effet, une fois ton sprite "i" créé, inutile de le créer 2240 fois !
Un sprite peut être afficher à plusieurs endroits en même temps, donc pas besoin d'en avoir plusieurs identiques, un seul suffit !
La vie est une rose dont il faut accepter les épines, mais la mienne est fannée, arrosée par le goût de mes larmes. (Soprano)
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Message par Huitbit »

Super wahou! Merci!
J'avais des problèmes avec les index pour faire d'autres sprites, je crois qu'avec ça je vais pouvoir faire quelque chose!

Encore merci!

PS: ici la température a chuté à 27° C!
ça caille!!!!!
Elevé au MSX !
Avatar de l’utilisateur
Chris
Messages : 3731
Inscription : sam. 24/janv./2004 14:54
Contact :

Message par Chris »

Huitbit a écrit :Super wahou! Merci!
J'avais des problèmes avec les index pour faire d'autres sprites, je crois qu'avec ça je vais pouvoir faire quelque chose!

Encore merci!

PS: ici la température a chuté à 27° C!
ça caille!!!!!
Ce qui faut pas lire, par moment :roll:
27° : Ca caille!

Chez moi, il fait 2° à 17 h
:lol:
AWEAR
Messages : 264
Inscription : ven. 28/oct./2005 8:20
Localisation : Mayotte ( 976 ), Océan Indien, France

Message par AWEAR »

De rien !
PS : Chez nous c'est monté à 35°C ! Commence à faire chaud !! Mais bon moi je comprends très bien qu'on puisse avoir froid à 27°C ! Moi je dors toujours avec une couverture, si si ! :lol:
La vie est une rose dont il faut accepter les épines, mais la mienne est fannée, arrosée par le goût de mes larmes. (Soprano)
Avatar de l’utilisateur
Chris
Messages : 3731
Inscription : sam. 24/janv./2004 14:54
Contact :

Message par Chris »

Punaise, y vont finir par me foutre le blues avec leurs températures autour de 30°.

Quand je pense que chez nous, on se les gèle :(
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Chris a écrit :Quand je pense que chez nous, on se les gèle :(
TOUTE L'ANNEE !! :? ça descend a -12 ici la nuit !
AWEAR
Messages : 264
Inscription : ven. 28/oct./2005 8:20
Localisation : Mayotte ( 976 ), Océan Indien, France

Message par AWEAR »

Oula ! C'est pas bon ça moi j'arrive dans une semaine, je pensais pas qu'il faisait si froid :lol:
La vie est une rose dont il faut accepter les épines, mais la mienne est fannée, arrosée par le goût de mes larmes. (Soprano)
Avatar de l’utilisateur
Chris
Messages : 3731
Inscription : sam. 24/janv./2004 14:54
Contact :

Message par Chris »

AWEAR a écrit :Oula ! C'est pas bon ça moi j'arrive dans une semaine, je pensais pas qu'il faisait si froid :lol:
Non, mais Dobro, il habite en Sibérie. Faut pas se baser sur ce qu'il dit.

(Et en plus, il sait même pas lire un thermomètre :roll: )

:wink:
AWEAR
Messages : 264
Inscription : ven. 28/oct./2005 8:20
Localisation : Mayotte ( 976 ), Océan Indien, France

Message par AWEAR »

Oui mais le problème c'est que moi je vais juste à coté de chez Dobro :lol:
La vie est une rose dont il faut accepter les épines, mais la mienne est fannée, arrosée par le goût de mes larmes. (Soprano)
Avatar de l’utilisateur
Chris
Messages : 3731
Inscription : sam. 24/janv./2004 14:54
Contact :

Message par Chris »

Alors tu vas te geler :lol:
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Message par Huitbit »

"Le froid est une conception de l'esprit" dixit le sergent ......
J'ai fais les troupes de montagnes au 92° RI à Clermond Ferrand en 99
A -18° C on faisait le reveil musculaire dans la neige et en caleçon!!!
On a eu droit aux peaux de phoques(pauv'bêtes), aux igloos, à l'ARVA, etc

Bon merci AWEAR, j'ai mis un peu de couleurs (le sprites en forme de disques sont là pour l'exemple faute de mieux!) maintenant ça ressemble un peu plus à une carte!

Il me manque un buttongadget mais j'y travaille!

Il faut remplacer la fin du code par:

Code : Tout sélectionner

; *********** on va creer des sprites !! ***************** 
 ;création  sprite représentant de la terre 
CreateSprite (1,16,16) ; on crée un sprite de 16*16 
StartDrawing ( SpriteOutput (1)) ; on va dessiner dedans un rond ! 
Circle (8,8, 8, $44C2BB) ; le voila le beau rond 
StopDrawing () 

 ;création sprite représentant de la montagne
CreateSprite (2,16,16) ; on crée un sprite de 16*16 
StartDrawing ( SpriteOutput (2)) ; on va dessiner dedans un rond ! 
Circle (8,8, 8, $33B0CC) ; le voila le beau rond 
StopDrawing () 

 ;création sprite représentant de la mer
CreateSprite (3,16,16) ; on crée un sprite de 16*16 
StartDrawing ( SpriteOutput (3)) ; on va dessiner dedans un rond ! 
Circle (8,8, 8, $BB1544) ; le voila le beau rond 
StopDrawing () 

 ;création sprite représentant de la bordure
CreateSprite (4,16,16) ; on crée un sprite de 16*16 
StartDrawing ( SpriteOutput (4)) ; on va dessiner dedans un rond ! 
Circle (8,8, 8, $0C0CE9) ; le voila le beau rond 
StopDrawing () 



; ********* les sprites sont terminés on va jouer avec !! ****** 
Repeat ; boucle principale 

Event= WaitWindowEvent () ; on regarde si quelqu'un a cliqué sur la croix pour quitter 

; ***************************************** 


ExamineMouse () 
If MouseButton (2) ; le bouton de souris droit fait quitter ! 
End 
EndIf 

For xt2= 0 To 55 
  For yt2 = 0 To 39 
    
    
   If t2(xt2,yt2)=1   ; si terre afficher le rond 
     DisplaySprite (1,xt2*16,yt2*16) ; et voila ! 
   EndIf 
   
   If t2(xt2,yt2)=3 ;montagne
     DisplaySprite (2,xt2*16,yt2*16)  
   EndIf  


   If t2(xt2,yt2)=4 ;mer
     DisplaySprite (3,xt2*16,yt2*16)  
   EndIf
   
   
   If t2(xt2,yt2)=5 ;bordure
     DisplaySprite (4,xt2*16,yt2*16)  
   EndIf
     
  Next yt2
Next xt2

; *************************************************** 
FlipBuffers () ; <---- ceci pour voir le dessin se faire +Lent !! 
ClearScreen (0, 0, 0) ; <--- ceci efface l'ecran !! 
Until Event= #PB_Event_CloseWindow 
Return 

En route pour de nouvellesaventures...
Elevé au MSX !
AWEAR
Messages : 264
Inscription : ven. 28/oct./2005 8:20
Localisation : Mayotte ( 976 ), Océan Indien, France

Message par AWEAR »

A oui la ça donne bien, mais j'ai du changer les couleurs parce que je voyais pas de différence !
(je suis daltonien ça doit être pour ça !)
La vie est une rose dont il faut accepter les épines, mais la mienne est fannée, arrosée par le goût de mes larmes. (Soprano)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

je sais que la methode n'as rien a voir, mais on peut faire un truc du genre aussi :D


 
; *********** initialisation *********

; ******************************


InitMouse ()


  ; ******** ** pour le sprite *****************
InitSprite ()
; ***************************************



OpenWindow (1, 1,1, 800, 600, #PB_Window_SystemMenu , "test" ) ; on ouvre une fenetre
OpenWindowedScreen ( WindowID (1) , 0, 0, 800, 600, 1, 1, 1) ; on met un ecran dedans !!

; *********** on va creer le sprite !! *****************
CreateSprite (1,8,8 ) ; on cree un sprite pierre
StartDrawing ( SpriteOutput (1)) ;
Circle (8,8, 8, RGB ($C0,$C0,$C0)) ;
StopDrawing ()
; ********* le sprite est terminer on va jouer avec !! ******
CreateSprite (2,8,8 ) ; on cree un sprite terre
StartDrawing ( SpriteOutput (2)) ;
Circle (8,8, 8, RGB ($0,$9B,$0)) ;
StopDrawing ()
; ********* le sprite est terminer on va jouer avec !! ******
CreateSprite (3,8,8 ) ; on cree un sprite herbe
StartDrawing ( SpriteOutput (3)) ;
Circle (8,8, 8, RGB ($0,$B9,$0)) ;
StopDrawing ()

StartDrawing ( ScreenOutput ()) ;
Locate (300, 200)
DrawText ( "dessin en cours !!" )
FlipBuffers ()
StopDrawing ()
ClearScreen ($2D,$96,$FF)



nombre_ile=80
montagne=nombre_ile-(nombre_ile/2)
For n=1 To nombre_ile
    de_x= Random (800)
    de_y= Random (600)
    tourx= Random (100)
    toury= Random (600)+1
     For y=1 To toury Step 2
         For x=1 To tourx Step 2
            tourx= Random (100)
             If tourx>montagne
                 DisplaySprite (3,de_x+ Random (tourx),de_y+y) ; herbe
             EndIf
             If tourx>montagne/2
                 DisplaySprite (2,de_x+tourx,de_y+y) ; terre
             EndIf
             If tourx<montagne/8
                 DisplaySprite (1,de_x+tourx,de_y+y) ; pierre
             EndIf
         Next x
     Next y
Next n
Repeat ; boucle principale
    
    Event= WaitWindowEvent () ; on regarde si quelqu'un a cliqué sur la croix pour quitter
    
     ExamineMouse ()
     If MouseButton (2) ; le bouton de souris droit fait quitter !
         End
     EndIf
     FlipBuffers ()
     ; ClearScreen($2D,$96,$FF)
Until Event= #PB_Event_CloseWindow
Return
l'avantage c'est plus court !! :lol:
Avatar de l’utilisateur
Huitbit
Messages : 940
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Message par Huitbit »

Resuper wahou!
C'est court et en plus on a des infos sur les composantes de la carte.
Moi, il me faut un détecteur d'îles (pour les compter), un détecteur de trous...

A propos de musique, j'ai vu et ententu purenoide,
ben ... purebravo quoi!
(J'ai une interface Aardvark et cubase sx) avoir une aussi bonne qualité de son sur un fichier aussi petit, bravo!
Elevé au MSX !
Répondre