Jeu de la vie

Description

C'est une simple simulation du jeu de la vie de Conway.
L'algorithme n'est pas trop lent mais reste bien moins efficace que hashlife. L'univers est "presque" illimité (2^32 x 2^32 cellules). Possibilité de zoomer (molette de la souris) et de se déplacer (Touche majuscule enfoncée + glisser-déposer).
On peut ouvrir des fichiers au format life 1.05, rle et des images.

Source / Exemple :


package conway.controle;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import conway.presentation.PresentationConway;
import conway.presentation.PresentationPopulation;

/**

  • population representee par une table de hachage, la taille maximale de
  • l'univers est 2^32 * 2^32
  • @author guehenneux
  • /
public class PopulationTable implements Population { private Map<CleCellule, Cellule> cellules; private List<Cellule> cellulesMortes; private List<Cellule> cellulesNees; private long nombreCellulesVivantes; private int generation; private boolean editionManuellePossible; private PresentationPopulation presentation; private PresentationConway presentationConway; /**
  • /
public PopulationTable() { cellules = new HashMap<CleCellule, Cellule>(); nombreCellulesVivantes = 0; generation = 0; presentation = new PresentationPopulation(this); editionManuellePossible = true; } /**
  • @param cle
  • @return
  • /
private boolean isCelluleVivante(CleCellule cle) { Cellule cellule = cellules.get(cle); return cellule != null && cellule.vivante; } /**
  • /
private void appliquerRegles() { Collection<Cellule> collectionCellules = cellules.values(); cellulesMortes = new ArrayList<Cellule>(); cellulesNees = new ArrayList<Cellule>(); for (Cellule cellule : collectionCellules) { if (cellule.vivante) { if (cellule.nombreVoisins < 2 || cellule.nombreVoisins > 3) { cellulesMortes.add(cellule); } } else { if (cellule.nombreVoisins == 3) { cellulesNees.add(cellule); } } } } /**
  • /
private void actualiserCellules() { for (Cellule cellule : cellulesMortes) { mort(cellule); } for (Cellule cellule : cellulesNees) { naissance(cellule); } } /**
  • les cellules mortes n'ayant plus de voisins sont eliminees de la
  • population pour soulager l'algorithme
  • /
private void eliminerCellulesInutiles() { Collection<Cellule> collectionCellules = cellules.values(); Iterator<Cellule> iterateurCellules = collectionCellules.iterator(); Cellule cellule; while (iterateurCellules.hasNext()) { cellule = iterateurCellules.next(); if (!cellule.vivante && cellule.nombreVoisins == 0) { iterateurCellules.remove(); } } } /**
  • tue une cellule
  • @param cellule
  • /
private void mort(Cellule cellule) { cellule.vivante = false; nombreCellulesVivantes--; Cellule[] cellulesVoisines = getCellulesVoisines(cellule.cle); for (Cellule celluleVoisine : cellulesVoisines) { celluleVoisine.nombreVoisins--; } } /**
  • donne naissance a une cellule
  • @param cellule
  • /
private void naissance(Cellule cellule) { cellule.vivante = true; nombreCellulesVivantes++; Cellule[] cellulesVoisines = getCellulesVoisines(cellule.cle); for (Cellule celluleVoisine : cellulesVoisines) { celluleVoisine.nombreVoisins++; } } @Override public void generationSuivante() { /*
  • on applique les regles du jeu de la vie afin de determiner quelles
  • cellules changent d'etat (naissance ou mort)
  • /
appliquerRegles(); /*
  • on actualise le nombre de voisins des cellules en fonction des
  • changements d'etats
  • /
actualiserCellules(); /*
  • on elimine les cellules mortes n'ayant plus aucun voisins afin de
  • soulager l'algorithme, on ne le fait qu'une fois toutes les 16
  • generations pour ne pas surcharger l'algorithme
  • /
if ((generation & 15) == 0) { eliminerCellulesInutiles(); } generation++; } @Override public void actualiserPresentation() { if (presentationConway != null) { presentationConway.setGeneration(generation); presentationConway.setTaille(nombreCellulesVivantes); } } @Override public long getTaille() { return nombreCellulesVivantes; } @Override public void creerCelluleVivante(int x, int y) { CleCellule cle = new CleCellule(x, y); Cellule cellule = getCellule(cle); naissance(cellule); } @Override public void inverserCellule(int x, int y) { if (editionManuellePossible) { CleCellule cle = new CleCellule(x, y); Cellule cellule = getCellule(cle); if (cellule.vivante) { mort(cellule); } else { naissance(cellule); } } } /**
  • @param cle
  • la cle de la cellule a recuperer
  • @return la cellule correspond a la cle, elle est creee si elle n'existe
  • pas encore
  • /
private Cellule getCellule(CleCellule cle) { Cellule cellule = cellules.get(cle); if (cellule == null) { cellule = new Cellule(cle); cellules.put(cle, cellule); } return cellule; } /**
  • @param cle
  • la cle d'une cellule
  • @return un tableau contenant les cellules voisines de la cellule
  • correspondant a la cle passee en parametre
  • /
private Cellule[] getCellulesVoisines(CleCellule cle) { CleCellule[] clesVoisines = cle.getClesVoisines(); int nombreCellulesVoisines = clesVoisines.length; Cellule[] cellulesVoisines = new Cellule[nombreCellulesVoisines]; int indexCelluleVoisine = 0; for (CleCellule cleVoisine : clesVoisines) { cellulesVoisines[indexCelluleVoisine++] = getCellule(cleVoisine); } return cellulesVoisines; } @Override public void effacer() { cellules = new HashMap<CleCellule, Cellule>(); nombreCellulesVivantes = 0; } @Override public boolean[][] getEchantillon(int xMin, int yMin, int xMax, int yMax) { int x, y; CleCellule cle; int largeur = xMax - xMin; int hauteur = yMax - yMin; boolean[][] echantillon = new boolean[largeur][hauteur]; for (x = xMin; x < xMax; x++) { for (y = yMin; y < yMax; y++) { cle = new CleCellule(x, y); echantillon[x - xMin][y - yMin] = isCelluleVivante(cle); } } return echantillon; } @Override public int getGeneration() { return generation; } @Override public void setGeneration(int generation) { this.generation = generation; } @Override public PresentationPopulation getPresentation() { return presentation; } @Override public void setPresentationConway(PresentationConway presentationConway) { this.presentationConway = presentationConway; } @Override public void setEditionManuellePossible(boolean editionManuellePossible) { this.editionManuellePossible = editionManuellePossible; } }

Conclusion :


Sans être lent, l'algorithme n'est pas très efficace. L'application est loin d'être complète.
Le package utilitaire contient des petits bouts de code intéressants.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.