Le jeu de la vie : implémentation sous Maple

Introduction :

Je partirais du principe que vous connaissez déjà le jeu de la vie (si ce n'est pas le cas, un petit tour sur cette page pourrait vous être bien utile..). Étant le sujet de mes T.I.P.E. à dominante informatique, le seul langage alors autorisé et compréhensible par mon juri était Maple. De plus, les ordinateurs de mon établissement ne possédaient que la version 4 (gratuite car trop vieille). Je me décharge donc du choix du langage utilisé et de la vétusté du code utilisé.

Description :

Il s'agit d'un petit programme que je vais commenter tout du long qui permet de calculer des générations et même de créer une animation montrant son évolution.

restart:
Inutile de s'étendre sur la chose..
with(linalg):
with(plots):
Chargement des bibliothèques "Linalg" pour l'utilisation des matrices utilisées pour l'implémentation des configurations et de "Plots" comme librairie graphique.
rand_matrix:=proc(n,p,m)
  local A,i,j,t;
  t:=rand(100);
  A:=matrix(n,p);
  for i from 1 to n do
    for j from 1 to p do
      A[i,j]:= `if`(t()<m,1,0);
    end do;
  end do;
  evalm(A);
end:
[matrice] rand_matrix([n:int], [p:int], [m:int]) : crée un espace à n lignes et p colonnes avec une probabilité de m% par case d'avoir une cellule vivante.
Voici ce qui nous permetera de générer des "soupes". On peut voir comment sont utilisées les matrices pour représnter l'espace.
next_gen:=proc(A)
  local M,n,p,i,j,t,adj;
  n:=rowdim(A);
  p:=coldim(A);
  M:=Matrix(n,p);
  adj:=proc(x,y)
    local t;
    t:=0;
    if (A[(x-2 mod n)+1,(y-2 mod p)+1] = 1) then
	  t:=t+1;
    end if;
    if (A[(x-2 mod n)+1,y] = 1) then
      t:=t+1;
    end if;
    if (A[(x-2 mod n)+1,(y mod p)+1] = 1) then
      t:=t+1;
    end if;
    if (A[x,(y-2 mod p)+1] = 1) then
      t:=t+1;
    end if;
    if (A[x,(y mod p)+1] = 1) then
      t:=t+1;
    end if;
    if (A[(x mod n)+1,(y-2 mod p)+1] = 1) then
      t:=t+1;
    end if;
    if (A[(x mod n)+1,y] = 1) then
      t:=t+1;
    end if;
    if (A[(x mod n)+1,(y mod p)+1] = 1) then
      t:=t+1;
    end if;     
    t;    
  end;
  for i from 1 to n do
    for j from 1 to p do
      t:=adj(i,j);
      if (t=3) then
        M[i,j]:=1;
      end if;
      if (A[i,j]=1 and t=2) then
        M[i,j]:=1;
      end if;
    end do;
  end do;
  eval(M);
end:
[matrice] next_gen([A:matrice]) : calcule l'espace A à la génération suivante.
Ici, la génération suivante est calculée à l'aide d'une sous-procédure (qui reprend les méta-règles) appliquées à chaque cellule. Comme vous pouvez le voir, j'ai préféré la struture de tore plutôt que d'île.
calc_gen:=proc(A,n)
  local M,i;
  M:=A;
  for i from 1 to n do
    M:=next_gen(M);
  end do;
  eval(M);
end:
[matrice] calc_gen([A:matrice],[n:int]) : calcule l'espace A après n générations.
L'itération de la fonction précédente permet le calcul d'une génération donnée (exemple : la trentième génération d'une configuration A : calc_gen(A, 30);)
display_gen:=proc(A)
  local S,t,n,p,i,j;
  t:=0;
  n:=rowdim(A);
  p:=coldim(A);
  for i from 1 to n do
    for j from 1 to p do
      if A[i,j]=1 then
        S[t]:=[[j-1,n-i],[j,n-i],[j,n-i+1],
		[j-1,n-i+1],[j-1,n-i]];
        t:=t+1;
      end if;
    end do;
  end do;
  PLOT(POLYGONS(seq(S[i],i=0..t-1)), COLOR(RGB,0,0,0),
  AXESTICKS(0,0), AXESSTYLE(BOX), SCALING(CONSTRAINED),
  VIEW(0..p,0..n));
end:
[plot] display_gen([A:matrice]) : affiche une représentation de l'espace A.
Alors là, ça commence à se corser : on aborde la partie graphique. Chaque cellule vivante va être représentée par un carré noir ; Le tout sera sur un fond blanc. Les axes sont orthonormés et visibles sans leurs valeurs. L'espace est parcourru de cellule en cellule et si l'une d'entre elles est vivante, les coordonnées des quattre points du carré sont mémorisées dans une liste. Chaque liste de quattre points est un élément d'une liste (de carré donc) qui sera tracé via un "plot polygons".
anim_gen:=proc(A,n)
  local B,S,t;
  B:=A;
  S[0]:=display_gen(B);
  for t from 1 to n do
    B:=next_gen(B);
    S[t]:=display_gen(B);
  end do;
  display(seq(S[x],x=0..n), INSEQUENCE=TRUE,
  SCALING=CONSTRAINED);
end:
[plot] anim_gen([A:matrice], [n:int]) : affiche une annimation l'espace A durant n générations.
Si vous avez tout suivi jusque là, vous aurez compris tout de suite que c'est la fin : cette fonction se sert des fonction précédantes (next_gen(), display_gen()) pour créer une animation en prenant la liste des dessins faits à chaque générations et en les assemblant dans un "animate".

- Télécharger la feuille de travail -

Screenshot :

Apres avoir regardé le code, voyons un peu ce qu'il peut faire à travers ces exemples :

M1:=Matrix(4,4,[[0,0,0,0],[0,1,1,1]]);
display_gen(M1);
anim_gen(M1,10);
Voilà donc comment l'on rentre une configuration. Et voici ce que l'on peut en obtenir :

Exemple 1 Exemple 2 Un bel oscillateur 2-périodique ! Et maintenant un vaisseau :
M1:=Matrix(20,20,[[0,1,0],[0,0,1],[1,1,1]]):
display_gen(M1);
anim_gen(M1,100);
Exemple 3 Exemple 4 Et maintenant un canon (attention, beaucoup plus long à renter ..!)
M_canon:=Matrix(50,50,[[0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,1,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,
0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,
0,0,1,1],[0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,
0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1],[1,1,0,0,0,0,
0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,
0,0,0,0,0,0],[1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,
1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,
0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,
0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
1,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0]]):
anim_gen(M_canon, 100);
Exemple 5 Joli non ? Si vous vous souvenez de la première fonction (celle pour créer des soupes), en voici un exemple :
anim_gen(rand_matrix(100,100,25),100);
Exemple 6 Le tout seulement pour environ 1'30 de calcul ! Maple, quand tu nous tiens..

Suggestions :

Pour toutes suggestions, n'hésitez pas à me contacter via mon mail.

 
 
Admin