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
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