IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Ruby Discussion :

jeu de la vie (conway-petit problème..)


Sujet :

Ruby

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 20
    Points : 11
    Points
    11
    Par défaut jeu de la vie (conway-petit problème..)
    Vous connaissez surement le jeu de la vie de Conway?

    Si oui vous pouvez peut être m'aider...J'essaye de recréer ce petit programme mais je ne comprends pas pourquoi je n'ai pas le résultat escompté...Il est difficile pour moi de donner plus d'infos....Disons que sur une population de cellule de départ nombreuse,dès le première étape, il y a quasi plus personne(3 ou 4 cellules vivantes,sur le bord à chaque fois)


    Mon code est simple:dans le initialize je créé la pop. au hasard,puis je passe une étape, et là ma population est décimée
    soit il y a une erreur dans mon code et dans ma logique,soit ......je sais pas!!!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
     
    begin
     
      require 'rubygems'
    rescue LoadError
     
    end
     
    require 'gosu'
    include Gosu
    #on a appelé gosu et tout ce qu'il faut pour pouvoir faire des graphismes.
     
    #################################################################################
    class Game < Window#la classe de la fenetre.
    #=====================================================================================================================================
      def initialize(height,width)#début initialize
     
     
        super(height*10, width*10, false)#taille de la fenetre(10 fois le nombre de case plus une marge de 20 px)
        self.caption = "Life..."#le nom de la fenetre
        @height=height#longueur de la fenetre
        @width =width#largeur de la fenetre
        @compteur=0
        @tableau1=Array.new#on créé un tableau
        for i in 0 ... @height#de 0 jusqu'a la longueur de la fenetre...
        @tableau1[i]=Array.new#on créé un tableau dans chaque case du tableau
        for j in 0 ... @width#ce qui fait qu'on a un tableau a 2 dimensions.
        @tableau1[i][j]=rand(2)#pour chaque case du tableau on met une valeur entre 0 et 1.
     
        end#fin for i
      end#fin for j
     
     
          @tableau2=Array.new#on créé un tableau
        for i in 0 ... @height#de 0 jusqu'a la longueur de la fenetre...
        @tableau2[i]=Array.new#on créé un tableau dans chaque case du tableau
        for j in 0 ... @width#ce qui fait qu'on a un tableau a 2 dimensions.
        @tableau2[i][j]=0#on met tout a 0 cette fois ci
        end#fin for i
      end#fin for j
     
     
    for i in 0 ... @height
    for j in 0 ... @width
       avenir(i,j)
     
     end
     
     end
     
       end#fin initialize
      #===================================================================================================================================(
      def update
        if button_down? Button::KbEscape
        self.close
      end
        end
      #===================================================================================================================================
      def avenir(x,y)#début avenir
     
    for i in x-1 ... x+1
    for j in y-1 ... y+1
    if i>=0 and i <=@height and j>=0 and j <=@width
    if @tableau1[i][j]==1
    @compteur += 1
    end
    end
    end
    end
    #====================================
    if @tableau1[x][y]==0
    if @compteur==3 or @compteur==2
    @tableau2[x][y]=1
    else#compteur different de 2 ou 3(isolé ou surpop)
    @tableau2[x][y]=0
    end
    else#if @tableau1[x][y]==1
    @compteur -= 1
    if @compteur==2 or @compteur==3
    @tableau2[x][y]=1
    else
    @tableau2[x][y]=0
    end
    end
     
        end#fin avenir
      #===================================================================================================================================
      def draw
        @img1=Image.new(self,"cell01.png",true)#dessiner image1
        @img0=Image.new(self,"cell00.png",true)
        if !button_down? Button::KbLeft
        for i in 0 ... @height
        for j in 0 ... @width
        if @tableau2[i][j]==1
     
            @img1.draw(i*10,j*10,2)
          else
                 # @img=Image.new(self,"cell00.png",true)
                  @img0.draw(i*10,j*10,2)
    #dessiner image2
          end
     
        end
     
      end
    else
      for i in 0 ... @height
        for j in 0 ... @width
             if @tableau1[i][j]==1
     
            @img1.draw(i*10,j*10,2)
          else
                 # @img=Image.new(self,"cell00.png",true)
                  @img0.draw(i*10,j*10,2)
    #dessiner image2
          end
        end
        end
    end
     
      end#fin draw
      #===================================================================================================================================
    end#fin de la classe Game
     
    Game.new(80,25).show#on affiche la fenetre...
    Je sais pas si vous voyez une erreur(flagrante??)mais en tout cas il n'y a pas le résultat qui est là...)

    Merci de répondre

  2. #2
    Membre extrêmement actif
    Avatar de Madmac
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2004
    Messages
    1 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Alimentation

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 685
    Points : 1 376
    Points
    1 376
    Billets dans le blog
    7
    Par défaut
    À mon avis, il existe deux possibilités:

    - soit la fonction avenir est défectueuse.
    - soit votre problème est lié a la petite population que vous utilisez.

    Pour vérifier la deuxième possibilité, faite manuellement le résultat de la seconde génération. Si le résultat ne concorde pas, vous saurez ou chercher.


    Petit conseil, l'usage du for en Ruby est à déconseiller pour deux raisons; il est beaucoup plus lent que le 'each' et il peut introduire des bugs difficiles à découvrir, si vous utilisez des blocks.

    Au premier coup d'oeil, c'est deux programmes devraient donnés des résultats identiques. Pourtant ce n'est pas le cas.

    results = [ ]
    (1..3).each do |i|
    results << lambda { i }
    end
    puts results.map { |l| l.call }
    # >> 1
    # >> 2
    # >> 3



    results = [ ]
    for i in 1..3
    results << lambda { i }
    end
    puts results.map { |l| l.call }
    # >> 3
    # >> 3
    # >> 3

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    Alors...
    population:
    11
    01

    résultat:
    01
    00

    On aurait du avoir:
    11
    11
    exemple encore plus flagrant:
    10 résultat: 01 au lieu de: 00
    00 résultat: 01 au lieu de: 00

    Donc avenir est défectueux...mais où???J'ai beau la relire et relire encore je vois pas ou est le problème...même si je remplace les fors par des eachs


    Pour moi tout est logique dans la fonction il n'y a qu'a dire ce qu'on fait dans les commentaires et tout va bien je trouve:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
      def avenir(x,y)#début avenir
        (x-1 ... x+1).each do |i|#on vérifie les cases alentours
          (y-1 ... y+1).each do |j|
    if i>=0 and i <=@height and j>=0 and j <=@width#on vérifie si la case est bien dans le tableau
    if @tableau1[i][j]==1#si une cellule alentour est vivante
    @compteur += 1#on rajoute un au compteur
    end
    end
    end
    end
    #====================================
    if @tableau1[x][y]==0#si la case de départ est morte
    if @compteur==3 or @compteur==2#et que aux alentours il y a 2 ou 3 cellules vivantes
    @tableau2[x][y]=1#elle est vivante la prochaine fois
    else#compteur different de 2 ou 3(isolé ou surpop)
    @tableau2[x][y]=0#la prochaine génération==>cellule morte soit par isolement,soit par surpop.
    end
    else#if @tableau1[x][y]==1
    @compteur -= 1#la cellule vivante ne compte pas dans le compteur
    if @compteur==2 or @compteur==3#si il y a 2 ou 3 cellules vivantes alentours
    @tableau2[x][y]=1#alors la cellule ne bouge pas a la prochaine generation
    else#isolement ou surpop.
    @tableau2[x][y]=0#elle meurt à la prochaine generation
    end
    end
     
        end#fin avenir
    en résumé:
    ==============
    début avenir:

    1-grâce aux eachs on regarde toutes les cases aux alentours de la case de départ.


    2-on vérifie SI la case est bien dans le tableau


    3-SI une cellule aux alentours est vivante on rajoute 1 à @compteur
    Il n'y a pas de sinon


    4-fin each+fin each+fin SI+fin Si

    #jusque là pas de problème....


    5-Si la case de départ est morte,mais que les cellules alentours sont aux nombres de 2 ou 3:


    6-A la prochaine génération, elle sera vivante


    7-Sinon(il n'y a pas 2 ou 3 cellules à côté):elle est toujours morte


    8-Sinon(si la case de départ est vivante):on enlève 1 au compteur car elle ne compte pas elle même dans décompte de la population.


    9-Si les cellule aux alentours sont au nombre de 2 ou 3:A la prochaine génération la cellule est toujours vivante


    10-Sinon(si il n'y a pas 2 ou 3 cellules aux alentours)la cellule mourra lors de la prochaine génération

    fin avenir
    ==============

    Qu'est ce qui ne va pas

    Merci pour ta volonté de m' aider tout de même

  4. #4
    Membre extrêmement actif
    Avatar de Madmac
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2004
    Messages
    1 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Alimentation

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 685
    Points : 1 376
    Points
    1 376
    Billets dans le blog
    7
    Par défaut
    Il n'y aurait pas un point de trop sur chacune de ces deux lignes ?

    for i in x-1 ... x+1
    for j in y-1 ... y+1

    Parce que ... exclu la dernière valeur contrairement au ..

    J'avoue ne pas comprendre ton test puisque normalement il devrait porté sur une matrice de 3 par 3.

    http://www.math.com/students/wonders/life/life.html

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    a mon tour de pas comprendre:
    1- j'ai toujours eu l'habitude de mettre ... à chaque fois et c'est bizarre mais quand je mets .. ça ne marche pas:
    ==undefined method `[]' for nil:NilClass (NoMethodError)==
    2- Quand tu dis le test tu parle du
    if i>=0 and i <=@height and j>=0 and j <=@width??

    si tu pouvais mieux expliquer...ça serait bien!

  6. #6
    Membre extrêmement actif
    Avatar de Madmac
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2004
    Messages
    1 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Alimentation

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 685
    Points : 1 376
    Points
    1 376
    Billets dans le blog
    7
    Par défaut
    Citation Envoyé par morius Voir le message
    a mon tour de pas comprendre:
    1- j'ai toujours eu l'habitude de mettre ... à chaque fois et c'est bizarre mais quand je mets .. ça ne marche pas:
    ==undefined method `[]' for nil:NilClass (NoMethodError)==
    2- Quand tu dis le test tu parle du
    if i>=0 and i <=@height and j>=0 and j <=@width??

    si tu pouvais mieux expliquer...ça serait bien!
    Je parlais des deux premières ligne de la fonction avenir. (malheureusement j'avais pris les deux lignes dans ta première version ... )

    (x-1 ... x+1).each do |i|#on vérifie les cases alentours
    (y-1 ... y+1).each do |j|

    Dans cette version tu fais un test de deux par deux. Est-ce bien ce que tu voulais faire ?

    En fait, il existe deux versions standards du programme de jeu de vie. Une d'elle produit des sortes de grappes alors que l'autre produit des mutations de forme dans un matrice 2d (ex: http://www.math.com/students/wonders/life/life.html ). Donc je suis un peu dans le brouillard sur les résultat de tes test, car j'ignore l'allure que devrait avoir la sortie sur ton écran graphique.

    Le message d'erreur signifie qu'à un moment donné il se produit l'assignation d'un objet de la classe Nil. Et évidemmet la class nil n'a pas de méthode [].

    Citation Envoyé par morius Voir le message
    1- j'ai toujours eu l'habitude de mettre ... à chaque fois et c'est bizarre mais quand je mets .. ça ne marche pas:
    ==undefined method `[]' for nil:NilClass (NoMethodError)==
    Le problème est ordinairement que les gens oublient de changer les limites.
    0..3 est égale à 0..2

    Il y a un point qui me chiffonne le tableau2 est le résultat de la première mutation. Pour pourvoir faire la génération suivante ce tableau(tableau 2) ne devrait-il pas être cloné dans le tableau1 et être remplacé par une nouveau tableau vide ?

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    oui mais j'essaie déjà de faire une génération qui marche avant de continuer les autres^^Pour le nil l'erreur est sur cette ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def avenir(x,y)
     (x-1 ..x+1).each do |i|
     (y-1 ..y+1).each do |j|
     
    if i>=0 and i <=@height and j>=0 and j <=@width
    if @tableau1[i][j]==1#l'erreur est ici
    @compteur += 1
    end
    end
    end
    end
    donc le code doit rencontrer une "case qui n'existe pas" malgré la vérification qui est faite...
    if i>=0 and i <=@height and j>=0 and j <=@width
    J'avoue que je suis dépassé sur ce coup là...

  8. #8
    Membre extrêmement actif
    Avatar de Madmac
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2004
    Messages
    1 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Alimentation

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 685
    Points : 1 376
    Points
    1 376
    Billets dans le blog
    7
    Par défaut
    Citation Envoyé par morius Voir le message
    oui mais j'essaie déjà de faire une génération qui marche avant de continuer les autres^^Pour le nil l'erreur est sur cette ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def avenir(x,y)
     (x-1 ..x+1).each do |i|
     (y-1 ..y+1).each do |j|
     
    if i>=0 and i <=@height and j>=0 and j <=@width
    if @tableau1[i][j]==1#l'erreur est ici
    @compteur += 1
    end
    end
    end
    end
    donc le code doit rencontrer une "case qui n'existe pas" malgré la vérification qui est faite...
    if i>=0 and i <=@height and j>=0 and j <=@width
    J'avoue que je suis dépassé sur ce coup là...

    J'ai tenté de reproduire votre message d'erreur avec ce programme, mais sans succès. J'ai fait quelques simplifications, mais le seul véritable changement est que compteur est initialisé au début.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
     
    class Game
     def initialize (height=80, width =25)
        @height=height#longueur de la fenetre
        @width =width#largeur de la fenetre
        @compteur = 0
    	@tableau1 = Array.new(height, Array(width))
    	for i in 0 ... @height#de 0 jusqu'a la longueur de la fenetre...
    		for j in 0 ... @width#ce qui fait qu'on a un tableau a 2 dimensions.
    			@tableau1[i][j]=rand(2)#pour chaque case du tableau on met une valeur entre 0 et 1.
    		end#fin for i
    	end#fin for j
     
    @tableau2=Array.new(@height,Array.new(@width,0))
     
     
    =begin 
     # test des matrices et de rand
    	for i in 0 ... @height
    		for j in 0 ... @width
    			print @tableau1[i][j]
    		end
    		puts ''
    	end
     
    	puts ''
     
    	for i in 0 ... @height
    		for j in 0 ... @width
    			print @tableau2[i][j]
    		end
    		puts ''
    	end
    =end	
    	(0...@height).each do |i|
    		(0...@width).each do |j|
    			avenir(i,j)
    		end
    	end
    end
     
     
      #===================================================================================================================================(
    	def update
    	end
      #===================================================================================================================================
      def avenir(x,y)#début avenir
     
    	(x-1...x+1).each do |i|
    		(y-1...y+1).each do |j|
    			if i>=0 and i <=@height and j>=0 and j <=@width
    				if @tableau1[i][j]==1
    					@compteur += 1
    				end
    			end
    		end
    	end
    #====================================
    	if @tableau1[x][y]==0
    		if @compteur==3 or @compteur==2
    			@tableau2[x][y]=1
    		else#compteur different de 2 ou 3(isolé ou surpop)
    			@tableau2[x][y]=0
    		end
    	else#if @tableau1[x][y]==1
    		@compteur -= 1
    		if @compteur==2 or @compteur==3
    			@tableau2[x][y]=1
    		else
    			@tableau2[x][y]=0
    		end
    	end
     
    end#fin avenir
      #===================================================================================================================================
      def draw(x)
     
        if (x)
    		for i in 0 ... @height
    			for j in 0 ... @width
    				if @tableau2[i][j]==1
     
    					print ('X')
    				else
    				# @img=Image.new(self,"cell00.png",true)
    					print ('0')
    				#dessiner image2
    				end
    			end
    			puts ''
    		end
    	else
    		for i in 0 ... @height
    			for j in 0 ... @width
    				if @tableau1[i][j]==1
     
    					print ('X')
    				else
    				# @img=Image.new(self,"cell00.png",true)
    					print ('0')
    				#dessiner image2
    				end
     
    			end
    			puts ''
    		end
    	end
      end#fin draw
      #===================================================================================================================================
    end#fin de la classe Game
     
    g = Game.new(80,25)#on affiche la fenetre...
    g.draw(true)
    puts ''
    g.draw(false)

  9. #9
    Membre éprouvé

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2007
    Messages : 552
    Points : 1 058
    Points
    1 058
    Par défaut
    Citation Envoyé par morius Voir le message
    donc le code doit rencontrer une "case qui n'existe pas" malgré la vérification qui est faite...
    if i>=0 and i <=@height and j>=0 and j <=@width
    J'avoue que je suis dépassé sur ce coup là...
    Je n'ai pa regardé la définition de @height et de @width mais je testerai plutôt avec la ligne suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if i>=0 and i <@height and j>=0 and j <@width
    ZiK un lecteur audio et son blog.

Discussions similaires

  1. Jeu de la vie - Conway
    Par luffy27 dans le forum Développement 2D, 3D et Jeux
    Réponses: 9
    Dernier message: 24/10/2010, 19h10
  2. [SDL et C] Problème avec mon jeu de la vie
    Par _SamSoft_ dans le forum Développement 2D, 3D et Jeux
    Réponses: 4
    Dernier message: 24/05/2008, 09h43
  3. Problème pour le jeu de la vie
    Par daninou dans le forum Débuter
    Réponses: 8
    Dernier message: 04/12/2007, 21h14
  4. Problème jeu de la vie de Wolfram
    Par romromp dans le forum Pascal
    Réponses: 14
    Dernier message: 11/03/2007, 19h58
  5. Conway's life (jeu de la vie) pour images
    Par O( N ) dans le forum C
    Réponses: 1
    Dernier message: 26/09/2006, 02h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo