Tom's Guide > Forum > Programmation > Visual basic: programmation d'un jeu de vie [MA QUESTION EST TOUT EN BAS]

Visual basic: programmation d'un jeu de vie [MA QUESTION EST TOUT EN BAS]

Forum Programmation : Visual basic: programmation d'un jeu de vie [MA QUESTION EST TOUT EN BAS]

TomsGuide.com : 800 000 inscrits répondent à toutes vos questions high-tech et informatique. Pour obtenir de l'aide, inscrivez-vous gratuitement !
Mot :    Pseudo :           
 

Bonjour à tous,


J'ai un projet à réaliser en visual basic. Je connais assez bien le langage de programmation (boucle, booléen...etc...) mais, mon gros problème réside dans le fait que j'ai beaucoup de mal à analyser le sujet pour le découper en une série de sous programme.

Je souhaiterais avoir un peu d'aide pour démarrer mon projet. Merci

Citation :

Le but de ce projet est de simuler un jeu de la vie. Le jeu de la vie est le plus célèbre des automates cellulaires. Il a été inventé par John Conway et popularisé dans la rubrique de Martin Gardner du magazine américain "Scientific American" d'octobre 1970.

Le jeu de la vie consiste à faire naître, vivre ou mourir des cellules. Celles-ci sont disposées sur une grille carrée. Chaque case de la grille contient une cellule. Initialement une cellule est soit "en vie" soit "morte". A chaque génération, les cellules évoluent en fonction de l’état de leurs voisines, en suivant une loi d’évolution.

Par exemple, une loi d’évolution peut être :
• Une cellule en vie meurt si elle a plus de 3 voisins morts,
• Une cellule en vie survit si elle a exactement 2 voisins en vie,
• Une cellule morte naît si elle a exactement 3 voisins en vie.
Les cases voisines d’une case donnée sont les quatre cases adjacentes, c’est-à-dire les cases ayant au moins un côté en commun.

D’autres règles d’évolution sont envisageables. Lors d’une exécution, toutes les cellules suivent la même règle d’évolution.

Vous réaliserez une application en Visual basic qui affiche à l’écran à chaque génération l’état des cellules sur la grille, ainsi que des informations sur l’évolution des populations de cellules en vie ou mortes. La grille sera initialisée en fonction du pourcentage de cellules en vie donné par l’utilisateur au lancement de l’application. Vous pourrez envisager de laisser l’utilisateur choisir une règle d’évolution parmi une liste de règles disponibles.


Code :
  1. Option Explicit
  2. Const col_max = 15
  3. Const row_max = 15
  4. Tableau_cellules(1 To col_max, 1 To row_max) As String
  5. Sub affich()
  6. Dim i As String
  7. Dim j As String
  8. Dim x As String
  9. For i = 1 To col_max
  10.     For j = 1 To row_max
  11.    
  12.     x = cellule_hazard() 'Fais appel à une procédure qui va choisir si la cellule est morte ou vivante
  13.     Call mort_ou_vie(i, j, x)
  14.     Next j
  15.     Next i
  16. End Sub
  17. Sub mort_ou_vie(a, b, i)
  18. If i = False Then
  19.   ms.Col = a
  20.   ms.Row = b
  21.   ms.Text = "M"
  22. Else
  23.   ms.Col = a
  24.   ms.Row = b
  25.   ms.Text = "V"
  26.      
  27. End Sub


Voila mes premier algo. J'ai un problème pour créer une procédure (ou une fonction?) qui me sort aléatoirement une valeur (je sais que ça sera un booléen).
Je dois me servir de l'objet "ramdomize" mais je ne suis pas sur de moi pour la syntaxe.
Mon deuxième problème est la manière par laquelle j'aurai par exemple 40% de cellules vivantes au départ.

Merci de votre aide

Liens sponsorisés
Inscrivez-vous ou connectez-vous pour masquer ceci.

salut,

pour ce qui est de la syntaxe en VB, j'utilise rarement VB.NET mais la syntaxe est la suivante :

Code :
  1. Randomize  'oui c'est tout :), ça permet d'avoir un tirage différent à chaque lancement du programme



apres pour tirer un chiffre aléatoirement avec un biais, tu peux par exemple créer une fonction du type :
(je ne t'assure pas l'exactitude la syntaxe ...)

Code :
  1. Function TirageBiaise(ByVal biais As Integer) As Boolean
  2.     Dim tirage As Integer
  3.     tirage = CInt(Int((100 * Rnd()) + 1)) ' Generate random value between 1 and 100
  4.     if tirage<biais then
  5.         return true
  6.     else
  7.         return false
  8.     end if
  9. End Function



Avec cette fonction, si tu rentre 40 en paramètre, alors dans 40% des cas elle te renverra true (si bien sûr la distribution de Rnd est normale :))

Attention, quand tu va analyser ton plateau pour connaître le nouvel état de cellule il faut bien que tu utilises 2 tableaux différents. Un qui contient l'état en cours et l'autre qui contient l'état modifié.
En pour tester chaque cellule, il faut commencer par tester les cas par ordre de prioirité (une cellule vivante entouré de 3 voisines est forcement entouré de 2 voisines ...)

Enfin, il faut penser à ce que tu vas faire pour les cases sur les bords du plateau.

Bon courage.

Répondre à ataofeal

Merci beaucoup pour ces éléments de réponses :)

Si j'ai bien compris, lorsque je vais faire appelle à cette fonction et que je voudrais obtenir par exemple 40% de cellule vivante, je devrais écrire:

Code :
  1. Call Function TirageBiaise(ByVal 40 As Integer)


C'est bien ça?

De plus dans mon cas, le nombre de case seront prédéfénies.
Pour un carré de 20*20 donc 400 cellules, est ce que je dois écrire:

Code :
  1. Function TirageBiaise(ByVal biais As Integer) As Boolean
  2.     Dim tirage As Integer
  3.     tirage = CInt(Int(((col_max*row_max) * Rnd()) + 1)) ' Generate random value between 1 and 400
  4.     if tirage<biais then
  5.         return true
  6.     else
  7.         return false
  8.     end if
  9. End Function




Citation :

Enfin, il faut penser à ce que tu vas faire pour les cases sur les bords du plateau.


