Bonjour à tous,

Je me permets de poster ici, je pense avoir plus de chances d'être vue, que sur la forum d'aide au nouveaux :

Dans le cadre de ma première année en biologie, nous suivons des cours d'algorithme, et de code.
Par code, c'est très simplifié, nous utilisons Algoscript (http://www.algoscript.info), un Javascript simplifié, et francisé de ce que j'ai compris.

J'ai un projet à rendre pour dimanche, je bloque sur de nombreux points, pourriez-vous m'orienter, me débloquer ? Malgré mes demandes cordiales, ma professeur n'a pas voulu nous aider, arguant qu'elle n'est pas en charge des projets.. bon !
Je fais appel à votre générosité, en espérant que le projet soit assez facile, basique, pour qu'il ne vous prenne pas trop de temps à comprendre (ce dont je ne doute pas).

Sujet : Le jeu de la vie

Le principe du jeu de la vie a été introduit par John H. Conway en 1970. Ce "jeu" a donné naissance plus tard à toute une théorie mathématique dite des automates cellulaires. Ce jeu a trouvé des applications dans l'étude de quelques modes de développement de populations. Malgré des règles simples de reproduction et de décès, le mimétisme avec des processus "réels" est frappant.

Grossièrement, le jeu de la vie se compose d'une grille sur laquelle évolue des cellules.
Chaque point de la grille peut-être occupé par au plus une cellule. À chaque étape du jeu, des cellules peuvent apparaître ou disparaître selon la règle suivante :

- si une case vide est entourée d'exactement trois cases pleines, alors une cellule nait dans cette case à la génération suivante;
- si une cellule vivante est entourée de deux ou trois cellules vivantes alors elle le reste, sinon elle meurt.

1) Comment représenter une génération du jeu. Ok

2) Écrire la fonction AppliquerRegle(génération) qui calcule une génération en fonction de la précédente. Pas encore au point

