diff --git a/code/jeu de la vie/rsrc/fxml/VueJeu.fxml b/code/jeu de la vie/rsrc/fxml/VueJeu.fxml index 3befbd0..aab54b4 100644 --- a/code/jeu de la vie/rsrc/fxml/VueJeu.fxml +++ b/code/jeu de la vie/rsrc/fxml/VueJeu.fxml @@ -25,6 +25,7 @@ + - - + - - + + +
@@ -66,11 +68,17 @@
- - - - - - + + + + + + + + + + + + diff --git a/code/jeu de la vie/src/model/CellulesVivantes.java b/code/jeu de la vie/src/model/CellulesVivantes.java index 93842ea..d1d7c90 100644 --- a/code/jeu de la vie/src/model/CellulesVivantes.java +++ b/code/jeu de la vie/src/model/CellulesVivantes.java @@ -9,14 +9,20 @@ import java.util.HashMap; public class CellulesVivantes implements ObserverCellule { private HashMap cellVivantes; + public CellulesVivantes(){ + this(new HashMap<>()); + } + + private CellulesVivantes(HashMap cellVivantes){ + this.cellVivantes = cellVivantes; + } + public Cellule getAt(int x, int y){ Position p = new Position(x, y); return cellVivantes.get(p); } - private void addPeer(Cellule cell){ - cellVivantes.put(cell.getPosition(), cell); - } + private void addPeer(Cellule cell){ cellVivantes.put(cell.getPosition(), cell); } private void rmPeer(Cellule cellule){ cellVivantes.remove(cellule.getPosition()); @@ -30,4 +36,8 @@ public class CellulesVivantes implements ObserverCellule { rmPeer(cellule); } } + + public CellulesVivantes clone(){ + return new CellulesVivantes(cellVivantes); + } } diff --git a/code/jeu de la vie/src/model/Manager.java b/code/jeu de la vie/src/model/Manager.java index b916ab1..fc58f68 100644 --- a/code/jeu de la vie/src/model/Manager.java +++ b/code/jeu de la vie/src/model/Manager.java @@ -4,8 +4,11 @@ import model.actualiseur.ActualiseurCellule; import model.actualiseur.ActualiseurTour; import model.actualiseur.ActualiseurTourUnParUn; import model.boucleDeJeu.BoucleDeJeu30FPS; +import model.boucleDeJeu.BoucleDeJeu5FPS; import model.boucleDeJeu.IBoucleDeJeu; +import model.boucleDeJeu.observer.ObservableBDJ; import model.boucleDeJeu.observer.ObserverBDJ; +import model.cellule.Cellule; import model.plateau.Plateau; public class Manager implements ObserverBDJ { @@ -16,7 +19,8 @@ public class Manager implements ObserverBDJ { private boolean jeuLance; public Manager(){ - boucleDeJeu = new BoucleDeJeu30FPS(); + boucleDeJeu = new BoucleDeJeu5FPS(); + ((ObservableBDJ)boucleDeJeu).attacher(this); changeurRegle = new ChangeurRegle(); Thread thread = new Thread(boucleDeJeu); thread.start(); @@ -33,14 +37,20 @@ public class Manager implements ObserverBDJ { } } + public ActualiseurTour getActualiseurTour(){ + return actualiseurTour; + } + private void deleguerChangementCellule() { - for (int y=0; y getArbitre().getPlateau().getCell(x, y).setAlive(false); case LIVE, BIRTH -> getArbitre().getPlateau().getCell(x, y).setAlive(true); } diff --git a/code/jeu de la vie/src/model/actualiseur/ActualiseurTourUnParUn.java b/code/jeu de la vie/src/model/actualiseur/ActualiseurTourUnParUn.java index 0bc6d75..de23299 100644 --- a/code/jeu de la vie/src/model/actualiseur/ActualiseurTourUnParUn.java +++ b/code/jeu de la vie/src/model/actualiseur/ActualiseurTourUnParUn.java @@ -1,24 +1,25 @@ package model.actualiseur; +import javafx.beans.property.IntegerProperty; +import javafx.beans.property.SimpleIntegerProperty; + public class ActualiseurTourUnParUn implements ActualiseurTour{ - private int cptTour; + private IntegerProperty cptTour = new SimpleIntegerProperty(); + public int getcptTour(){return cptTour.get();} + private void setCptTour(int valeur){cptTour.set(valeur);} + public IntegerProperty cptTourProperty(){return cptTour;} public ActualiseurTourUnParUn(){ resetTour(); } @Override public void changerTour() { - ++cptTour; - } - - public int getTour() - { - return cptTour; + setCptTour(getcptTour()+1); } @Override public void resetTour(){ - cptTour = 0; + cptTour.set(0); } } diff --git a/code/jeu de la vie/src/model/arbitre/Arbitre.java b/code/jeu de la vie/src/model/arbitre/Arbitre.java index dbfebe6..49719df 100644 --- a/code/jeu de la vie/src/model/arbitre/Arbitre.java +++ b/code/jeu de la vie/src/model/arbitre/Arbitre.java @@ -9,11 +9,9 @@ public abstract class Arbitre { private Plateau plateau; private CompteurDeCellule compteurCell; - private CellulesVivantes cellulesVivantes; public Arbitre(Plateau plateau) { this.plateau = plateau; - cellulesVivantes = new CellulesVivantes(); compteurCell = new CompteurDeCellule(); } public Plateau getPlateau(){ @@ -21,10 +19,7 @@ public abstract class Arbitre { } protected CompteurDeCellule getCompteurCell(){ - return getCompteurCell(); + return compteurCell; } - protected CellulesVivantes getCellulesVivantes(){ - return cellulesVivantes; - } - public abstract CellState VerifierChangementCellules(int x, int y); + public abstract CellState verifierChangementCellules(int x, int y); } diff --git a/code/jeu de la vie/src/model/arbitre/ArbitreConwayStyle.java b/code/jeu de la vie/src/model/arbitre/ArbitreConwayStyle.java index 062333b..f066bc7 100644 --- a/code/jeu de la vie/src/model/arbitre/ArbitreConwayStyle.java +++ b/code/jeu de la vie/src/model/arbitre/ArbitreConwayStyle.java @@ -1,5 +1,6 @@ package model.arbitre; +import javafx.scene.control.Cell; import model.CellulesVivantes; import model.plateau.Plateau; import model.cellule.CellState; @@ -11,26 +12,26 @@ public class ArbitreConwayStyle extends Arbitre{ } @Override - public CellState VerifierChangementCellules(int x, int y) { - if(verifierNaissance(x, y)) { + public CellState verifierChangementCellules(int x, int y) { + if(verifierNaissance(x, y, getPlateau().getCellulesVivantes().clone())) { return CellState.BIRTH; } - if(verifierMort(x, y)) { + if(verifierMort(x, y, getPlateau().getCellulesVivantes())) { return CellState.DIE; } return getPlateau().getCell(x, y).isAlive() ? CellState.LIVE : CellState.DIE; } - private boolean verifierNaissance(int x, int y) { - int cpt = getCompteurCell().compteNombreCellulesAutour(x, y, getCellulesVivantes()); + private boolean verifierNaissance(int x, int y, CellulesVivantes reference) { + int cpt = getCompteurCell().compteNombreCellulesAutour(x, y, reference); if(cpt == 3 && !getPlateau().getCell(x, y).isAlive()) { return true; } return false; } - private boolean verifierMort(int x, int y) { - int cpt = getCompteurCell().compteNombreCellulesAutour(x, y, getCellulesVivantes()); + private boolean verifierMort(int x, int y, CellulesVivantes reference) { + int cpt = getCompteurCell().compteNombreCellulesAutour(x, y, reference); if(!(cpt == 2 || cpt == 3) && getPlateau().getCell(x, y).isAlive()) { return true; } diff --git a/code/jeu de la vie/src/model/boucleDeJeu/BoucleDeJeu5FPS.java b/code/jeu de la vie/src/model/boucleDeJeu/BoucleDeJeu5FPS.java new file mode 100644 index 0000000..a2c8ab9 --- /dev/null +++ b/code/jeu de la vie/src/model/boucleDeJeu/BoucleDeJeu5FPS.java @@ -0,0 +1,31 @@ +package model.boucleDeJeu; + +import model.boucleDeJeu.observer.ObservableBDJ; + +import java.util.LinkedList; + +public class BoucleDeJeu5FPS extends ObservableBDJ implements IBoucleDeJeu { + public BoucleDeJeu5FPS(){ + setObserveurs(new LinkedList<>()); + } + @Override + public void run() + { + while (true){ + try { + Thread.sleep(200); + beep(); + } + + // Gestion des exceptions : si le processus à été intérompu pendant le sleep, on le log. + catch (InterruptedException e) + { + return; + } + } + } + + public void beep() { + notifier(); + } +} diff --git a/code/jeu de la vie/src/model/boucleDeJeu/observer/ObservableBDJ.java b/code/jeu de la vie/src/model/boucleDeJeu/observer/ObservableBDJ.java index e52b152..5907173 100644 --- a/code/jeu de la vie/src/model/boucleDeJeu/observer/ObservableBDJ.java +++ b/code/jeu de la vie/src/model/boucleDeJeu/observer/ObservableBDJ.java @@ -1,5 +1,7 @@ package model.boucleDeJeu.observer; +import javafx.application.Platform; + import java.util.List; public abstract class ObservableBDJ { @@ -24,7 +26,7 @@ public abstract class ObservableBDJ { public void notifier() { for (ObserverBDJ observeur : observeurs) { - observeur.update(); + Platform.runLater(()->observeur.update()); } } } \ No newline at end of file diff --git a/code/jeu de la vie/src/model/cellule/Cellule.java b/code/jeu de la vie/src/model/cellule/Cellule.java index 2cbb52e..2748002 100644 --- a/code/jeu de la vie/src/model/cellule/Cellule.java +++ b/code/jeu de la vie/src/model/cellule/Cellule.java @@ -54,9 +54,9 @@ public class Cellule extends ObservableCellule { * @param alive */ public void setAlive(Boolean alive) { - notifier(this); setActiveColor(alive ? (Color) getLivingColor() : deathColor); this.alive.set(alive); + notifier(this); } public Position getPosition(){ @@ -79,4 +79,7 @@ public class Cellule extends ObservableCellule { } return false; } + public void inverseAlive(){ + setAlive(!alive.get()); + } } diff --git a/code/jeu de la vie/src/model/cellule/Position.java b/code/jeu de la vie/src/model/cellule/Position.java index 2c6206e..0d103ea 100644 --- a/code/jeu de la vie/src/model/cellule/Position.java +++ b/code/jeu de la vie/src/model/cellule/Position.java @@ -1,5 +1,7 @@ package model.cellule; +import java.util.Objects; + /** * Définit une position dans un axe x et y */ @@ -32,7 +34,7 @@ public class Position { */ public void setX(int valeur) throws IllegalArgumentException{ if(valeur<0) { - throw new IllegalArgumentException("La valeur de X doit être positive"); + //throw new IllegalArgumentException("La valeur de X doit être positive"); } x = valeur; } @@ -52,8 +54,21 @@ public class Position { */ public void setY(int valeur) throws IllegalArgumentException{ if(valeur<0) { - throw new IllegalArgumentException("La valeure de Y doit être positive"); + // throw new IllegalArgumentException("La valeure de Y doit être positive"); } y = valeur; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Position position = (Position) o; + return x == position.x && y == position.y; + } + + @Override + public int hashCode() { + return Objects.hash(x, y); + } } diff --git a/code/jeu de la vie/src/model/cellule/créateur/CreateurCellule.java b/code/jeu de la vie/src/model/cellule/créateur/CreateurCellule.java index 6f17d90..6b105d2 100644 --- a/code/jeu de la vie/src/model/cellule/créateur/CreateurCellule.java +++ b/code/jeu de la vie/src/model/cellule/créateur/CreateurCellule.java @@ -4,6 +4,7 @@ import javafx.beans.property.ListProperty; import javafx.beans.property.SimpleListProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; +import model.CellulesVivantes; import model.cellule.Cellule; import java.util.LinkedList; @@ -20,18 +21,21 @@ public class CreateurCellule implements ICreateurCellule { this.w = w; this.h = h; } - public ListProperty> creerCellules(){ - return creerCellules(w, h); + public ListProperty> creerCellules(CellulesVivantes observer){ + return creerCellules(w, h, observer); } - public ListProperty> creerCellules(int w, int h){ + public ListProperty> creerCellules(int w, int h, CellulesVivantes observer){ ObservableList> cellsInit = FXCollections.observableArrayList(); ListProperty> cells = new SimpleListProperty<>(cellsInit); List tmp; + Cellule c; for (int i = 0; i < h; i++) { tmp = new LinkedList<>(); for (int j = 0; j < w; j++) { - tmp.add(new Cellule(j, i)); + c = new Cellule(j, i); + c.attacher(observer); + tmp.add(c); } cells.add(tmp); } diff --git a/code/jeu de la vie/src/model/cellule/créateur/ICreateurCellule.java b/code/jeu de la vie/src/model/cellule/créateur/ICreateurCellule.java index 72e9dc0..ecade5e 100644 --- a/code/jeu de la vie/src/model/cellule/créateur/ICreateurCellule.java +++ b/code/jeu de la vie/src/model/cellule/créateur/ICreateurCellule.java @@ -1,9 +1,10 @@ package model.cellule.créateur; +import model.CellulesVivantes; import model.cellule.Cellule; import java.util.List; public interface ICreateurCellule { - List> creerCellules(); + List> creerCellules(CellulesVivantes observer); } diff --git a/code/jeu de la vie/src/model/cellule/observer/ObservableCellule.java b/code/jeu de la vie/src/model/cellule/observer/ObservableCellule.java index 6613af2..16459dd 100644 --- a/code/jeu de la vie/src/model/cellule/observer/ObservableCellule.java +++ b/code/jeu de la vie/src/model/cellule/observer/ObservableCellule.java @@ -2,14 +2,13 @@ package model.cellule.observer; import model.cellule.Cellule; -import java.util.Collection; -import java.util.TreeSet; +import java.util.*; public abstract class ObservableCellule { - Collection observeurs; + List observeurs; public ObservableCellule(){ - observeurs = new TreeSet<>(); + observeurs = new LinkedList<>(); } /** diff --git a/code/jeu de la vie/src/model/plateau/Plateau.java b/code/jeu de la vie/src/model/plateau/Plateau.java index 8255c45..2449b10 100644 --- a/code/jeu de la vie/src/model/plateau/Plateau.java +++ b/code/jeu de la vie/src/model/plateau/Plateau.java @@ -1,6 +1,7 @@ package model.plateau; import javafx.beans.property.*; +import model.CellulesVivantes; import model.cellule.Cellule; import model.cellule.créateur.CreateurCellule; @@ -23,6 +24,7 @@ public class Plateau implements PrototypePlateau{ public ListProperty> getGrille() { return (ListProperty>) grille.get(); } public void setGrille(ListProperty> cells) {grille.set(cells);} public ReadOnlyListProperty grilleProperty() { return grille;} + private CellulesVivantes cellulesVivantes; public Cellule getCell(int x, int y) throws IllegalArgumentException{ if(x < 0 || y < 0) { @@ -41,18 +43,23 @@ public class Plateau implements PrototypePlateau{ resetGrille(getLargeur(), getLongueur()); } public void resetGrille(int w, int h){ - setGrille(createurCellule.creerCellules(w, h)); + setGrille(createurCellule.creerCellules(w, h, cellulesVivantes)); } public Plateau(){ createurCellule = new CreateurCellule(0, 0); + cellulesVivantes = new CellulesVivantes(); setGrille(new SimpleListProperty<>()); } public Plateau(int longueur, int largeur) { + this(longueur, largeur, new CellulesVivantes()); + } + public Plateau(int longueur, int largeur, CellulesVivantes observer) { createurCellule = new CreateurCellule(longueur, largeur); setLargeur(largeur); setLongueur(longueur); - setGrille(createurCellule.creerCellules()); + cellulesVivantes = observer; + setGrille(createurCellule.creerCellules(cellulesVivantes)); } public Plateau(int longueur, int largeur, ListProperty> cellules) @@ -65,4 +72,8 @@ public class Plateau implements PrototypePlateau{ public Plateau cloner() { return new Plateau(getLongueur(), getLargeur(), getGrille()); } + + public CellulesVivantes getCellulesVivantes() { + return cellulesVivantes; + } } diff --git a/code/jeu de la vie/src/views/VueJeu.java b/code/jeu de la vie/src/views/VueJeu.java index 046671a..74dc7d2 100644 --- a/code/jeu de la vie/src/views/VueJeu.java +++ b/code/jeu de la vie/src/views/VueJeu.java @@ -2,6 +2,7 @@ package views; import javafx.beans.property.Property; import javafx.event.ActionEvent; +import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.scene.Node; import javafx.scene.control.Button; @@ -13,6 +14,7 @@ import javafx.scene.layout.GridPane; import javafx.scene.paint.Color; import javafx.scene.shape.Rectangle; import model.Manager; +import model.actualiseur.ActualiseurTourUnParUn; import model.cellule.Cellule; import model.plateau.Plateau; @@ -40,51 +42,31 @@ public class VueJeu { @FXML private Label nbColGame; + @FXML + private Label numTour; + private Manager manager; private Color deathColor; private Plateau plateau; public void createGrid() { - /*if (manager.getActualiseurCellule().getArbitre().getPlateau().getLongueur() > 100) { - manager.getActualiseurCellule().getArbitre().getPlateau().setLongueur(100); - } - if(manager.getActualiseurCellule().getArbitre().getPlateau().getLongueur() < 20) { - manager.getActualiseurCellule().getArbitre().getPlateau().setLongueur(20); - } - if (manager.getActualiseurCellule().getArbitre().getPlateau().getLargeur() > 50) { - manager.getActualiseurCellule().getArbitre().getPlateau().setLargeur(50); - } - if (manager.getActualiseurCellule().getArbitre().getPlateau().getLargeur() < 20) { - manager.getActualiseurCellule().getArbitre().getPlateau().setLargeur(20); - }*/ - map.getChildren().clear(); for(int i=0; i < colGame.getValue().intValue(); ++i) { for(int j=0; j < rowGame.getValue().intValue(); ++j) { Rectangle rect = new Rectangle(15, 15, color.getValue()); - rect.fillProperty().bindBidirectional(manager.getActualiseurCellule().getArbitre().getPlateau().getCell(j, i).activeColorProperty()); + Cellule c = manager.getActualiseurCellule().getArbitre().getPlateau().getCell(j, i); + rect.fillProperty().bindBidirectional(c.activeColorProperty()); + rect.setOnMouseClicked((src)->manager.inverserEtatCellule(c)); map.add(rect, i, j); } } } - @FXML - public void changeColor(MouseEvent mouseEvent) { - try { - Node source = (Node)mouseEvent.getSource(); - Integer colIndex = GridPane.getColumnIndex(source); - Integer rowIndex = GridPane.getRowIndex(source); - map.add(new Rectangle(15, 15, color.getValue()), colIndex.intValue(), rowIndex.intValue()); - } catch (NullPointerException e){} - - } - public void generateraRandom() { - //createGrid(manager.getActualiseurCellule().getArbitre().getPlateau().getLargeur(), manager.getActualiseurCellule().getArbitre().getPlateau().getLongueur()); resetGrid(); int largeur = manager.getActualiseurCellule().getArbitre().getPlateau().getLargeur(); int longueur = manager.getActualiseurCellule().getArbitre().getPlateau().getLongueur(); - for(int i=0; i<20; ++i) { + for(int i=0; i<(longueur+largeur)/2; ++i) { Random random = new Random(); manager.getActualiseurCellule().getArbitre().getPlateau().getCell(random.nextInt(longueur), random.nextInt(largeur)).setAlive(true); } @@ -97,18 +79,31 @@ public class VueJeu { colGame.getValueFactory().valueProperty().bindBidirectional((Property) manager.getActualiseurCellule().getArbitre().getPlateau().longueurProperty()); manager.getActualiseurCellule().getArbitre().getPlateau().longueurProperty().addListener((src)->resetGrid()); manager.getActualiseurCellule().getArbitre().getPlateau().largeurProperty().addListener((src)->resetGrid()); - color.valueProperty().bindBidirectional(Cellule.livingColorProperty()); + colGame.getValueFactory().setValue(10); + rowGame.getValueFactory().setValue(10); - // createGrid(); + color.valueProperty().bindBidirectional(Cellule.livingColorProperty()); nbColGame.setText(colGame.getValue().toString()); nbRowGame.setText(rowGame.getValue().toString()); + numTour.textProperty().bind(((ActualiseurTourUnParUn)manager.getActualiseurTour()).cptTourProperty().asString()); + nbColGame.textProperty().bind(manager.getActualiseurCellule().getArbitre().getPlateau().longueurProperty().asString()); + nbRowGame.textProperty().bind(manager.getActualiseurCellule().getArbitre().getPlateau().largeurProperty().asString()); } public void startGame(ActionEvent actionEvent) { manager.lancerJeu(); } + public void pauseGame(ActionEvent actionEvent) { + manager.pauseJeu(); + } + + public void resetGame(ActionEvent actionEvent){ + manager.stoperJeu(); + resetGrid(); + } + public void resetGrid(){ manager.getActualiseurCellule().getArbitre().getPlateau().resetGrille(); createGrid();