Je sens que ça va aussi me poser des problème :-( :-(

Répondre à mauriiiice

Pour le bord du tableau, comme pour un démineur, tu peux ajouter une colone à gauche et à droite, et une ligne en haut et en bas supplémentaire.
Ces cases seront interdites pour les déplacements, mais pour faire les tests autour d'une cellule, c'est plus facile à faire, car il n'y a pas de cas particulier.

Répondre à CRicky

Citation :

Si j'ai bien compris, lorsque je vais faire appelle à cette fonction et que je voudrais obtenir par exemple 40% de cellule vivante, je devrais écrire:

Code :
  1. Call Function TirageBiaise(ByVal 40 As Integer)



C'est bien ça?


heu non, il me semble que tu devras faire :

Code :
  1. Dim res as Boolean
  2. res=TirageBiaise(40)



Citation :


De plus dans mon cas, le nombre de case seront prédéfénies.
Pour un carré de 20*20 donc 400 cellules, est ce que je dois écrire:

Code :
  1. ...
  2.         tirage = CInt(Int(((col_max*row_max) * Rnd()) + 1)) ' Generate random value between 1 and 400




non non, en fait le 100 permet de donner un rapport en pourcentage.
La formule que je t'ai donné te permet d'avoir statistiquement des tirages au pourcentage défini, mais pas surement.
Si tu veux un tirage sûr alors il faut tirer des valeurs avec retirage en cas de doublon, jusqu'à obtention de ton pourcentage.

Pour les cases sur les bords, y'a un truc sympa à faire , c'est considérer que grossierement ton plateau est une sphère. Donc une case complètement à gauche a une voisine sur la même ligne complètement à droite.

Répondre à ataofeal

J'ai apporté quelques modifications:

Code :
  1. Option Explicit
  2. Const n = 40
  3. Au préalable, le nombre de case correspondant à 40% de mon tableau sera calculé:



Code :
  1. Pourcentage_cell_vie = (((col_max * row_max) / n) / 100)


=40% des cases de mon carré
Ensuite, je ferais appelle à la fonction:

Code :
  1. Dim res as Boolean
  2. res=TirageBiaise(Pourcentage_cell_vie)


Code :
  1. Function TirageBiaise(ByVal biais As Integer) As Boolean
  2.     Dim tirage As Integer
  3.     Dim V_ou_M As Boolean
  4.     tirage = CInt(Int((100 * Rnd()) + 1)) ' Generate random value between 1 and 100
  5.     If tirage <= biais Then  'Inférieur ou égal à 40%
  6.         V_ou_M = True
  7.        
  8.     Else
  9.         V_ou_M = False
  10.     End If
  11.     biais = V_ou_M  'Car la fonction doit renvoyer une valeur "true" ou "false"
  12. End Function



Vous en pensez quoi?

(désolé si je fais des erreurs conne, je suis loin d'être un expert...)

Répondre à mauriiiice

juste je reprécise ce que j'ai dit, la fonction TirageBiaise de garantie que statistiquement tu auras un remplissage de "biais"% (je sais pas pourquoi je l'ai appelé comme ça cet argument ...).

Il te manque un

Code :
  1. Return biais

à la fin de ta fonction TirageBiaise

[edit]heu non pas un return biais, biais est un Integer et V_ou_M est un booléen. Il te manque un

Code :
  1. return V_ou_M

Répondre à ataofeal

Je le place de cette façon?

Code :
  1. Function TirageBiaise(ByVal biais As Integer) As Boolean
  2.     Dim tirage As Integer
  3.     Dim V_ou_M As Boolean
  4.     tirage = CInt(Int((100 * Rnd()) + 1)) ' Generate random value between 1 and 100
  5.     If tirage <= biais Then  'Inférieur ou égal à 40%
  6.         V_ou_M = True
  7.        
  8.     Else
  9.         V_ou_M = False
  10.     End If
  11. return V_ou_M
  12.     biais = V_ou_M  'Car la fonction doit renvoyer une valeur "true" ou "false"
  13. End Function



En tout cas, merci de ton aide :-)

Répondre à mauriiiice

oui, sauf que tu supprimes ton

Code :
  1. biais = V_ou_M

à la fin de ta fonction.

Sinon en fait je pense qu'il y a une meilleur solution.
C'est d'initialiser ton tableau avec le nombre exact de case que tu veux.

Tu définis ta constante du nombre de case (cas simple d'un tableau non dynamique)

Code :
  1. Const nCell = 400



Tu définis la fonction d'init :

Code :
  1. Function initPlateau(ByVal nbVivant As Integer, ByRef plateau As Array)
  2.         Randomize()
  3.         Dim i As Integer
  4.         Dim cell As Integer
  5.         For i = 0 To nCell - 1
  6.             plateau(i) = False 'tu vides  ton tableau
  7.         Next
  8.         i = 0
  9.       'tu rajoutes des cellules vivantes aléatoirement jusqu'au nombre voulu
  10.         While i < nbVivant
  11.             cell = CInt(Int(Rnd() * nCell ) + 1)
  12.             If plateau(cell) = False Then
  13.                 plateau(cell) = True
  14.                 i = i + 1
  15.             End If
  16.         End While
  17.     End Function



tu appelles ta fonction quelque part initialisant ton tableau :

Code :
  1. Dim tableau(nCell) As Boolean
  2. initPlateau(200, tableau)



Mais bon ce ne sont que des pistes.

Bon courage.

Répondre à ataofeal

Citation :

Mais bon ce ne sont que des pistes.


Pas mal du tout! Je vais tester cette approche!

En fait, mon second tableau aura par défaut que des valeurs "false".
Le placement des cellules vivante sera bien effectué dans un tableau à deux dimensions?

Répondre à mauriiiice

disons que c'était une méthode avec un seul vecteur et après tu pouvais jouer avec les indices pour te créer un tableau.
Mais VB te propose les tableaux, alors tu peux également tout faire en 2D :

tu déclares :

Code :
  1. Const nLine = 20
  2.     Const nRow = 20



tu crées une fonction init en 2D

Code :
  1. Function initPlateau2D(ByVal nbVivant As Integer, ByRef plateau As Array)
  2.         Randomize()
  3.         Dim i, j As Integer
  4.         Dim row, line As Integer
  5.         For i = 0 To nRow - 1
  6.             For j = 0 To nLine - 1
  7.                 plateau(i, j) = False
  8.             Next
  9.         Next
  10.         i = 0
  11.         While i < nbVivant
  12.             row = CInt(Int(Rnd() * nRow) + 1)
  13.             line = CInt(Int(Rnd() * nLine) + 1)
  14.             If plateau(line - 1, row - 1) = False Then
  15.                 plateau(line - 1, row - 1) = True
  16.                 i = i + 1
  17.             End If
  18.         End While
  19.     End Function



et tu appelles ta fonction avec un tableau en 2D

Code :
  1. Dim tableau2D(nRow - 1, nLine - 1) As Boolean
  2. initPlateau2D(10, tableau2D)



Sur ce je me rentre moi :-D

Répondre à ataofeal

Il y a quelque chose que je n'arrive pas à comprendre:
Je n'arrivais pas à afficher des trucs dans mon tableau (élément MSflexgrid) alors j'ai fais une mini procédure qui me met une valeur dans chaque case afin de trouver la bonne syntaxe.

Code :
  1. Option Explicit
  2. Const col_max = 15
  3. Const row_max = 15
  4. Dim Tableau_cellules(1 To col_max, 1 To row_max)
  5. Sub remp1(ms As MSFlexGrid)
  6. Dim i As Integer
  7. Dim j As Integer
  8. For i = 1 To col_max
  9.     For j = 1 To row_max
  10.     Tableau_cellules(i, j) = ((i + j) * 2)
  11.     ms.Col = i - 1
  12.     ms.Row = j - 1
  13.       ms.Text = Tableau_cellules(i, j)
  14.  
  15.     Next j
  16.     Next i
  17.          
  18. End Sub


Voila la procedure qui appelle "remp1":

Code :
  1. Private Sub Command5_Click()
  2. Call remp1(MSFlexGrid1)
  3. End Sub




Au départ, j'avais mis:
ms.col = i
ms.row = j
Et mon programme (je devrais pas mettre une fonction à la place?) bugé, j'ai regardé la valeur des variables "i" et "j" et j'ai du mettre (i - 1) et (j - 1) mais je n'arrive pas à comprendre pourquoi.

Répondre à mauriiiice

je pense simplement que l'objet MSFlexgrid doit être appelé en commençant à l'indice 0 (comme n'importe quel tableau dans la plupart des langages).
Donc si tu as déclaré ton composant MSFlexgrid comme ayant col_max colonnes alors les indices colonnes de composant irons de 0 à (col_max-1) (ce qui fait bien col_max indices, et idem pour row_max)

Donc ton programme devait planté quand tu arrivais à l'indice i=col_max ou j=row_max.

Citation :

je devrais pas mettre une fonction à la place?


J'ai pas compris?

Répondre à ataofeal

C'était bien ça! L'objet Msflexgrid commence à 0, je n'y avais pas pensé du tout... Quel con...

Citation :

J'ai pas compris?


Est ce que je dois mettre "Sub remp1(ms As MSFlexGrid)"
ou
"Function remp1(ms As MSFlexGrid)"

J'ai du mal à faire la distinction.
Si j'ai bien compris: ce sous programme ne renvoit aucune valeur, il rempli un tableau donc c'est une procédure et c'est "sub" que je dois mettre? C'est ça?

Répondre à mauriiiice

heu ... honnêtement j'en sais rien.

Voilà ce qui est dit dans la doc MSDN :

Citation :

Une procédure Sub, à l'instar d'une procédure Function, est une procédure distincte qui peut prendre en charge des arguments et exécuter une série d'instructions. Toutefois, contrairement à une procédure Function, qui retourne une valeur, une procédure Sub ne peut pas être utilisée dans une expression



Donc d'après eux, la seule différence est que la procédure ne renvoit pas d'argument ... mais comme il est possible d'appeler une fonction avec un call je ne vois pas vraiment l'interêt.

Sur certains site, ils parlent de différence de performances qui seraient meilleurs avec les Sub ...

En tout cas il y a certaintement un interêt à Sub sur function puisque la méthode new (entre autre) d'une Form , généré automatiquement sous VS.NET est déclarée en tant que sub et non en tant que function.

Je laisse la place aux spécialistes en VB pour le choix. :-D

Répondre à ataofeal

J'ai pas tout lu
A la base des langages procéduraux (comme le pascal), il faut distinguer les procédures des fonctions (le C ne faisant pas de distinction car une procédure est une fonction retournant void).
D'un point de vue conceptuel, le Sub est l'éxécution d'un code qui par exemple fait appel à un périphérique, alors qu'une fonction est plus un calcul qui ne toucherait pas ou peu un périphérique.
Mais bon je suis surpris que ça existe encore, comme avec le vieux QBasic :-D

Répondre à CRicky

Merci :-D

J'ai une autre petite question: j'ai un tableau à deux dimensions:


Code :
  1. Dim Tableau_cellules(1 To col_max, 1 To row_max)


Comment puis je faire pour que les valeurs présentes dans chaque case soient mélangés dans le même tableau?

Répondre à mauriiiice

Tu boucles sur tous les élément du tableau, et pour chaque élément, tu faits une permutation avec une case choisie aléatoirement entre la case courante (comprise) et la fin du tableau.

Répondre à CRicky

WEp! J'ai réussi avec une autre approche!

J'ai un autre problème:
Je n'arrive pas à mettre les bonnes variables: a chaque fois, j'ai le message d'erreur...

[RESOLU]

Répondre à mauriiiice

Code :
  1. Option Explicit
  2. Const Longmax = 10
  3. Dim Tableau_cellules(1 To Longmax, 1 To Longmax) As String
  4. Dim Tvie(1 To Longmax, 1 To Longmax) As Boolean
  5. Const nbCellV = 20
  6. Private Sub Command2_Click()
  7.     Call InitTV(Tvie())
  8.     Call InitTabcell(MSFlexGrid1)
  9.     Call hazard2(Tvie())
  10. End Sub
  11. Sub InitTabcell(ms2 As MSFlexGrid)
  12. Dim i As Integer
  13. Dim j As Integer
  14. For i = 1 To Longmax
  15.     For j = 1 To Longmax
  16.         Tableau_cellules(i, j) = ""
  17.         ms2.Col = i - 1
  18.         ms2.Row = j - 1
  19.         ms2.Text = Tableau_cellules(i, j)
  20.     Next j
  21. Next i
  22. End Sub
  23. Private Sub Command6_Click()
  24.     Call initJeu(nbCellV, Tvie()) 'Fais appel à une procédure qui va choisir si la cellule est morte ou vivante
  25. End Sub
  26. Sub InitTV(tvi() As Boolean)
  27. Dim i As Integer
  28. Dim j As Integer
  29.     For i = 1 To Longmax
  30.         For j = 1 To Longmax
  31.             tvi(i, j) = False
  32.         Next j
  33.     Next i
  34. End Sub
  35. Sub hazard2(tvi() As Boolean)
  36. Dim MaVal As Integer
  37. Dim MaVal2 As Integer
  38. Dim i As Integer
  39. For i = 1 To nbCellV
  40. ligne1:
  41.     Randomize  ' Initialise le générateur de hazard
  42.     MaVal = CInt(Int((Longmax * Rnd()) + 1))
  43.     MaVal2 = CInt(Int((Longmax * Rnd()) + 1))
  44.         If tvi(MaVal, MaVal2) = True Then
  45.         GoTo ligne1
  46.             Else
  47.             tvi(MaVal, MaVal2) = True
  48.         End If
  49. Next i
  50. End Sub
  51. Private Sub Command1_Click()
  52.     Call debut_cycle(MSFlexGrid1)
  53. End Sub
  54. Sub debut_cycle(ms As MSFlexGrid)
  55. Dim i As Integer
  56. Dim j As Integer
  57. For i = 1 To Longmax
  58.     For j = 1 To Longmax
  59.     Call mort_ou_vie(i, j, ms, Tvie())
  60.     Next j
  61. Next i
  62. End Sub
  63. Function mort_ou_vie(a As Integer, b As Integer, ms1 As MSFlexGrid, tvi() As Boolean)
  64. For a = 1 To Longmax
  65.     For b = 1 To Longmax
  66.    
  67.         If tvi(a, b) = False Then
  68.         Tableau_cellules(a, b) = "M"
  69.         ms1.Col = a - 1
  70.         ms1.Row = b - 1
  71.         ms1.Text = Tableau_cellules(a, b)
  72.        
  73.             Else
  74.             Tableau_cellules(a, b) = "V"
  75.             ms1.Col = a - 1
  76.             ms1.Row = b - 1
  77.             ms1.Text = Tableau_cellules(a, b)
  78.            
  79.         End If
  80.     Next b
  81. Next a
  82. End Function


Ce code me permet d'afficher dans un tableau et de façon aléatoire 100 cellules: 20 sont vivantes("V" ) et 80 sont mortes ("M" ).
Le programme fonctionne, il n'y a pas de problème.(Merci à tous ceux qui m'ont aidé)

Je souhaiterais avoir quelques renseignements concernant l'interface graphique:
- quel est le nom du truc qui me permet d'avoir des cellules carrés (les redimentionner)
- comment puisse faire pour que la cellule soit colorié en verte à la place de "V" (vivante) et rouge pour "M" (morte)?

Merci

Répondre à mauriiiice
Tom's Guide > Forum > Programmation > Visual basic: programmation d'un jeu de vie [MA QUESTION EST TOUT EN BAS]
Aller à :

Il y a 2240 utilisateurs connus et inconnus. Pour voir la liste des connectés connus, cliquez ici.

Attention

Vous allez répondre sur un sujet resté inactif pendant plus de 6 mois.
Assurez-vous d'apporter des éléments nouveaux à la discussion avant de poursuivre.

Répondre Annuler
Liens