3) Écrire une fonction JoliAffichageLettres(génération) qui retourne une chaîne de caractères où tous les 0 de génération sont remplacés par des espaces et tous les 1 par des 'X'. Pas de soucis particulier, je vais m'en occuper
4) Améliorez deux choses à ce programme : ajoutez une création de génération aléatoire (de longueur saisie par l'utilisateur) - Là ça coince - et un affichage dans l'interface graphique des différentes générations - Ok

Je vous laisse regarder mon code avant, vous pouvez le c/c sur le lien algoscript plus haut, faire dérouler le menu déroulant (Code JS, jusqu'à Graphic Output) puis le lancer, chaque clique calcule une génération.
J'ai donc deux points où je bloque :

Question 2 :

J'ai crée un tableau "2D" où je stocke mes données (1 = une cellule, 0 = pas de cellule). La première génération est générée aléatoirement, pas de soucis.
Le problème survient lors du calcul de toutes les autres générations et tient à pas grand chose :

La génération suivante n'est pas calculée en fonction de la génération précédente, mais en fonction de la génération en cours. J'ai beaucoup de mal à expliquer..

Hum.. chaque cellule a des coordonnées en x,y. Le code commence à calculer les cellules pour x= 1 à 13 et y = 1 par exemple. Du coup la suite est biaisée, car il calcule les cellules pour x = 1 à 13 et y = 2 en fonction non pas de la génération 1, mais de ce qu'il a déjà calculé (génération 2) + de la génération 1 qu'il n'a pas encore calculé.
En lançant le "graphic output" on se rend compte très bien que les cellules ne suivent pas correctement les règles énoncées.

J'ai pensé à créer un second tableau où stocker la génération précédente, afin qu'il calcule en fonction du second tableau, et qu'il attribue au premier. Mais le résultat est le même...
Des idées ?

Question 4-1 :

La création de génération aléatoire de longueur saisie par l'utilisateur me pose grand soucis. Cependant cela devrait être simple pour vous :
Je suis obligé de créer un tableau de base, de longueur saisie, remplie.
Comment puis-je arriver à créer un "tableau 2D" de longueur choisie, préremplie avec des 0, afin que je puisse attribuer par la suite un 0 ou un 1 aléatoirement ?

C'est un pavé, je m'en excuse, j'ai essayé d'être le plus concis.

Je vous remercie grandement d'avance,

Je joints une petite feuille explicative, enfin de mes recherches, un peu brouillon, mais cela permet de comprendre le code plus rapidement :
Et maintenant le code (j'espère que vous ne hurlerez pas au massacre haha) :

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
// Population
var v, h, x, y;
 
h = 25; // Var qui sert à rien pour l'instant
tour = 1; 
generation = 0;
 
 
do {
  h = h + 25;
  RectanglePlein(h, 25, 1, 125, 'black'); //  Que de l'esthétique, pour mettre une grille par la suite
} while (h != 125);
 
v = 25;
do {
  v = v + 25;
  RectanglePlein(25, v, 125, 1, 'black'); // De même, pas d’importance pour l’instant
} while (v != 125);
 
var T = [      // Var T -> le tableau dans lequel on stocke les coordonnées des cellules
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Cette ligne : y = 0 et x compris entre 0 et 13
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] // cette ligne : y = 13 et x compris entre 0 et 13
//x=0 1  2  3  4  5  6  7  8  9  10 11 12 13
];
 
for (x = 0; x < 14; x = x + 1) { // Pour x allant de 0 à 13 et x toujours < 14
  for (y = 0; y < 14; y = y + 1) { // pour y allant de 0 à 13 et y toujours < 14
    T[y][x] = Hasard(2); // On donne à chaque 0 du tableau soit 0, soit 1 par hasard pour la première génération
    T[0][x] = 0; // 4 lignes suivantes très importantes -> il faut que chaque extrémité reste tout le temps = à 0, cf + bas **
    T[13][x] = 0;
    T[y][0] = 0; 
    T[y][13]=0;
 
    if (T[y][x] == 1) { // Si un point de la coordonnée y,x = 1 (1 veut dire qu'il y a une cellule , 0 -> case vide)
      CerclePlein(y * 20 + 20, x * 20 + 20, 10, 'red'); // Cellules sont rouges - pour première génération
    } else {
      CerclePlein(y * 20 + 20, x * 20 + 20, 10, 'black'); // cases vides sont noires - pour première génération
    }
  }
}
 
function MouseClick(x, y) { // Très important, permet à chaque clique de calculer une nouvelle génération, moyen le plus simple trouvé pour calculer plusieurs générations. 1 clique = génération + 1. Une autre idée ?
  for (x = 0; x < 14; x = x + 1) { // Même chose que là-haut, on affecte à une cellule du rouge, à une case vide du noir, mais pour génération + 1
    for (y = 0; y < 14; y = y + 1) { 
      if (T[y][x] == 1) {
        CerclePlein(y * 20 + 20, x * 20 + 20, 10, 'red');
      } else {
        CerclePlein(y * 20 + 20, x * 20 + 20, 10, 'black');
      }
    }
  }
 
  for (y = 1; y <= 13; y = y + 1) { // 0 < y < 14 car comme dit, il ne faut pas calculer pour les extrémités
    for (x = 1; x <= 13; x = x + 1) { // pareil pour x
      if (T[y][x] == 0) {
        if ((T[y - 1][x] == 1) && (T[y][x + 1] == 1) && (T[y + 1][x]) == 1) { // ** voilà ici plus bas, on calcule par rapport à cellule case haut, case droite, case bas - cf scan
          T[y][x] = 1;
          CerclePlein(x * 20 + 20, y * 20 + 20, 10, 'red'); // scan -> jaune
        } else {
          if ((T[y - 1][x] == 1) && (T[y][x - 1] == 1) && (T[y][x + 1] == 1)) { // cf scan
            T[y][x] = 1;
            CerclePlein(x * 20 + 20, y * 20 + 20, 10, 'red'); // scan -> marron
          } else {
            if ((T[y - 1][x] == 1) && (T[y][x - 1] == 1) && (T[y + 1][x] == 1)) { // cf scan
              T[y][x] = 1;
              CerclePlein(x * 20 + 20, y * 20 + 20, 10, 'red'); // scan -> noir
            } else {
              if ((T[y][x - 1] == 1) && (T[y + 1][x] == 1) && (T[y][x + 1] == 1)) { // cf scan
                T[y][x] = 1;
                CerclePlein(x * 20 + 20, y * 20 + 20, 10, 'red'); // scan -> rose 
              }
            }
          }
        }
      } else {
        if (T[y][x] == 1) {
          if ((T[y][x - 1] + T[y - 1][x] + T[y + 1][x] + T[y][x + 1]) == 3) {// Si une cellule vivante est entourée de 3 cellules, elle le reste (Txy = 1)
            T[y][x] = 1;
            RectanglePlein(x * 20 + 20, y * 20 + 20 + 7, 7, 'red'); 
 
          } else {
            if ((T[y][x - 1] + T[y - 1][x] + T[y + 1][x] + T[y][x + 1]) == 2) { // Si une cellule vivante est entourée de 2 cellules, elle le reste (Txy = 1)
              T[y][x] = 1;
              RectanglePlein(x * 20 + 20, y * 20 + 20 + 7, 7, 'red');
            } else { // si aucun de ces deux cas -> cellule entourée de 0,1 ou 4 cellules, elle meurt -> tyx = 0
              T[y][x] = 0;
              CerclePlein(x * 20 + 20, y * 20 + 20, 10, 'black');
            }
          }
        }
      }
    }
  }
}
 
 
 
 
 
 
 
 
// 4 lignes suivantes cf scan ac quadrillage partie droite
// ROSE (T[y][x-1])
// ROUGE (T[y-1][x])
// ORANGE (T[y+1][x])
// VERT (T[y][x+1])