jeux de la vie (les Chmolls)
Publié : ven. 03/oct./2008 15:11
				
				qui ne s'est pas pris pour Dieu a jouer avec son ordinateur a Populous et Sim ou autre Spore,
ce qui m'a d'ailleurs toujours plus ou moins fasciné avec les ordinateur c'était la possibilité de faire naitre des êtres virtuel
a l'époque des TI99/4a et autre Mo5, Atari st..etc , je m'amusais a créer
des "fourmis" en utilisant les "plots"
je leur donnais des règles et je regardais ce qui se passait...
 on s'amuse comme on peut n'est ce pas.... 
récemment avec Spore (que je n'ai toujours pas acheté d'ailleurs)
m'est apparu le concept de la génétique dans le monde virtuel !!
comment en effet faire en sorte que des être virtuel récupère des caractéristique génétique de leur parents ??...
voila la question que je me suis posé..
je me suis donc mis a cogiter un poil (faut pas déconner non plus
)
j'ai donc cree un univers bizarre et saugrenu (comme souvent les univers virtuel)
l'univers est donc l'écran !<-- pas trop dur jusque la
des êtres "primitif" apparaissent Les CHMOLs !!
gérés par la variable nombre_de_chmol
ces êtres (primitif) peuvent avoir comme forme soit Rond, soit Carré
il peuvent être de différentes couleurs et être soit Mâle, soit femelle
ils ont un mode de déplacement assez simple!! :
des qu'ils rencontre un autre Chmol par contact , ils rebroussent chemin
s'ils rencontre le bord de l'écran il rebroussent chemin
toutes les 2 secondes le premiers contact entre un mâle et une femelle engendre un BB
 (qu'il est mignon 
 )
