Dec 09 2009

The Game of Life

Category: C, SDLFaltad @ 1:50 pm

Avant de commencer, il faut définir ce qu’est un automate cellulaire :
Grossièrement, c’est une grille ou tableau qui contient un nombre défini de cellules.
Il y a plusieurs états possible pour une cellule et chaque cellule dépend de l’état de ses voisines.
A chaque génération, on applique un ensemble de règles sur la grille, ce qui donne une nouvelle grille et ainsi de suite.

Parmi les automates cellulaires, on peut s’intéresser plus particulièrement au jeu de la vie.

Inventé en 1970 par John Horton Conway, il possède quatres règles très simple et chaque cellule possède seulement deux états : morte ou vivante.

Les règles sont :

  • Chaque cellule avec moins de 2 voisines vivantes meurt (ou reste morte).
  • Chaque cellule avec plus de 3 voisines vivantes meurt aussi (ou reste morte).
  • Chaque cellule vivante avec 2 ou 3 voisines vivantes reste en vie.
  • Chaque cellule morte avec 3 voisines vivantes ressuscite.

Je me suis amusé à faire une implémentation de ce jeu, à l’aide de la SDL.
Cela se représente facilement à l’aide d’un double tableau, où chaque cellule correspond à une case.

Voici un petit aperçu :
life

Le piège qu’il peut y avoir, c’est de bien faire gaffe au fait que toutes les cellules sont modifiées en même temps. Il faut donc deux tableaux pour avoir l’ancienne génération, et celle à venir.
Avec la SDL, on peut s’amuser à rendre le jeu un peu plus intéractif, grâce aux événements et autre.
J’ai implémenté la mise en pause du programme, ainsi que la modification de la carte à l’aide de la souris.

Ça a l’air un peu brouillon présenté comme cela, mais il y a de nombreuses structures qui reviennent assez souvent :
Par exemple les vaisseaux, c’est un ensemble de cellules qui peut se déplacer, sans se détruire. Le plus connu étant le glider.

On peut avoir aussi des canons, c’est une structure qui générera indéfiniment des vaisseaux, comme par exemple le canon à glider :
glider

Il y a de nombreuses autres structures, plus compliquées, ou plus simple que l’on peut retrouver facilement sur google.

Pour colorier l’écran, je me suis servi de ces deux fonctions :


/* On colorie une zone pixel par pixel */
void            color_cell(int i, int j, int boolean, SDL_Surface *screen)
{
   int          x, y;

   if (boolean)
      boolean = SDL_MapRGB(screen->format, 0, 0, 0);
   else
      boolean = SDL_MapRGB(screen->format, 255, 255, 255);
   for (y = j; y < j + SIZE_CELL; y++)
      for (x = i; x < i + SIZE_CELL; x++)
         setPixel(screen, x, y, boolean);
}
/* Colorie un pixel sur l'écran */
void setPixel(SDL_Surface* screen, int x, int y, Uint32 color)
{
   Uint8 *p;

   if (x < screen->w && y < screen->h)
    {
       p = (Uint8 *)screen->pixels +
	y * screen->pitch + x * screen->format->BytesPerPixel;
      *(Uint32 *)p = color;
    }
}

J'ai préféré utiliser seulement la SDL_Surface répresentant l'écran, en modifiant pixel par pixel, pour mieux gérer les tailles des cellules.
Bon, voilà, si vous voulez vous amuser, les sources sont ici

Il vous faut la libsdl-dev, sinon, ça ne risque pas de compiler !

(Vous pouvez aussi regarder du côté de golly, c'est "un peu" plus complet)

Avec un peu de random de temps à autre, ça peut faire un joli écran de veille :D
N'hésitez pas à creuser le sujet, ceci n'était qu'un très simple aperçu !