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

Pascal Discussion :

Problème jeu de la vie de Wolfram


Sujet :

Pascal

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 7
    Points : 2
    Points
    2
    Par défaut Problème jeu de la vie de Wolfram
    Bonjour à tous,
    Je réalise un jeu de la vie de wolfram en pascal (http://fr.wikipedia.org/wiki/Automate_cellulaire
    et donc j'ai une erreure que je n'arrive pas à corriger aux alentours de la ligne 129 dans la fonction "calculedesgenerations"...
    Si qq1 peut m'aider merci d'avance !

    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
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
     
     
    program test; 
    uses crt; 
     
     
    Const 
        NLIGNES      = 1; //nombre de lignes du jeu 
        NCOLONNES    = 120; //nombre de colonnes du jeu 
        CHAR_VIVANTE = '#'; //caractere a afficher pour une cellule vivante 
        CHAR_MORTE = '_'; //caractere a afficher pour une cellule morte 
        valeurExterieurGauche=FALSE; 
        valeurExterieurDroite=FALSE; 
     
     
    Type 
     
            tTerrain = array [1..NCOLONNES] of boolean; 
        //le terrain du jeu de la vie, un tableau a une dimensions 
     
        tRegle = array [0..7] of boolean; 
        //une regle (de naissance ou de survie) du jeu 
     
     
    Var 
        i,j:integer; 
        un, un_1: tTerrain; 
        choixUtilisateur : integer ; //le choix de l'utilisateur dans le menu 
     
    //pour rentrer la regle 
     
    function rentrerregle  : tRegle; 
    var t : tRegle; 
    var rep: integer ; 
     
    begin 
     
      writeln('taper votre chiffre (1..256)'); 
      readln(rep); 
     
              for i:=0 to 7 do 
            if (((rep-1) SHR i) mod 2)=1 then 
                    t[i]:=true 
            else     
                t[i]:=false; 
     
                rentrerregle:=t; 
    end; 
     
            //affiche une case du jeu de la vie 
    procedure afficherCase(const b  :boolean); 
    begin 
        if b then 
            write(CHAR_VIVANTE) 
        else 
            write(CHAR_MORTE); 
    end;      
     
    //retourne un booleen au hasard 
    function booleenHasard : boolean; 
    begin 
        if (random(2)=0) then 
            booleenHasard:=false 
        else 
            booleenHasard:=true; 
    end; 
     
     
    //rempli un terrain au hasard 
    function terrainHasard : tTerrain; 
    var rVal: tTerrain; 
    begin 
        randomize; 
        for i:=1 to NLIGNES do 
            for j:=1 to NCOLONNES do 
                rVal[j]:= booleenHasard; 
     
        terrainHasard:=rVal; 
    end;      
     
    procedure afficherTerrain(const  t : tTerrain); 
    var j : integer; 
    begin 
     
            for j:=1 to NCOLONNES do 
                afficherCase(t[j]); 
            writeln; 
     
    end; 
     
    //fonction etat suivant 
    function etatSuivant(precedente,courant,suivante:boolean) :    boolean; 
     
    var cas:integer; 
    var regle:tRegle;         
    begin 
    for j := 1 to NCOLONNES do 
            regle[j]:=False; 
        cas:=0; 
     
        if(precedente) then 
                  cas := cas+4; 
        if(courant) then 
                  cas := cas+2; 
        if(suivante) then 
                  cas := cas+1; 
     
        etatSuivant :=regle[cas]; 
     
     
    end; 
     
     
    //fonction qui compte les voisins 
    function quelvoisin (const generationCourante : tTerrain):tTerrain ; 
     
    var generationSuivante:tTerrain; 
    var m : integer; 
     
    begin 
              generationSuivante[1]:=etatSuivant(valeurExterieurGauche,generationCourante[1],generationCourante[2]); 
     
              for m:=2 to Ncolonnes-1 do 
              generationSuivante[m]:=etatSuivant(generationCourante[m-1],generationCourante[m],generationCourante[m+1]); 
     
              generationSuivante[Ncolonnes]:=etatSuivant(generationCourante[Ncolonnes-1],generationCourante[Ncolonnes],valeurExterieurDroite); 
      quelvoisin:=generationSuivante; 
     
    end; 
     
     procedure calculdesgenerations;
    var i,j:integer;
    var regle:tRegle;
     
    begin
         for j := 1 to NLIGNES do
         begin
              afficherTerrain(un);
              for i := 1 to NColonnes do
                  un_1[i]:=regle[quelvoisin[i]];
     
              un:=un_1;
         end;
         readln;
    end;
     
    // rentrer un motif manuellement 
    procedure Terrainmanuel(var t : tTerrain); 
    var c : char; 
    var pos : byte; 
    begin 
        pos := 0; 
        repeat 
            ClrScr; 
            afficherTerrain(t); 
            Writeln('Appuyer sur ''q'' pour terminer.'); 
            gotoXY(pos,1);         
            c := readkey; 
             case c of 
                'K' : if (pos>1) then 
                        pos := pos-1; 
                'M' : if (pos<120) then 
                        pos := pos+1; 
                ' ' : t[pos] := not(t[pos]);             
            end; 
            gotoXY(pos,1);     
        until ((c='Q') OR  (c='q'))     
    end; 
     
     
    //Menu 
     
     
    function afficherMenu : integer; 
    var rVal : integer; 
    begin 
        ClrScr; 
        writeln('0 : Saisir un motif de depart'); 
        writeln('1 : Generer un motif de depart aleatoire'); 
        writeln('2 : choix de la regle'); 
        writeln('3 : Lancer le jeu de la vie'); 
        //writeln('4 : choix du nombre de generations'); 
        writeln('5 : Quitte le jeu'); 
        readln(rVal); 
     
        afficherMenu:=rVal; 
    end; 
     
    procedure effectuerMenu(const i : integer); 
    begin 
         case i of 
            0 :     Terrainmanuel(un); 
            1 :      Un := terrainHasard; 
            2 :    rentrerregle; 
            3 :    calculdesgenerations; 
            {4 :    begin 
                    ClrScr; 
                    writeln('Nombre maximum de generations : '); 
                    readln(generationMaxi); 
                end; 
    } 
        end; 
     
    end; 
     
    //Programme principal 
     
    begin 
        //initialisation des variables 
            //generationMaxi := 40; 
            //rep:=30; 
        //repete le menu jusqu'a ce que l utilisateur quitte le jeu 
        repeat 
            choixUtilisateur := afficherMenu; 
            effectuerMenu (choixUtilisateur); 
        until (choixUtilisateur=5) 
     
    end.
    Si qq1 peut m'aider merci d'avance !

    tom
    +

  2. #2
    Membre confirmé
    Avatar de diden138
    Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    714
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2006
    Messages : 714
    Points : 589
    Points
    589
    Par défaut Re:
    1-)Tous d'abord cette fonction qui n'existe pas dans ton programme .
    2-)avant de poster ici veuillez lire attentivement le message d'erreur du compilateur aprés consulter l'aide +Google et si vous ne trouver pas de réponse poster sur le forum
    voila ton erreur ligne 138 : tu passe à ton array regle une valeur de type tTerrain au lieux d'un indice tous simplement .
    un_1[i]:=regle[quelvoisin[i]];
    Cordialement @+
    et vint le 20siècle et l'homme se mit à réflechir comme la machine auteur: diden138
    Langage: Pascal,OCaml,Delphi,c/c++.
    Langages web:Xhtml,Css,Php/Mysql,Javascript,Actionscript 2.0
    Plate forme:Windows XP Pro SP2./Red Hat 9.0/SUSE 10.2
    Config :Intel P4 3.2GHZ,2MO cach,512 RAM.
    Outils:Tp7,objective caml,Delphi 6 perso, C++builder 6,Visual C++ Express edition sous win,code-block sous linux(Ubuntu) .

  3. #3
    Membre actif Avatar de Ultima
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2006
    Messages
    223
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2006
    Messages : 223
    Points : 261
    Points
    261
    Par défaut
    Bonjour,
    A la ligne 113 voici ta déclaration de "quelvoisin" : function quelvoisin (const generationCourante : tTerrain):tTerrain ;

    A la ligne 138 voici ton utilisation de "quelvoisin" : quelvoisin[i]
    Il est évident que tu as oublié de mètre le paramètre que doit prendre ta fonction.

    Salut, courage.

  4. #4
    Membre actif Avatar de Ultima
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2006
    Messages
    223
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2006
    Messages : 223
    Points : 261
    Points
    261
    Par défaut
    Remarque : regle est du type tRegle or tu as écris regle[quelvoisin…] ceci aussi est une erreur, tu devrais plutôt écrire regle[i] avec i du type 1..7.
    Normale puisque quelvoisin est du type tTerrain.

    SalUt...

  5. #5
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 941
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 941
    Points : 5 652
    Points
    5 652
    Par défaut
    Hi,

    Juste pour le fun : tu appelles "Jeu de la vie" ton jeu mono-dimensionnel, alors que l'automate cellulaire qui s'appelle "Jeu de la vie", qui d'ailleurs n'est pas de Wolfram, mais de Conway, est un automate bi-dimensionnel.

    Si j'ai le temps, je jetterai un coup d'oeil ce week-end (les fins de semaines sont toujours très chargées, là j'ai un petit trou de quelques minutes )
    Si les cons volaient, il ferait nuit à midi.

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Merci à tous pour vos réponses;

    @ ultima :
    tu devrais plutôt écrire regle[i] avec i du type 1..7.
    c'est vrai, mais ca ne fait pas ce que je désire..


    Il est évident que tu as oublié de mètre le paramètre que doit prendre ta fonction.
    oui mais je suis perdu dans mon propre prog je ne sais meme plus ce que je dois mettre, parce que si je met : regle[i] ( avec regle un tRegle), je n'utilise alors plus la procedure quelvoisin qui est capitale.. je ne sais que faire

    En résumé, je veux afficher chaque ligne en fonction de ce contient chaque voisin de chaque case de mon tableau(d'ou la fonction quelvoisin) or, je n'arrive pas à l'appeler..

    quelqu'un a une idée ?
    merci encore pour votre aide !

    @+ tom

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Re,

    voilà j'ai changé ma procedure calculdesgenerations en ca :

    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
     
          procedure calculdesgenerations;
    var i,j:integer;
    var regle:tRegle;
    begin
         for j := 1 to NLIGNES do
         begin
              afficherTerrain(un);
              for i := 1 to NColonnes do
                  //un_1[i]:=regle[conv3bool(un[i-1],un[i],un[i+1])];
    	  regle:=t;
    	  un_1[i]:=regle[i];
     
              un:=un_1;
         end;
         readln;
    end;
    avec t un tRegle ou la regle a été rentrée précedemment.
    ca compile mais quand le programme utilise calculdesgenerations, il n'affiche que # tout a droite sur 40 ligne.. c'est pas encore ce que je veux..

    Une idée ?

    Merci d'avance

    Tom@+

  8. #8
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 941
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 941
    Points : 5 652
    Points
    5 652
    Par défaut
    Olé

    Hoho,

    J'ai jeté un coup d'oeil (c'est à dire que je n'ai pas lu en détails), et voici mes remarques, pour "ce qui me saute aux yeux".

    D'abord en général :

    - Tu utilises des noms très explicites, c'est très bien

    - L'indentation est un peu hasardeuse, il faut y faire attention, pour la lisibilité du code.

    - Puisque tes noms sont longs, et sont formés par des mots accolés, prends l'habitude de toujours mettre en majuscule la 1ère lettre de chaque mot, à l'exception possible de la 1ère du nom, mais pour celle-là, c'est une question de style personnel.
    Tu l'as fait souvent, mais pas toujours, par exemple (ce n'est pas le seul cas)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function rentrerregle  : tRegle;
    Et cela coule de source, toujours écrire un nom de la même manière (je sais, Pascal se moque de la distinction majuscules/minuscules), c'est simplement pour rester cohérent.

    - Tu utilises des variables globales.
    Dit et répété maintes fois : à éviter, on peut presque toujours s'en passer, les cas où elles sont nécessaires sont rarissimes.

    Ton programme d'un peu plus près :

    - Ton automate étant mono-dimensionnel, pourquoi une constante NLIGNES, qui n'est pas seulement là pour le décor, mais que utilises.
    Cela permettra peut-être une évolution vers un automate bi-dimensionnel, mais il y aura suffisamment d'autres choses à modifier pour justifier de faire un nouveau programme.

    - Le menu !!

    1) Les valeurs à entrer devraient être déclarées en constantes, constantes à utiliser pour afficher le menu, ainsi que dans la fonction qui teste la valeur entrée.

    2) Il faut l'éclater en plusieurs menus (et donc également la gestion de la valeur entrée).

    En effet, tu affiches, et gères plus loin ce menu.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    function afficherMenu : integer;
    var rVal : integer;
    begin
        ClrScr;
        writeln('0 : Saisir un motif de depart');
        writeln('1 : Generer un motif de depart aleatoire');
        writeln('2 : choix de la regle');
        writeln('3 : Lancer le jeu de la vie');
        { writeln('4 : choix du nombre de generations');}
        writeln('5 : Quitte le jeu');
        readln(rVal);
     
        afficherMenu:=rVal;
    end;
    Que va-t-il se passer si l'utilisateur entre le choix
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        writeln('3 : Lancer le jeu de la vie');
    sans être passé par au moins 2 des choix 0 à 2, c'est à dire sans avoir initialisé le terrain, et/ou la règle ?

    - Un petit détail mais qui a son importance:
    dans la procédure suivante
    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
     
    procedure Terrainmanuel(var t : tTerrain);
    var c : char;
    var pos : byte;
    begin
        pos := 0;
        repeat
            ClrScr;
            afficherTerrain(t);
            Writeln('Appuyer sur ''q'' pour terminer.');
            gotoXY(pos,1);
            c := readkey;
             case c of
                'K' : if (pos>1) then
                        pos := pos-1;
                'M' : if (pos<120) then
                        pos := pos+1;
                ' ' : t[pos] := not(t[pos]);
            end;
            gotoXY(pos,1);
        until ((c='Q') OR  (c='q'))
    end;
    Tu utilises la valeur 120, alors que tu as une constante NCOLONNES faite pour ça.

    Si tu changes la valeur de la constante, il est probable que tu chercheras quelques temps avant de trouver d'où vient le probème apparaissant tout à coup.

    - Le Programme principal
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    begin
        { initialisation des variables}
            { generationMaxi := 40;    }
            { rep:=30;
        { repete le menu jusqu'a ce que l utilisateur quitte le jeu}
        repeat
            choixUtilisateur := afficherMenu;
            effectuerMenu (choixUtilisateur);
        until (choixUtilisateur=5)
     
    end.
    D'accord, la procédure effectuerMenu ne fait rien si on lui passe une valeur qu'elle ne gère pas, en l'occurrence 5, pour quitter le jeu, mais ton code devrait être sécurisé en écrivant
    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
     
    begin
        { initialisation des variables}
            { generationMaxi := 40;    }
            { rep:=30;
        { repete le menu jusqu'a ce que l utilisateur quitte le jeu}
        repeat
            choixUtilisateur := afficherMenu;
            { -------- ici ---------- }
     
            if (choixUtilisateur <> 5) then effectuerMenu (choixUtilisateur);
     
            { on voit ici l'intérêt d'utiliser des constantes,
              car la valeur 5 peut parfaitement évoluer au fil des options
              que tu ajouteras/supprimeras, tu l'as déjà vu en supprimant
              du menu le choix 4.
              Il faudrait même une fonction chargée de contrôler la
              validité de l'entrée }
        until (choixUtilisateur=5)
     
    end.
    Ceci est d'autant plus nécessaire que la procédure effectuerMenu ne prend pas en compte toutes les valeurs possibles.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    procedure effectuerMenu(const i : integer);
    begin
         case i of
            0 :     Terrainmanuel(un);
            1 :      Un := terrainHasard;
            2 :    rentrerregle;
            3 :    calculdesgenerations;
            {4 :    begin
                    ClrScr;
                    writeln('Nombre maximum de generations : ');
                    readln(generationMaxi);
                end; }
        end;
    end;
    Quand on passe dans un case ... of, et que tous les cas possibles ne sont pas pris en compte, il y a danger :

    Certains compilateurs ne garantissent pas que tout se passera bien, car ne trouvant pas le cas désiré, il est possible que le programme le cherche au-delà du code généré.
    C'est rarement le cas avec des compilateurs "modernes", mais j'en ai connus qui avaient ce problème.

    Pascal fourni la possibilité de gérer les cas non prévus, autant l'utiliser.

    Il faut utiliser un cas else, même vide (mais comme dernier choix dans la liste gérée):
    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
    procedure effectuerMenu(const i : integer);
    begin
         case i of
            0 :     Terrainmanuel(un);
            1 :      Un := terrainHasard;
            2 :    rentrerregle;
            3 :    calculdesgenerations;
            {4 :    begin
                    ClrScr;
                    writeln('Nombre maximum de generations : ');
                    readln(generationMaxi);
                end; }
     
           { --------- ici ---------- }
     
           else { suivi par ce que tu veux faire pour les cas non gérés, ça peut être rien }
        end;
    end;
    Pour pinailler :

    - la fonction terrainHasard va, en moyenne, mettre une cellule sur 2 à true, le reste à false.

    Je ne pense pas que ce soit très génial, elle a probalement besoin d'être améliorée.
    C'est sans doute important pour générer des terrains un peu plus intéressants.

    Sur le style :

    - Quand tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
            { affiche une case du jeu de la vie}
    procedure afficherCase(const b  :boolean);
    begin
        if b then
            write(CHAR_VIVANTE)
        else
            write(CHAR_MORTE);
    end;
    Moi j'aurais déclaré une constante comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    const
     
        CelluleChar : array [boolean] of char = (CHAR_MORTE,CHAR_VIVANTE);
    et écrit la procédure comme cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            { affiche une case du jeu de la vie}
    procedure afficherCase(const b  :boolean);
    begin
        write(CelluleChar[b]);
    end;
    - Quand tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    { retourne un booleen au hasard}
    function booleenHasard : boolean;
    begin
        if (random(2)=0) then
            booleenHasard:=false
        else
            booleenHasard:=true;
    end;
    J'aurais plutôt écrit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    { retourne un booleen au hasard}
    function booleenHasard : boolean;
    begin
       booleenHasard := ( random(2) = 1 );
    end;
    Ces deux dernières remarques ne venant que de préférences dans le style utilisé pour coder, et ne concernent donc pas le fonctionnement de tes fonctions, qui fonctionnent

    En conclusion :

    Pour le reste, notamment les erreurs de compilation, je n'ai pas lu le code en détail, mais les remarques déjà faites par d'autres membres devraient t'aider.
    Si ça ne va toujours pas, reposte ta dernière version du code, et je verrais plus en détails.

    Gloabalement, c'est bien, malgré mes quelques remarques.

    Bonne suite.
    Si les cons volaient, il ferait nuit à midi.

  9. #9
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Merci de ta réponse droggo.

    Je met ici la dernière version de mon code et en attendant je vais essayer d'appliquer tes conseils.

    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
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
     
    program test; 
    uses crt; 
     
     
    Const 
        NLIGNES      = 40; //nombre de lignes du jeu 
        NCOLONNES    = 120; //nombre de colonnes du jeu 
        CHAR_VIVANTE = '#'; //caractere a afficher pour une cellule vivante 
        CHAR_MORTE = '_'; //caractere a afficher pour une cellule morte 
        valeurExterieurGauche=FALSE; 
        valeurExterieurDroite=FALSE; 
     
     
     
    Type 
     
            tTerrain = array [1..NCOLONNES] of boolean; 
        //le terrain du jeu de la vie, un tableau a une dimensions 
     
        tRegle = array [0..7] of boolean; 
        //une regle (de naissance ou de survie) du jeu 
     
     
    Var 
        i,j:integer; 
        un, un_1: tTerrain; 
        choixUtilisateur : integer ; //le choix de l'utilisateur dans le menu 
        t : tRegle;//regle de vie ou mort 
     
    //pour rentrer la regle 
     
    function rentrerregle  : tRegle; 
     
    var rep: integer ; 
     
    begin 
     
      writeln('taper votre chiffre (1..256)'); 
      readln(rep); 
     
              for i:=0 to 7 do 
            if (((rep-1) SHR i) mod 2)=1 then 
                    t[i]:=true 
            else     
                t[i]:=false; 
     
                rentrerregle:=t; 
    end; 
     
            //affiche une case du jeu de la vie 
    procedure afficherCase(const b  :boolean); 
    begin 
        if b then 
            write(CHAR_VIVANTE) 
        else 
            write(CHAR_MORTE); 
    end;      
     
    //retourne un booleen au hasard 
    function booleenHasard : boolean; 
    begin 
        if (random(2)=0) then 
            booleenHasard:=false 
        else 
            booleenHasard:=true; 
    end; 
     
     
    //rempli un terrain au hasard 
    function terrainHasard : tTerrain; 
    var rVal: tTerrain; 
    begin 
        randomize; 
        for i:=1 to NLIGNES do 
            for j:=1 to NCOLONNES do 
                rVal[j]:= booleenHasard; 
     
        terrainHasard:=rVal; 
    end;      
     
    procedure afficherTerrain(const  t : tTerrain); 
    var j : integer; 
    begin 
     
            for j:=1 to NCOLONNES do 
                afficherCase(t[j]); 
            writeln; 
     
    end; 
     
    //fonction etat suivant 
    function etatSuivant(precedente,courant,suivante:boolean) : boolean; 
     
    var cas:integer; 
    var regle:tRegle;         
    begin 
    for j := 1 to NCOLONNES do 
            regle[j]:=False; 
        cas:=0; 
     
        if(precedente) then 
                  cas := cas+4; 
        if(courant) then 
                  cas := cas+2; 
        if(suivante) then 
                  cas := cas+1; 
     
        etatSuivant :=regle[cas]; 
     
     
    end; 
     
     
    //fonction qui compte les voisins 
    function quelvoisin (const generationCourante : tTerrain):tTerrain; 
     
    var generationSuivante:tTerrain; 
    var m : integer; 
     
    begin 
              generationSuivante[1]:=etatSuivant(valeurExterieurGauche,generationCourante[1],generationCourante[2]); 
     
              for m:=2 to Ncolonnes-1 do 
              generationSuivante[m]:=etatSuivant(generationCourante[m-1],generationCourante[m],generationCourante[m+1]); 
     
              generationSuivante[Ncolonnes]:=etatSuivant(generationCourante[Ncolonnes-1],generationCourante[Ncolonnes],valeurExterieurDroite); 
      quelvoisin:=generationSuivante; 
     
    end; 
     
     
       procedure calculdesgenerations;
    var i,j:integer;
    var regle:tRegle;
    begin
         for j := 1 to NLIGNES do
         begin
              afficherTerrain(un);
              for i := 1 to NColonnes do
    	  regle:=t;
    	  un_1[i]:=regle[i];
     
              un:=un_1;
         end;
         readln;
    end;
    // rentrer un motif manuellement 
    procedure Terrainmanuel(var t : tTerrain); 
    var c : char; 
    var pos : byte; 
    begin 
        pos := 0; 
        repeat 
            ClrScr; 
            afficherTerrain(t); 
            Writeln('Appuyer sur ''q'' pour terminer.'); 
            gotoXY(pos,1);         
            c := readkey; 
             case c of 
                'K' : if (pos>1) then 
                        pos := pos-1; 
                'M' : if (pos<120) then 
                        pos := pos+1; 
                ' ' : t[pos] := not(t[pos]);             
            end; 
            gotoXY(pos,1);     
        until ((c='Q') OR  (c='q'))     
    end; 
     
     
    //Menu 
     
     
    function afficherMenu : integer; 
    var rVal : integer; 
    begin 
        ClrScr; 
        writeln('0 : Saisir un motif de depart'); 
        writeln('1 : Generer un motif de depart aleatoire'); 
        writeln('2 : choix de la regle'); 
        writeln('3 : Lancer le jeu de la vie'); 
        //writeln('4 : choix du nombre de generations'); 
        writeln('5 : Quitte le jeu'); 
        readln(rVal); 
     
        afficherMenu:=rVal; 
    end; 
     
    procedure effectuerMenu(const i : integer); 
    begin 
         case i of 
            0 :     Terrainmanuel(un); 
            1 :      Un := terrainHasard; 
            2 :    rentrerregle; 
            3 :    calculdesgenerations; 
            {4 :    begin 
                    ClrScr; 
                    writeln('Nombre maximum de generations : '); 
                    readln(generationMaxi); 
                end; 
    } 
        end; 
     
    end; 
     
    //Programme principal 
     
    begin 
        //initialisation des variables 
            //generationMaxi := 40; 
            //rep:=30; 
        //repete le menu jusqu'a ce que l utilisateur quitte le jeu 
        repeat 
            choixUtilisateur := afficherMenu; 
            effectuerMenu (choixUtilisateur); 
        until (choixUtilisateur=5) 
     
    end.

    bye

  10. #10
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 941
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 941
    Points : 5 652
    Points
    5 652
    Par défaut
    Halo

    Rapidement vu, tu as un gros problème la-dedans:
    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
    procedure calculdesgenerations;
    var i,j:integer;
    var regle:tRegle;
    begin
         for j := 1 to NLIGNES do
         begin
              afficherTerrain(un);
              for i := 1 to NColonnes do
    	            {la variable locale qui se contente de 
    	             copier une variable globale ne sert à rien }
     
    	  regle:=t; { on lit NLIGNES * NCOLONNES fois
    	              une donnée qui ne change pas !}
     
    	       { et en plus, c'est tout ce que
    	         l'on fait dans la boucle sur NCOLONNES ! }
     
    	       { la suite n'est exécutée que dans la boucle sur NLIGNE }
     
    	  { et là, je doute que ce soit aussi simple
    	    pour affecter la nouvelle valeur à une cellule.
     
    	    +++ les indices de regle vont de 0 à 7,
    	    et là tu les utilises de 1 à NLIGNES }
     
    	  un_1[i]:=regle[i];
     
              un:=un_1;
         end;
     
         { pourquoi un readln qui arrête le programme
           tant que l'utilisateur n'a pas fait Entrée ?.
           La moindre des choses serait de
           mettre un message pour prévenir }
         readln;
    end;
    Il faut absolument revoir ça.
    Si les cons volaient, il ferait nuit à midi.

  11. #11
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    je sais que le gros problème est là dedans, mais je n'arrive pas a exploiter ma fonction quelvoisin pour affecter la nouvelle valeur à la cellule et afficher la nouvelle case..

  12. #12
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 941
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 941
    Points : 5 652
    Points
    5 652
    Par défaut
    Houla,

    Ce n'est le seul problème que tu as.

    Comme je l'ai mis en commentaire, ta boucle sur NCOLONNES ne fait que
    Si tu n'arrives pas à utiliser ta fonction quelvoisin, il y a au moins 2 raisons possibles, peut-être les 2 ensembles.

    Dans l'ordre de probabilité:

    - Tu l'as mal définie par rapport à ce qu'elle doit faire

    - Tu n'as pas totalement compris ce qu'il faut faire

    Il faut donc creuser un peu
    Si les cons volaient, il ferait nuit à midi.

  13. #13
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    je sais sinon je ne serais pas venu sur ce forum

  14. #14
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 941
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 941
    Points : 5 652
    Points
    5 652
    Par défaut
    lola

    Ne t'inquiète pas du fait d'avoir besoin d'aide, nous sommes tous passés par là, et il arrive à tout le monde de "coincer" à un moment ou à un autre.

    Pour mettre tes programmes au point, il faut le faire par petits morceaux, et bien réfléchir aux algorithmes à mettre en oeuvre.

    Par exemple, j'anticipe sur ce j'ai écrit plus loin, un de tes problèmes est de calculer l'état suivant d'une cellule.

    Pour cela, et comme ça ne demande pas des milliers de calculs, tu écris une ligne contenant des # et des _, puisque ce sont les caractères que tu as choisis (elle n'a pas besoin d'être très longue, 15 ou 20 caractères sont largement suffisants).

    Tu écris une autre ligne de 8 caratères (des 1 et 0, par exemple, ou des V et F, pour représenter Vrai ou Faux), représentant la règle à appliquer.

    Une fois cela fait, tu essayes d'appliquer la règle à une cellule prise au hasard, pour tester l'algorithme que tu auras imaginé, en vérifiant que le résultat obtenu est bien celui que tu attends.

    Les petites vérifications manuelles comme celle-ci sont le meilleur moyen de contrôler les algorithmes simples.

    Revenons à nos oignons:

    - Au passage, j'ai vu l'utilisation de Ncolonnes pour la constante NCOLONNES.
    Il fait rester cohérent dans la notation, même si le compilateur s'en fout.

    - Au passage également, tu écris souvent
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function ...; 
     
    var generationSuivante:tTerrain; 
    var m : integer;
    Il est inutile d'écrire 2 fois le mot clé var.

    - ici, la partie qui nous intéresse
    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
    //fonction etat suivant 
    function etatSuivant(nuCell : integer;) : boolean; 
     
    var cas:integer; 
    var regle:tRegle;         
    begin 
     
    { ici encore, tu dépasses les limites des indices autorisés pour un type tRegle }
     
    for j := 1 to NCOLONNES do 
            regle[j]:=False; 
        cas:=0; 
     
        if(precedente) then 
                  cas := cas+4; 
        if(courant) then 
                  cas := cas+2; 
        if(suivante) then 
                  cas := cas+1; 
     
        etatSuivant :=regle[cas]; 
     
     
    end; 
     
    //fonction qui compte les voisins 
    function quelvoisin (const generationCourante : tTerrain):tTerrain; 
     
    var generationSuivante:tTerrain; 
    var m : integer; 
     
    begin 
              generationSuivante[1]:=etatSuivant(valeurExterieurGauche,generationCourante[1],generationCourante[2]); 
     
              for m:=2 to Ncolonnes-1 do 
              generationSuivante[m]:=etatSuivant(generationCourante[m-1],generationCourante[m],generationCourante[m+1]); 
     
              generationSuivante[Ncolonnes]:=etatSuivant(generationCourante[Ncolonnes-1],generationCourante[Ncolonnes],valeurExterieurDroite); 
      quelvoisin:=generationSuivante; 
     
    end;
    C'est la fonction etatSuivant qui devrait prendre en compte les bords du tableau, et n'avoir donc besoin que de l'indice de la case à calculer:

    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
    //fonction etat suivant 
    function etatSuivant(nuCell : integer;) : boolean; 
     
    var cas:integer; 
        { ici encore, la variable locale qui ne fait
          que copier une variable globale ne sert à rien }
        regle:tRegle;         
    begin 
        cas:=0; 
     
        { ici, gérer en fonction de l'indice nuCell passé à la fonction,
          sans oublier de traiter le cas des bords du tableau.
          je te laisse faire }
     
        if(precedente) then 
                  cas := cas+4; 
        if(courant) then 
                  cas := cas+2; 
        if(suivante) then 
                  cas := cas+1; 
     
        etatSuivant :=regle[cas]; 
     
     
    end; 
     
    //fonction qui compte les voisins 
    function quelvoisin (const generationCourante : tTerrain):tTerrain; 
     
    var generationSuivante:tTerrain; 
    var m : integer; 
     
    begin   
      for m:=1 to Ncolonnes do 
        generationSuivante[m]:=etatSuivant(m); 
      quelvoisin:=generationSuivante; 
    end;
    Ceci, en admettant l'utilisation de variables globales, très déconseillé

    Ta fonction quelvoisin est d'ailleurs mal nommée, puisque de fait, elle calcule carrément la prochaine génération.

    Un peu de boulot n'a jamais fait de mal à personne (un peu, pas trop !)
    Si les cons volaient, il ferait nuit à midi.

  15. #15
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    merci bcp de ton aide, avec tout ca je vais essayer de me débrouiller, je pense ( j'espère?) y arriver.

    Je te tient au courant
    bye

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Probléme en C du Jeu de la vie
    Par Stephanie larges dans le forum Débuter
    Réponses: 5
    Dernier message: 01/10/2012, 15h33
  2. Jeu de la vie, problème d'affichage.
    Par -ezano- dans le forum Débuter
    Réponses: 5
    Dernier message: 22/09/2009, 13h55
  3. jeu de la vie (conway-petit problème..)
    Par morius dans le forum Ruby
    Réponses: 8
    Dernier message: 18/03/2009, 14h00
  4. [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, 10h43
  5. Problème pour le jeu de la vie
    Par daninou dans le forum Débuter
    Réponses: 8
    Dernier message: 04/12/2007, 22h14

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