Visual basic: programmation d'un jeu de vie [MA QUESTION EST TOUT EN BAS]
Dernière réponse : dans Programmation
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
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.
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
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.
Option Explicit
Const col_max = 15
Const row_max = 15
Tableau_cellules(1 To col_max, 1 To row_max) As String
Sub affich()
Dim i As String
Dim j As String
Dim x As String
For i = 1 To col_max
For j = 1 To row_max
x = cellule_hazard() 'Fais appel à une procédure qui va choisir si la cellule est morte ou vivante
Call mort_ou_vie(i, j, x)
Next j
Next i
End Sub
Sub mort_ou_vie(a, b, i)
If i = False Then
ms.Col = a
ms.Row = b
ms.Text = "M"
Else
ms.Col = a
ms.Row = b
ms.Text = "V"
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
Autres pages sur : visual basic programmation jeu vie question bas
Lassé par la pub ? Créez un compte
salut,
pour ce qui est de la syntaxe en VB, j'utilise rarement VB.NET mais la syntaxe est la suivante :
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 ...)
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.
pour ce qui est de la syntaxe en VB, j'utilise rarement VB.NET mais la syntaxe est la suivante :
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 ...)
Function TirageBiaise(ByVal biais As Integer) As Boolean
Dim tirage As Integer
tirage = CInt(Int((100 * Rnd()) + 1)) ' Generate random value between 1 and 100
if tirage<biais then
return true
else
return false
end if
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.
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:
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:
Je sens que ça va aussi me poser des problème :-( :-(
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:
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:
Function TirageBiaise(ByVal biais As Integer) As Boolean
Dim tirage As Integer
tirage = CInt(Int(((col_max*row_max) * Rnd()) + 1)) ' Generate random value between 1 and 400
if tirage<biais then
return true
else
return false
end if
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 :-( :-(
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.
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.
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:
Call Function TirageBiaise(ByVal 40 As Integer)
C'est bien ça?
heu non, il me semble que tu devras faire :
Dim res as Boolean
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:
...
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.
J'ai apporté quelques modifications:
=40% des cases de mon carré
Ensuite, je ferais appelle à la fonction:
Vous en pensez quoi?
(désolé si je fais des erreurs conne, je suis loin d'être un expert...)
Option Explicit
Const n = 40
Au préalable, le nombre de case correspondant à 40% de mon tableau sera calculé:
Pourcentage_cell_vie = (((col_max * row_max) / n) / 100)
=40% des cases de mon carré
Ensuite, je ferais appelle à la fonction:
Dim res as Boolean
res=TirageBiaise(Pourcentage_cell_vie)
Function TirageBiaise(ByVal biais As Integer) As Boolean
Dim tirage As Integer
Dim V_ou_M As Boolean
tirage = CInt(Int((100 * Rnd()) + 1)) ' Generate random value between 1 and 100
If tirage <= biais Then 'Inférieur ou égal à 40%
V_ou_M = True
Else
V_ou_M = False
End If
biais = V_ou_M 'Car la fonction doit renvoyer une valeur "true" ou "false"
End Function
Vous en pensez quoi?
(désolé si je fais des erreurs conne, je suis loin d'être un expert...)
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
[edit]heu non pas un return biais, biais est un Integer et V_ou_M est un booléen. Il te manque un
Il te manque un
à la fin de ta fonction TirageBiaise
Return biais
[edit]heu non pas un return biais, biais est un Integer et V_ou_M est un booléen. Il te manque un
return V_ou_M
Je le place de cette façon?
En tout cas, merci de ton aide :-)
Function TirageBiaise(ByVal biais As Integer) As Boolean
Dim tirage As Integer
Dim V_ou_M As Boolean
tirage = CInt(Int((100 * Rnd()) + 1)) ' Generate random value between 1 and 100
If tirage <= biais Then 'Inférieur ou égal à 40%
V_ou_M = True
Else
V_ou_M = False
End If
return V_ou_M
biais = V_ou_M 'Car la fonction doit renvoyer une valeur "true" ou "false"
End Function
En tout cas, merci de ton aide :-)
oui, sauf que tu supprimes ton
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)
Tu définis la fonction d'init :
tu appelles ta fonction quelque part initialisant ton tableau :
Mais bon ce ne sont que des pistes.
Bon courage.
à la fin de ta fonction.
biais = V_ou_M
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)
Const nCell = 400
Tu définis la fonction d'init :
Function initPlateau(ByVal nbVivant As Integer, ByRef plateau As Array)
Randomize()
Dim i As Integer
Dim cell As Integer
For i = 0 To nCell - 1
plateau(i) = False 'tu vides ton tableau
Next
i = 0
'tu rajoutes des cellules vivantes aléatoirement jusqu'au nombre voulu
While i < nbVivant
cell = CInt(Int(Rnd() * nCell ) + 1)
If plateau(cell) = False Then
plateau(cell) = True
i = i + 1
End If
End While
End Function
tu appelles ta fonction quelque part initialisant ton tableau :
Dim tableau(nCell) As Boolean
initPlateau(200, tableau)
Mais bon ce ne sont que des pistes.
Bon courage.
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 :
tu crées une fonction init en 2D
et tu appelles ta fonction avec un tableau en 2D
Sur ce je me rentre moi :-D
Mais VB te propose les tableaux, alors tu peux également tout faire en 2D :
tu déclares :
Const nLine = 20
Const nRow = 20
tu crées une fonction init en 2D
Function initPlateau2D(ByVal nbVivant As Integer, ByRef plateau As Array)
Randomize()
Dim i, j As Integer
Dim row, line As Integer
For i = 0 To nRow - 1
For j = 0 To nLine - 1
plateau(i, j) = False
Next
Next
i = 0
While i < nbVivant
row = CInt(Int(Rnd() * nRow) + 1)
line = CInt(Int(Rnd() * nLine) + 1)
If plateau(line - 1, row - 1) = False Then
plateau(line - 1, row - 1) = True
i = i + 1
End If
End While
End Function
et tu appelles ta fonction avec un tableau en 2D
Dim tableau2D(nRow - 1, nLine - 1) As Boolean
initPlateau2D(10, tableau2D)
Sur ce je me rentre moi :-D
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.
Voila la procedure qui appelle "remp1":
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.
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.
Option Explicit
Const col_max = 15
Const row_max = 15
Dim Tableau_cellules(1 To col_max, 1 To row_max)
Sub remp1(ms As MSFlexGrid)
Dim i As Integer
Dim j As Integer
For i = 1 To col_max
For j = 1 To row_max
Tableau_cellules(i, j) = ((i + j) * 2)
ms.Col = i - 1
ms.Row = j - 1
ms.Text = Tableau_cellules(i, j)
Next j
Next i
End Sub
Voila la procedure qui appelle "remp1":
Private Sub Command5_Click()
Call remp1(MSFlexGrid1)
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.
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.
J'ai pas compris?
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?
C'était bien ça! L'objet Msflexgrid commence à 0, je n'y avais pas pensé du tout... Quel con...
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?
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?
heu ... honnêtement j'en sais rien.
Voilà ce qui est dit dans la doc MSDN :
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
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 expressionDonc 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
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
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
Option Explicit
Const Longmax = 10
Dim Tableau_cellules(1 To Longmax, 1 To Longmax) As String
Dim Tvie(1 To Longmax, 1 To Longmax) As Boolean
Const nbCellV = 20
Private Sub Command2_Click()
Call InitTV(Tvie())
Call InitTabcell(MSFlexGrid1)
Call hazard2(Tvie())
End Sub
Sub InitTabcell(ms2 As MSFlexGrid)
Dim i As Integer
Dim j As Integer
For i = 1 To Longmax
For j = 1 To Longmax
Tableau_cellules(i, j) = ""
ms2.Col = i - 1
ms2.Row = j - 1
ms2.Text = Tableau_cellules(i, j)
Next j
Next i
End Sub
Private Sub Command6_Click()
Call initJeu(nbCellV, Tvie()) 'Fais appel à une procédure qui va choisir si la cellule est morte ou vivante
End Sub
Sub InitTV(tvi() As Boolean)
Dim i As Integer
Dim j As Integer
For i = 1 To Longmax
For j = 1 To Longmax
tvi(i, j) = False
Next j
Next i
End Sub
Sub hazard2(tvi() As Boolean)
Dim MaVal As Integer
Dim MaVal2 As Integer
Dim i As Integer
For i = 1 To nbCellV
ligne1:
Randomize ' Initialise le générateur de hazard
MaVal = CInt(Int((Longmax * Rnd()) + 1))
MaVal2 = CInt(Int((Longmax * Rnd()) + 1))
If tvi(MaVal, MaVal2) = True Then
GoTo ligne1
Else
tvi(MaVal, MaVal2) = True
End If
Next i
End Sub
Private Sub Command1_Click()
Call debut_cycle(MSFlexGrid1)
End Sub
Sub debut_cycle(ms As MSFlexGrid)
Dim i As Integer
Dim j As Integer
For i = 1 To Longmax
For j = 1 To Longmax
Call mort_ou_vie(i, j, ms, Tvie())
Next j
Next i
End Sub
Function mort_ou_vie(a As Integer, b As Integer, ms1 As MSFlexGrid, tvi() As Boolean)
For a = 1 To Longmax
For b = 1 To Longmax
If tvi(a, b) = False Then
Tableau_cellules(a, b) = "M"
ms1.Col = a - 1
ms1.Row = b - 1
ms1.Text = Tableau_cellules(a, b)
Else
Tableau_cellules(a, b) = "V"
ms1.Col = a - 1
ms1.Row = b - 1
ms1.Text = Tableau_cellules(a, b)
End If
Next b
Next a
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
Lassé par la pub ? Créez un compte
- Contenus similaires :
Tags :
- ForumProgrammation web sous visual basic 6.0
- solutionsComment cree un jeu avec visual basic
- ForumProgrammation informatique visual basic
- ForumProgrammation de visual basic 2008
- ForumLa programmation en visual basic
- ForumCours programmation evenementielle visual basic 2010 express
- ForumAide programmation visual basic
- ForumProgrammation visual basic et sql
- ForumProgrammation visual basic 6.0
- ForumGuide de programmation visual basic pour debutant
- Voir plus