ce bb récupère une partie des composante de la couleur du père et une partie de la composante de la mère....
et aussi une partie de la forme du père, et une partie de la forme de la mère
ce qui peut donner des bb ayant la forme
demi-rond_demi_rond (si la mère et le père étaient des ronds)
demi-carre_demi-carré (si la mère et le père étaient carre)
demi-rond_demi-carré (si l'un des deux parent avait une forme différente)
demi-carré_demi-rond (si l'un des deux parent avait une forme différente)
bien sur ensuite les enfants qui copulent (je sais c'est pas moral..
)
qu'ils soient enfants ou parents
les petits enfants récupèrent aussi une partie des caractéristique leur parents
ceci est un petit exemple de ce principe de génétique très très simplifié
a noter, je ne gère pas la mortalité, ni le besoin de nourriture
bien que le paramètre vie soit implémenté, ont verra une version futur
on arrive vite a une surpopulation
 
il se peut que le prg au debut genere que des male ou que des femelles
bien sur dans se cas relancez le prg !!
en utilisant la touche espace , les chmols sont regeneré !!
le mieux étant d'avoir des males et des femelles de différentes couleurs et forme pour voir les effets de la génétique
ajout de la gestion des touches [+] e [-] pour ajouter ou diminer les chmols !!
 
			ce qui m'a d'ailleurs toujours plus ou moins fasciné avec les ordinateur c'était la possibilité de faire naitre des êtres virtuel
a l'époque des TI99/4a et autre Mo5, Atari st..etc , je m'amusais a créer
des "fourmis" en utilisant les "plots"
je leur donnais des règles et je regardais ce qui se passait...
récemment avec Spore (que je n'ai toujours pas acheté d'ailleurs)
m'est apparu le concept de la génétique dans le monde virtuel !!
comment en effet faire en sorte que des être virtuel récupère des caractéristique génétique de leur parents ??...
voila la question que je me suis posé..
je me suis donc mis a cogiter un poil (faut pas déconner non plus
j'ai donc cree un univers bizarre et saugrenu (comme souvent les univers virtuel)
l'univers est donc l'écran !<-- pas trop dur jusque la
des êtres "primitif" apparaissent Les CHMOLs !!
gérés par la variable nombre_de_chmol
ces êtres (primitif) peuvent avoir comme forme soit Rond, soit Carré
il peuvent être de différentes couleurs et être soit Mâle, soit femelle
ils ont un mode de déplacement assez simple!! :
des qu'ils rencontre un autre Chmol par contact , ils rebroussent chemin
s'ils rencontre le bord de l'écran il rebroussent chemin
toutes les 2 secondes le premiers contact entre un mâle et une femelle engendre un BB
ce bb récupère une partie des composante de la couleur du père et une partie de la composante de la mère....
et aussi une partie de la forme du père, et une partie de la forme de la mère
ce qui peut donner des bb ayant la forme
demi-rond_demi_rond (si la mère et le père étaient des ronds)
demi-carre_demi-carré (si la mère et le père étaient carre)
demi-rond_demi-carré (si l'un des deux parent avait une forme différente)
demi-carré_demi-rond (si l'un des deux parent avait une forme différente)
bien sur ensuite les enfants qui copulent (je sais c'est pas moral..
qu'ils soient enfants ou parents
les petits enfants récupèrent aussi une partie des caractéristique leur parents
ceci est un petit exemple de ce principe de génétique très très simplifié
a noter, je ne gère pas la mortalité, ni le besoin de nourriture
bien que le paramètre vie soit implémenté, ont verra une version futur
on arrive vite a une surpopulation
il se peut que le prg au debut genere que des male ou que des femelles
bien sur dans se cas relancez le prg !!
en utilisant la touche espace , les chmols sont regeneré !!
le mieux étant d'avoir des males et des femelles de différentes couleurs et forme pour voir les effets de la génétique
ajout de la gestion des touches [+] e [-] pour ajouter ou diminer les chmols !!
Code : Tout sélectionner
; Version 4
; Code by Dobro
; Purebasic 4.20
Declare create_chmol(id,posx,posy,pasx,pasy,vie,sex,couleur,forme,angle.f) ; procedure qui cree un etre vivant
Declare TimerProc(hwnd.l, uMsg.l, idEvent.l, dwTime.l)
Declare.f RotationX(x, angle.f, dist)
Declare.f RotationY(y, angle.f, dist)
Global nombre_de_chmol=3
Global compteur=nombre_de_chmol
Global effet,effet2
#dobro =1
#Police =1
#sprite=1
Structure etre
      id.l ; identité du chmol
      posx.l ; position x du schmol
      posy.l ; position y du schmol
      pas_x.l ; sens de directio x  du chmol
      pas_y.l; sens de direction y du chmol
      vie.l ; etat de santé du chmol
      sex.b ; sex du chmol
      couleur.l ; couleur du chmol
      forme.b ; forme des etres de base (les primitifs !!) LOL
      angle.f ; l'angle ; la direction du chmol
EndStructure
Global Dim etre.etre(nombre_de_chmol)
InitKeyboard () : ; j'espere qu'il y a un clavier au moins !!
Resultat = InitSprite () :InitSprite3D() ; initialisation de la gestion des  Sprites par Purebasic
; ************** definition des variables ****************
EcranX = 800
EcranY = 600
; ***************************************************
; *********** ouvre une fenetre aucentre de l'ecran sans bordure, mais ayant la petite croix pour fermer *****************
WindowID = OpenWindow (1, 0, 0,EcranX, EcranY, "hello" , #PB_Window_SystemMenu|#PB_Window_BorderLess |#PB_Window_ScreenCentered )
; **************************************************************************************************
;********** placement d'un ecran graphique dans notre fenetre préalablement crée *************************    
Result = OpenWindowedScreen ( WindowID (1),0,0, EcranX,EcranY, 1, 0,0)
; *****************************************************************************************
  
Handle = WindowID(1) 
SetTimer_(Handle, 1, 2000, @TimerProc()) ; envoie un evenement toutes les 2 secondes pour les naissances
SetTimer_(Handle, 2, 3000, @TimerProc()) ; envoie un evenement toutes les 4 secondes pour les morts
SetTimer_(Handle, 3, 200, @TimerProc()) ; envoie un evenement toutes les 3 secondes pour les changements d'angles
For i=1 To nombre_de_chmol
      id=id+1
      posx=Random(800-32)+32
      posy=Random(600-32)+32
      pas_x=Random(2)+1
      pas_y=Random(2)+1
      vie=100
      sex=Random(1)
      couleur=RGB(Random(255),Random(255),Random(255))
      forme= Random(1)
      angle.f=Random(359)+1
      create_chmol(id,posx,posy,pas_x,pas_y,vie,sex,couleur,forme,angle.f)
Next i
    
Repeat  ;*********  debut de boucle principale  ************************** 
      ExamineKeyboard (); on regarde si le clavier a ete touché par l'utilisateur  
      ; ************************ ecriture dans l'ecran *********************
      StartDrawing ( ScreenOutput ()) ; on va ecrire dans le fond de l'ecran
            Resultat = DrawText (50, 10, "nombre de chmol :"+Str(compteur) , RGB (255,255,0), RGB (0,0,0) ) 
      StopDrawing ()
      ; ******************************************************************
      
      If KeyboardPushed(#PB_Key_Space)
            id=0
            For i=1 To nombre_de_chmol
                  id=id+1
                  posx=Random(800-32)+32
                  posy=Random(600-32)+32
                  pas_x=Random(2)+1
                  pas_y=Random(2)+1
                  vie=100
                  sex=Random(1)
                  couleur=RGB(Random(255),Random(255),Random(255))
                  forme= Random(1)
                  angle.f=Random(359)+1
                  create_chmol(id,posx,posy,pas_x,pas_y,vie,sex,couleur,forme,angle.f)
            Next i
      EndIf
      
      If KeyboardPushed(#PB_Key_Add) 
            id=0
            nombre_de_chmol= nombre_de_chmol+1
            compteur= nombre_de_chmol
            Redim etre.etre(nombre_de_chmol)
            For i=1 To nombre_de_chmol
                  id=id+1
                  posx=Random(800-32)+32
                  posy=Random(600-32)+32
                  pas_x=Random(2)+1
                  pas_y=Random(2)+1
                  vie=100
                  sex=Random(1)
                  couleur=RGB(Random(255),Random(255),Random(255))
                  forme= Random(1)
                  angle.f=Random(359)+1
                  create_chmol(id,posx,posy,pas_x,pas_y,vie,sex,couleur,forme,angle.f)
            Next i
      EndIf
      If KeyboardPushed(#PB_Key_Subtract)
            id=0
            nombre_de_chmol= nombre_de_chmol-1
            If nombre_de_chmol<=0
                  nombre_de_chmol=1
            EndIf 
            compteur= nombre_de_chmol
            Redim etre.etre(nombre_de_chmol)
            For i=1 To nombre_de_chmol
                  id=id+1
                  posx=Random(800-32)+32
                  posy=Random(600-32)+32
                  pas_x=Random(2)+1
                  pas_y=Random(2)+1
                  vie=100
                  sex=Random(1)
                  couleur=RGB(Random(255),Random(255),Random(255))
                  forme= Random(1)
                  angle.f=Random(359)+1
                  create_chmol(id,posx,posy,pas_x,pas_y,vie,sex,couleur,forme,angle.f)
            Next i
      EndIf
      
      
      ;-affichage
      ; ***************** affichage *****************************************
      
      For i=1 To nombre_de_chmol  ; pour tout les etre present dans la liste chainée on recupere 
            
            id=etre(i)\id  ; l'identité   
            vie=etre(i)\vie ; son niveau de vie 
            sex=etre(i)\sex ; son sex 
            couleur=etre(i)\couleur   
            ; ici
            
            etre(i)\posx=RotationX(etre(i)\posx, etre(i)\angle.f, etre(i)\pas_x)  
            etre(i)\posy=RotationY(etre(i)\posy, etre(i)\angle.f, etre(i)\pas_y)
            
            ; ********* condition de collision et sortie d'ecran ****************************
            ; sortie d'ecran
            If etre(i)\posx >EcranX
                  etre(i)\posx=1
            EndIf
            If etre(i)\posy >EcranY
                  etre(i)\posy=1
            EndIf
            If etre(i)\posx <=0
                  etre(i)\posx=EcranX-1
            EndIf
            If etre(i)\posy <=0
                  etre(i)\posy=EcranY-1
            EndIf 
            ;************************************************************************
            
            ; *************** regle de collision entre eux ******************************
            flag=0
            For i2=1 To nombre_de_chmol
                  If i2<>etre(i)\id And etre(i)\vie>0  ; on ne test pas le sprite en cours d'observation pour une collision avec lui-meme et qu'il est vivant
                        If SpritePixelCollision(i2, etre(i2)\posx,etre(i2)\posy, etre(i)\id,  etre(i)\posx,etre(i)\posy)  
                              
                              ;******** changement de la direction suivant la collision ***************
                              If etre(i)\posx <etre(i2)\posx
                                    etre(i)\pas_x =-2
                              EndIf
                              If etre(i)\posx >etre(i2)\posx
                                    etre(i)\pas_x =2
                              EndIf
                              If etre(i)\posy <etre(i2)\posy
                                    etre(i)\pas_y =-2
                              EndIf
                              If etre(i)\posy >etre(i2)\posy
                                    etre(i)\pas_y =2
                              EndIf 
                              
                              ; ******* rencontre male+male ou femelle+femelle ***********
                              If etre(i2)\sex=etre(i)\sex And effet2=0
                                    etre(i)\posx=-100 ; pour tuer les chmol on triche
                                    etre(i)\posy=-100 ; on les mets en dehor de l'ecran
                                    etre(i)\pas_x=0 ; et on les exclus des test de collision
                                    etre(i)\pas_y=0 
                                    etre(i2)\posx=-100 
                                    etre(i2)\posy=-100  
                                    etre(i2)\pas_x=0
                                    etre(i2)\pas_y=0 
                                    
                                    etre(i)\vie=0   ; en utilisant cette variable on sait que le chmol vie ou pas
                                    etre(i2)\vie=0   
                                    compteur=compteur-2
                                    effet2 =1
                              EndIf
                              ; ****************************************************
                              
                              
                              
                              ;-Reproduction
                              ; ******************  REPRODUCTION  ************
                              If etre(i2)\sex<>etre(i)\sex And effet=0  ; rencontre male+femele 
                                    
                                    nombre_de_chmol=nombre_de_chmol+1 ; ajout d'un etre vivant
                                    compteur=compteur+1
                                    Redim etre.etre(nombre_de_chmol)
                                    ; recupere les parametres  de ses deux parents !!
                                    ; posx=EcranX/2; les bb naissent au millieu de l'ecran
                                    ; posy=EcranY/2
                                    posx=etre(i)\posx
                                    posy=etre(i2)\posy 
                                    pas_x=etre(i2)\pas_x
                                    pas_y=etre(i)\pas_y
                                    sex=Random(1) ; sex aleatoire
                                    
                                    ; gestion de la future couleur du bb
                                    ; couleur d'un des 2 parents
                                    rouge1=Red(etre(i)\couleur)
                                    vert1=Green(etre(i)\couleur)
                                    bleue1=Blue(etre(i)\couleur)
                                    
                                    ; couleur de l'autre
                                    rouge2=Red(etre(i2)\couleur)
                                    vert2=Green(etre(i2)\couleur)
                                    bleue2=Blue(etre(i2)\couleur)
                                    
                                    ; on mix !! 
                                    couleur=RGB(rouge1,vert1,bleue2)
                                    
                                    ; mixage de la forme 
                                    StartDrawing(SpriteOutput(etre(i)\id)) 
                                          Global  Dim tab(32,32)
                                          For y=1 To 31
                                                For x=1 To 16 
                                                      tab(x,y)=Point(x,y) 
                                                Next x
                                          Next y 
                                    StopDrawing()
                                    StartDrawing(SpriteOutput(etre(i2)\id))
                                          For y=1 To 31
                                                For x=16 To 31 
                                                      tab(x,y)=Point(x,y) 
                                                Next x
                                          Next y 
                                    StopDrawing() 
                                    forme=3
                                    effet =1
                                    effet2 =1 ; empeche la mort de frapper au moment de la naissance
                                    create_chmol(nombre_de_chmol,posx,posy,pas_x,pas_y,vie,sex,couleur,forme,angle) ; creation du BB                                     
                              EndIf 
                        EndIf
                        
                  EndIf
            Next i2 
            ; *********************************************************************
            
            ; ******* affichage du sprite ****************************************
            If etre(i)\vie>0 
                  
                  
                  ;   DisplayTransparentSprite ( id , etre(i)\posx,  etre(i)\posy) ; affiche le sprite au coordonées modifié par les touches 
                  Start3D()
                        RotateSprite3D(id , etre(i)\angle,0)
                        DisplaySprite3D( id , etre(i)\posx,  etre(i)\posy,255)
                  Stop3D()
            EndIf
            
            ; **************************************************************** 
      Next i 
      
      ; *************** affiche l'ecran ********************************
      FlipBuffers (): ; affiche l'ecran
      ; **************************************************************
      ; ***********************************************************************************
      
      ; **** ok on nettoie pour le prochain affichage **********************
      ClearScreen ( RGB (0, 0, 0)) : ;efface l'ecran
      ; ***************************************************************
      
      event= WindowEvent ()
      Delay (2)
Until event= #PB_Event_CloseWindow Or KeyboardPushed ( #PB_Key_Escape ) ; press touche droit 
Procedure create_chmol(id,posx,posy,pas_x,pas_y,vie,sex,couleur,forme,angle.f)
      ;-creation chmol
      ; ******* creation d'un chmol ************ 
      etre(id)\id =id 
      etre(id)\posx =posx 
      etre(id)\posy =posy 
      etre(id)\pas_x =pas_x  
      etre(id)\pas_y =pas_y  
      etre(id)\vie =vie 
      etre(id)\sex.b =sex 
      etre(id)\couleur.l =couleur 
      etre(id)\angle =angle.f 
      If CreateSprite (etre(id)\id,32,32,#PB_Sprite_Texture) ; on creer un sprite vide (une cellule) de 32 par 32 et on lui donne le numero 1
            StartDrawing ( SpriteOutput (etre(id)\id) ) ; on va dessiner dedans ! 
                  If forme=0
                        Circle (16,16,16, etre(id)\couleur.l ) ; on dessine un cercle rouge
                  EndIf
                  If forme=1
                        Box(0,0,32,32,etre(id)\couleur.l )
                  EndIf
                  If forme=3  
                        For y=1 To 31
                              For x=1 To 16
                                    Plot(x,y, tab(x,y))
                              Next x
                        Next y 
                        For y=1 To 31
                              For x=16 To 31
                                    Plot(x,y, tab(x,y))
                              Next x
                        Next y   
                  EndIf 
                  If etre(id)\sex.b=1 
                        DrawText(12, 12, "M",RGB(0,0,0), RGB(255,255,255))
                  Else 
                        DrawText(12, 12, "F",RGB(0,0,0), RGB(255,255,255))
                  EndIf
            StopDrawing ()
      EndIf 
      ; ******************************************
      CreateSprite3D(etre(id)\id, etre(id)\id)
EndProcedure
Procedure TimerProc(hwnd.l, uMsg.l, idEvent.l, dwTime.l)
      Select uMsg
            Case #WM_TIMER
                  Select idEvent
                        Case 1 
                              effet=0  ; permet une reproduction a nouveau toute les 2 secondes
                        Case 2
                              effet2=0 ; permet de faire mourrir 2 male ou 2 femelle qui se collisionnent
                              
                        Case 3
                              For i4=1 To nombre_de_chmol 
                                    etre(Random(nombre_de_chmol))\angle.f=Random(90) 
                              Next i4
                  EndSelect
      EndSelect
EndProcedure
Procedure.f RotationX(x, angle.f, dist)
      ProcedureReturn x + Cos (angle.f* #PI /180)*dist
EndProcedure
    
    
Procedure.f RotationY(y, angle.f, dist)
      ProcedureReturn y + Sin (angle.f* #PI /180)*dist
EndProcedure