Created
October 20, 2011 10:34
-
-
Save lukaspili/1300856 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.supinfo.gameoflife; | |
public class AliveCell implements Cell { | |
private int age = 0; | |
public AliveCell() { | |
} | |
public AliveCell(int age) { | |
this.age = age; | |
} | |
@Override | |
public Cell newGeneration(int nbNeighbours) { | |
Cell result = null; | |
if (nbNeighbours == 2 || nbNeighbours == 3){ | |
age++; | |
result = this; | |
} else { | |
result = new DeadCell(); | |
} | |
return result; | |
} | |
@Override | |
public String getAsString() { | |
return age == 0 ? "0" : "+"; | |
} | |
@Override | |
public boolean isAlive() { | |
return true; | |
} | |
@Override | |
public int hashCode() { | |
final int prime = 31; | |
int result = 1; | |
result = prime * result + age; | |
return result; | |
} | |
@Override | |
public boolean equals(Object obj) { | |
if (this == obj) { | |
return true; | |
} | |
if (obj == null) { | |
return false; | |
} | |
if (getClass() != obj.getClass()) { | |
return false; | |
} | |
AliveCell other = (AliveCell) obj; | |
if (age != other.age) { | |
return false; | |
} | |
return true; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.supinfo.gameoflife; | |
public interface Cell { | |
Cell newGeneration(int nbNeighbours); | |
String getAsString(); | |
boolean isAlive(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.supinfo.gameoflife; | |
public class DeadCell implements Cell { | |
@Override | |
public Cell newGeneration(int nbNeighbours) { | |
Cell newCell; | |
if (nbNeighbours == 3) { | |
newCell = new AliveCell(); | |
} | |
else { | |
newCell = this; | |
} | |
return newCell; | |
} | |
@Override | |
public String getAsString() { | |
return "-"; | |
} | |
@Override | |
public Boolean isAlive() { | |
return false; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.supinfo.gameoflife; | |
public class Launcher { | |
public static void main(String[] args) { | |
World world = new World(10, 10); | |
for (int i = 0; i < 100; i++) { | |
world.nextGeneration(); | |
System.out.println(world); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.supinfo.gameoflife; | |
import java.util.Random; | |
public class World { | |
// constantes qui définissent une taille par défaut du monde | |
private static final int NB_ROWS = 100; | |
private static final int NB_COLUMNS = 100; | |
// le tableau à double dimension va contenir les cellules | |
private Cell[][] world; | |
// le tableau à double dimension de même taille que le tableau de cellule | |
// mais qui va contenir le nombre de voisin pour chaque cellule | |
private int[][] neighbourNumbers; | |
// la generation commence à 1 | |
private int generation = 1; | |
/** | |
* Constructeur par défaut | |
*/ | |
public World() { | |
// Appeller le constructeur surchargé World(int nbColumns, int nbRows) | |
this(NB_COLUMNS, NB_ROWS); | |
} | |
/** | |
* Constructeur surchargé qui prend en paramètre 2 nombres, qui vont | |
* correspondre à la taille du tableau des cellules | |
* | |
*/ | |
public World(int nbColumns, int nbRows) { | |
// initialiser le tableau des cellules avec la bonne taille | |
this.world = new Cell[nbRows][nbColumns]; | |
// ainsi que le tableau des voisins | |
this.neighbourNumbers = new int[nbRows][nbColumns]; | |
// remplir le tableau des cellules avec des valeurs par défaut | |
// aléatoires | |
initRandomWorld(); | |
// définir les voisins de chaque cellule | |
initNeighbours(); | |
} | |
/** | |
* Constructeur surchargé qui prend en paramètre un tableau de cellule à | |
* double dimension | |
*/ | |
public World(Cell[][] world) { | |
// si le tableau est correct alors on le set dans l'attribut | |
// correspondant | |
this.world = world; | |
// et on créé un tableau de voisin correspondant à la bonne taille du | |
// tableau | |
this.neighbourNumbers = new int[world.length][world[0].length]; | |
// puis on définit les voisins pour chaque cellule | |
initNeighbours(); | |
} | |
/** | |
* Remplir le tableau avec des cellules vivante ou morte de manière | |
* aléatoire | |
*/ | |
private void initRandomWorld() { | |
// créer un nouvel objet random qui va nous permettre de générer des | |
// valeurs aléatoires | |
Random random = new Random(); | |
// parcourir le tableau de cellules à double dimension | |
for (int y = 0; y < world.length; y++) { | |
for (int x = 0; x < world[y].length; x++) { | |
// pour chaque element du tableau, y ajouter une cellule... | |
if (random.nextBoolean()) { | |
// ...vivante | |
world[y][x] = new AliveCell(); | |
} else { | |
// ...ou morte | |
world[y][x] = new DeadCell(); | |
} | |
} | |
} | |
} | |
/** | |
* Définir les voisins pour chaque cellule | |
*/ | |
private void initNeighbours() { | |
// parcourir le tableau à double dimension | |
for (int y = 0; y < world.length; y++) { | |
for (int x = 0; x < world[y].length; x++) { | |
// pour chaque élément du tableau = pour chaque cellule, nous | |
// allons calculer le nombre de voisin | |
int sum = 0; | |
// il faut définir dans quelles zones rechercher les cellules en | |
// fonction des limites du tableau | |
int yMin = (y - 1 >= 0) ? y - 1 : 0; | |
int yMax = (y + 1 < world.length) ? y + 1 : world.length - 1; | |
int xMin = (x - 1 > 0) ? x - 1 : 0; | |
int xMax = (x + 1 < world[y].length) ? x + 1 : world[y].length - 1; | |
// parcourir la zone à 2 dimensions définie précdemment | |
for (int y2 = yMin; y2 <= yMax; y2++) { | |
for (int x2 = xMin; x2 <= xMax; x2++) { | |
// ajouter un voisin uniquement dans le cas ou la | |
// cellule voisine est vivante et si ce n'est pas la | |
// cellule elle même ! | |
if ((x2 != x || y2 != y) && world[y2][x2].isAlive()) { | |
sum++; | |
} | |
} | |
} | |
// ajouter le nombre de voisin au tableau | |
neighbourNumbers[y][x] = sum; | |
} | |
} | |
} | |
/** | |
* Créer une nouvelle génération de cellule | |
*/ | |
public void newGeneration() { | |
// parcourir le tableau de cellules | |
for (int y = 0; y < world.length; y++) { | |
// à 2 dimensions | |
for (int x = 0; x < world[y].length; x++) { | |
// pour chaque cellule du tableau, créer la génération suivante | |
// en lui passant son nombre de voisin. C'est l'avantage ici | |
// d'avoir un 2ème tableau contenant le nombre de voisin pour | |
// chaque cellule, on n'a pas a calculer à chaque fois pour | |
// chaque cellule | |
world[y][x] = world[y][x].newGeneration(neighbourNumbers[y][x]); | |
} | |
} | |
generation++; | |
initNeighbours(); | |
} | |
/** | |
* Surcharge de la méthode. Cette méthode est appelée dès qu'il faut un | |
* équivalent en chaine de caractère de l'objet. Ici on affiche le monde de | |
* cellule | |
* | |
*/ | |
public String toString() { | |
String str = "Generation " + generation + ": \n"; | |
for (int y = 0; y < world.length; y++) { | |
for (int x = 0; x < world[y].length; x++) { | |
str += world[y][x].getAsString() + " "; | |
} | |
str += '\n'; | |
} | |
return str; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment