Suite de la javadoc + changement (on a travallier ensemble ^^

master
Allan POINT 4 years ago
parent 872460562e
commit 4cd9fe5017

@ -43,11 +43,7 @@
-->
<HBox>
<Label> Rules </Label>
<ChoiceBox>
<items>
<FXCollections fx:factory="emptyObservableList">
</FXCollections>
</items>
<ChoiceBox fx:id="regleChoiceBox" >
</ChoiceBox>
</HBox>
<Label>Row</Label>

@ -6,7 +6,18 @@ import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
* Classe qui s'ocupe de lancer l'application
* @author Yohan Breuil
* @author Allan Point
*/
public class Launcher extends Application {
/**
* Lance l'application
* @param primaryStage
* @throws Exception
*/
@Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(this.getClass().getResource("/fxml/VueJeu.fxml"));

@ -6,7 +6,16 @@ import model.cellule.Position;
import java.util.HashMap;
/**
* Représentation des cellules vivantes sur le plateau. Elle se met à jours automatiquement.
* @author Yohann Breuil
* @author Allan Point
*/
public class CellulesVivantes implements ObserverCellule {
/**
* Dictionaire contenant toutes les cellules vivantes
*/
private HashMap<Position, Cellule> cellVivantes;
public CellulesVivantes(){
@ -17,17 +26,40 @@ public class CellulesVivantes implements ObserverCellule {
this.cellVivantes = cellVivantes;
}
/**
* Récuperer une cellule vivante
* @param x Absisse de la cellule
* @param y Ordonée de la cellule
* @return La cellule (x; y) si elle est vivante. Sinon null
*/
public Cellule getAt(int x, int y){
Position p = new Position(x, y);
return cellVivantes.get(p);
}
/**
* Ajoute une paire clef:valeur (Postion:Cellule) dans le dictionaire contenant les cellules vivantes
* @param cell Cellule à ajouter
* @see Position
* @see Cellule
*/
private void addPeer(Cellule cell){ cellVivantes.put(cell.getPosition(), cell); }
/**
* Retir une paire clef:valeur (Postion:Cellule) du dictionaire contenant les cellules vivantes
* @param cellule Cellule à retirer
* @see Position
* @see Cellule
*/
private void rmPeer(Cellule cellule){
cellVivantes.remove(cellule.getPosition());
}
/**
* Comportement lors ce que le cellule notifit l'objet CellulesVivantes.
* Ici on ajoute ou retire la cellule du dictionaire qui contient les cellules vivante en fonction de la cellule qui à notifiée.
* @param cellule Cellule qui à notifiée
*/
@Override
public void update(Cellule cellule) {
if(cellule.isAlive()){
@ -37,10 +69,17 @@ public class CellulesVivantes implements ObserverCellule {
}
}
/**
* Cloner l'objet
* @return Le meme objet CellulesVivantes avec une référence diférente
*/
public CellulesVivantes clone(){
return new CellulesVivantes(new HashMap<>(cellVivantes));
}
/**
* Nétoie le dictionaire contenant les cellules vivantes
*/
public void reset(){
cellVivantes = new HashMap<>();
}

@ -1,17 +1,43 @@
package model;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import model.actualiseur.ActualiseurCellule;
import model.actualiseur.ActualiseurEtatCellule;
import model.arbitre.ArbitreConwayStyle;
import model.arbitre.ArbitreKiller;
import model.plateau.Plateau;
/**
* Permet de gerer le changement de règles
* @author Yohann Breuil
* @author Allan Point
*/
public class ChangeurRegle {
public ActualiseurCellule changerRegle(Regle regle, Plateau plateau){
switch (regle){
case CONWAY_STYLE -> {
private ObjectProperty<Regle> regleEnCours = new SimpleObjectProperty<>();
public Regle getRegleEnCours() { return regleEnCours.get(); }
public void setRegleEnCours(Regle regleEnCours) { this.regleEnCours.set(regleEnCours); }
public ObjectProperty<Regle> regleEnCoursProperty() { return regleEnCours; }
public ChangeurRegle(){
setRegleEnCours(Regle.values()[0]);
}
/**
* Change l'actualiseur en fonction des règles
* @param plateau Plateau actuel du jeu
* @return Un ActualiseurCellule avec le bon arbitre
* @see model.arbitre.Arbitre
* @see ActualiseurCellule
*/
public ActualiseurCellule changerRegle(Plateau plateau) {
switch (getRegleEnCours()){
case REGLE_KILLER -> {
return new ActualiseurEtatCellule(new ArbitreKiller(plateau));
}
default -> {
return new ActualiseurEtatCellule(new ArbitreConwayStyle(plateau));
}
default -> throw new IllegalArgumentException("Regle Inconue");
}
}
}

@ -6,12 +6,26 @@ import model.cellule.Position;
import java.util.LinkedList;
import java.util.List;
/**
* Classe permtant de compter des cellules
* @author Yohann Breuil
* @author Allan Point
*/
public class CompteurDeCellule {
/**
* Compte le nombre de voisinne de la cellule (x; y)
* @param x Absisse de la cellule à compter
* @param y Ordoné de la cellule à compter
* @param cellulesVivantes Toutes les cellule vivantes
* @return Le nombre de voisinne de la cellule (x; y)
*/
public int compteNombreCellulesAutour(int x, int y, CellulesVivantes cellulesVivantes){
int cpt = 0;
Cellule c;
List<Position> positionsAVerifier = new LinkedList<>();
// Définition des 8 diréction autour de la position (x; y)
positionsAVerifier.add(new Position(x-1, y-1));
positionsAVerifier.add(new Position(x, y-1));
positionsAVerifier.add(new Position(x+1, y-1));

@ -10,6 +10,11 @@ import model.boucleDeJeu.observer.ObserverBDJ;
import model.cellule.Cellule;
import model.plateau.Plateau;
/**
* Point d'entré du model
* @author Yohann Breuil
* @author Allan Point
*/
public class Manager implements ObserverBDJ {
private ActualiseurTour actualiseurTour;
private ActualiseurCellule actualiseurCellule;
@ -17,17 +22,31 @@ public class Manager implements ObserverBDJ {
private ChangeurRegle changeurRegle;
private boolean jeuLance;
public Manager(){
boucleDeJeu = new BoucleDeJeu5FPS();
((ObservableBDJ)boucleDeJeu).attacher(this);
changeurRegle = new ChangeurRegle();
Thread thread = new Thread(boucleDeJeu);
thread.start();
actualiseurCellule = changeurRegle.changerRegle(Regle.CONWAY_STYLE, new Plateau());
actualiseurCellule = changeurRegle.changerRegle(new Plateau());
actualiseurTour = new ActualiseurTourUnParUn();
jeuLance = false;
changeurRegle.regleEnCoursProperty().addListener((src)->actualiserActualiseurCellule());
}
/**
* Change l'actualiseur de cellule en fonction des règles
*/
private void actualiserActualiseurCellule(){
actualiseurCellule = changeurRegle.changerRegle(getActualiseurCellule().getArbitre().getPlateau());
}
/**
* Comportement à adopter quand la boucle de jeu notifie le manager.
* (Actualier les cellules et le numéro de génération(tours))
*/
@Override
public void update() {
if(jeuLance) {
@ -40,6 +59,9 @@ public class Manager implements ObserverBDJ {
return actualiseurTour;
}
/**
* Actualiser l'état des cellules
*/
private void deleguerChangementCellule() {
CellulesVivantes reference = getActualiseurCellule().getArbitre().getPlateau().getCellulesVivantes().clone();
for (int y = 0; y<actualiseurCellule.getArbitre().getPlateau().getLigne(); ++y){
@ -47,28 +69,42 @@ public class Manager implements ObserverBDJ {
actualiseurCellule.changerCellule(x, y, reference);
}
}
}
/**
* Demende d'inversion de l'état d'une cellule
* @param c Cellue à inverser
*/
public void inverserEtatCellule(Cellule c){
getActualiseurCellule().getArbitre().getPlateau().getCell(c.getPosition().getX(), c.getPosition().getY()).inverseAlive();
}
public ActualiseurCellule getActualiseurCellule(){
return actualiseurCellule;
}
/**
* Authorise le lancement du jeu
*/
public void lancerJeu(){
jeuLance = true;
}
/**
* Met en pause le jeu
*/
public void pauseJeu(){jeuLance = false;}
/**
* Recommencer le jeu
*/
public void stoperJeu(){
actualiseurTour.resetTour();
actualiseurCellule.getArbitre().getPlateau().getCellulesVivantes().reset();
jeuLance = false;
}
//public void setPlateau(Plateau plateau) {
//this.plateau = plateau;
//}
public ChangeurRegle getChangeurRegle() {
return changeurRegle;
}
}

@ -1,5 +1,18 @@
package model;
/**
* Toutes les règles disponibles
*/
public enum Regle {
CONWAY_STYLE
/**
* La cellule nait si elle a exactement 3 voisin
* Elle reste en vie avec 2 ou 3 voisin
* Elle meurt dans les autres sitations
*/
CONWAY_STYLE,
/**
* Toutes les cellules meurts
*/
REGLE_KILLER
}

@ -2,10 +2,21 @@ package model.actualiseur;
import model.CellulesVivantes;
import model.arbitre.Arbitre;
import model.plateau.Plateau;
/**
* Gère l'actualisation des cellules (Abstraction)
* @author Yohann Breuil
* @author Allan Point
*/
public abstract class ActualiseurCellule {
private Arbitre arbitre;
/**
* Change l'état d'une cellule si besoin
* @param x Absisse de le cellule à changer
* @param y Ordonné de la cellule à changer
* @param reference CellulesVivantes au début du tour qui sert de référence
*/
public abstract void changerCellule(int x, int y, CellulesVivantes reference);
ActualiseurCellule(Arbitre arbitre) throws IllegalArgumentException{

@ -3,10 +3,22 @@ package model.actualiseur;
import model.CellulesVivantes;
import model.arbitre.Arbitre;
/**
* Permet de changer l'état d'une cellule si besoin
* @author Yohann Breuil
* @author Allan Point
*/
public class ActualiseurEtatCellule extends ActualiseurCellule{
public ActualiseurEtatCellule(Arbitre a) throws IllegalArgumentException{
super(a);
}
/**
* Peremet de changer l'état d'une cellule si besoin
* @param x Absisse de le cellule à changer
* @param y Ordonné de la cellule à changer
* @param reference CellulesVivantes au début du tour qui sert de référence
*/
@Override
public void changerCellule(int x, int y, CellulesVivantes reference) {
switch(getArbitre().verifierChangementCellules(x, y, reference)) {

@ -1,6 +1,18 @@
package model.actualiseur;
/**
* Comportement à adopter quand on veut actualiser des tours
* @author Yohann Breuil
* @author Allan Point
*/
public interface ActualiseurTour {
/**
* Changer le numéro de génération
*/
void changerTour();
/**
* Réinitialiser le numéro de génération
*/
void resetTour();
}

@ -3,6 +3,11 @@ package model.actualiseur;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
/**
* Actualiseur de tours qui incrémente le numéro de génération 1 par 1
* @author Yohann Breuil
* @author Allan Point
*/
public class ActualiseurTourUnParUn implements ActualiseurTour{
private IntegerProperty cptTour = new SimpleIntegerProperty();
@ -13,11 +18,18 @@ public class ActualiseurTourUnParUn implements ActualiseurTour{
public ActualiseurTourUnParUn(){
resetTour();
}
/**
* Incrémneter le numéro de génération de 1
*/
@Override
public void changerTour() {
setCptTour(getcptTour()+1);
}
/**
* Réinitialiser le numéro de génération à 0
*/
@Override
public void resetTour(){
cptTour.set(0);

@ -1,11 +1,11 @@
package model.arbitre;
import javafx.scene.control.Cell;
import model.CellulesVivantes;
import model.plateau.Plateau;
import model.cellule.CellState;
/**
* Arbitre selon les régles de Conway (3 voisinnes pour naitre, 2 ou 3 voisinnes pour survivre, meurt dans d'autre situations)
* @author Yohann Breuil
* @author Allan Point
*/

@ -0,0 +1,34 @@
package model.arbitre;
import model.CellulesVivantes;
import model.cellule.CellState;
import model.plateau.Plateau;
/**
* Arbitre qui tue toute les cellules
* @author Yohann Breuil
* @author Allan Point
*/
public class ArbitreKiller extends Arbitre{
/**
*
* @param plateau Plateau à arbitrer
* @see Arbitre
*/
public ArbitreKiller(Plateau plateau) {
super(plateau);
}
/**
*
* @param x Coordonée x de la cellule à checker
* @param y Coordonée y de la cellule à checker
* @param reference Toutes les cellules qui était vivantes au début du tour et qui servent donc de references
* @return L'état de la cellule au prohain tour
*/
@Override
public CellState verifierChangementCellules(int x, int y, CellulesVivantes reference) {
return CellState.DIE;
}
}

@ -7,6 +7,8 @@ import model.cellule.observer.ObservableCellule;
/**
* Classe métier représentant une cellule
* @author Yohann Breuil
* @author Allan Point
*/
public class Cellule extends ObservableCellule {
/**
@ -21,7 +23,6 @@ public class Cellule extends ObservableCellule {
private boolean alive;
/**
* TODO: Faire un poid mouche pour séparé les partis commune des cellules (livingColor)
* Permet d'avoir une propriété qui représente la coulleur de toutes les cellules vivantes
*/
private static ObjectProperty<Color> livingColor = new SimpleObjectProperty<>();
@ -57,13 +58,13 @@ public class Cellule extends ObservableCellule {
/**
*
* @return état de la cellule (vivante ou morte)
* @return True si la cellule est vivante. Sinon false.
*/
public Boolean isAlive() { return alive; }
/**
*
* @param alive
* Change l'état de la cellule en changant le couleur actve ainsi qu'en notifiant tout les abonnés du changement
* @param alive Booléen assigné a l'état de la cellule
*/
public void setAlive(Boolean alive) {
setActiveColor(alive ? (Color) getLivingColor() : deathColor);
@ -77,8 +78,8 @@ public class Cellule extends ObservableCellule {
/**
*
* @param o
* @return
* @param o Objet à comparrer
* @return True si les cellules ont les mêmes positions. Sinon false
*/
@Override
public boolean equals(Object o) {
@ -91,6 +92,10 @@ public class Cellule extends ObservableCellule {
}
return false;
}
/**
* Inverset l'état d'une cellule. La tue si elle est vivante et vice versa.
*/
public void inverseAlive(){
setAlive(!alive);
}

@ -3,10 +3,20 @@ package model.cellule;
import java.util.Objects;
/**
* Définit une position dans un axe x et y
* Représente une position dans un axe x et y (2 dimentions)
* @author Yohann Breil
* @author Allan Point
*/
public class Position {
/**
* Position x
*/
private int x;
/**
* Position y
*/
private int y;
/**
@ -30,12 +40,8 @@ public class Position {
/**
*
* @param valeur position x
* @throws IllegalArgumentException
*/
public void setX(int valeur) throws IllegalArgumentException{
if(valeur<0) {
//throw new IllegalArgumentException("La valeur de X doit être positive");
}
public void setX(int valeur){
x = valeur;
}
@ -50,15 +56,16 @@ public class Position {
/**
*
* @param valeur position y
* @throws IllegalArgumentException
*/
public void setY(int valeur) throws IllegalArgumentException{
if(valeur<0) {
// throw new IllegalArgumentException("La valeure de Y doit être positive");
}
y = valeur;
}
/**
*
* @param o L'objet à comparer
* @return True si les 2 positions on les mêmes coordonées. Sinon false.
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;

@ -7,25 +7,56 @@ import model.cellule.créateur.CreateurCellule;
import java.util.List;
/**
* Représentation du plateau de jeu
* @author Yohann Breuil
* @author Allan Point
*/
public class Plateau implements PrototypePlateau{
/**
* Pour créer corréctement des cellules
* @see CreateurCellule
*/
private CreateurCellule createurCellule;
/**
* Propriété qui permet de mettre en relation le nombre de colones avec la vue
*/
private IntegerProperty colone = new SimpleIntegerProperty();
public int getColone() { return colone.get();}
public void setColone(int valeur) { colone.set(valeur); resetGrille(valeur, getLigne());}
public IntegerProperty coloneProperty() { return colone; }
/**
* Propriété qui permet de mettre en relation le nombre de ligne avec la vue
*/
private IntegerProperty ligne = new SimpleIntegerProperty();
public int getLigne() { return ligne.get(); }
public void setLigne(int valeur ) { ligne.set(valeur); resetGrille(getColone(), valeur);}
public IntegerProperty ligneProperty() { return ligne; }
//private ObservableList<List<Cellule>> grilleObs = FXCollections.observableArrayList();
/**
* Représentation du plateau dans une liste à 2 dimention
*/
private ListProperty<List<Cellule>> grille = new SimpleListProperty<>();
public ListProperty<List<Cellule>> getGrille() { return (ListProperty<List<Cellule>>) grille.get(); }
public void setGrille(ListProperty<List<Cellule>> cells) {grille.set(cells);}
public ReadOnlyListProperty grilleProperty() { return grille;}
/**
* Enssemble des cellules vivante du plateau
* @see CellulesVivantes
*/
private CellulesVivantes cellulesVivantes;
/**
* Récuperer une cellule sur le plateau
* @param x Coordonée x
* @param y Coordonée y
* @return La cellule positioné en (x; y)
* @throws IllegalArgumentException x et y doivent être > 0 et respéctivement inferieur au nombre de colones et de ligne
*/
public Cellule getCell(int x, int y) throws IllegalArgumentException{
if(x < 0 || y < 0) {
throw new IllegalArgumentException("X ou Y est inférieur à 0");
@ -39,9 +70,18 @@ public class Plateau implements PrototypePlateau{
return grille.get().get(y).get(x);
}
/**
* Netoyer la grille
*/
public void resetGrille(){
resetGrille(getColone(), getLigne());
}
/**
* Créer une nouvelle grille
* @param colone nombre de colone de la grille
* @param ligne nombre de ligne de la grille
*/
public void resetGrille(int colone, int ligne){
setGrille(createurCellule.creerCellules(colone, ligne, cellulesVivantes));
}
@ -51,9 +91,22 @@ public class Plateau implements PrototypePlateau{
cellulesVivantes = new CellulesVivantes();
setGrille(new SimpleListProperty<>());
}
/**
*
* @param colone Nombre de colones du plateau
* @param ligne Nombre de lignes du plateau
*/
public Plateau(int colone, int ligne) {
this(colone, ligne, new CellulesVivantes());
}
/**
*
* @param colone Nombre de colone du plateau
* @param ligne Nombre de ligne du plateau
* @param observer CellulesVivantes qui veux observer les cellules crées
*/
public Plateau(int colone, int ligne, CellulesVivantes observer) {
createurCellule = new CreateurCellule(colone, ligne);
setLigne(ligne);
@ -62,12 +115,22 @@ public class Plateau implements PrototypePlateau{
setGrille(createurCellule.creerCellules(cellulesVivantes));
}
/**
*
* @param colone Nombre de colones du plateau
* @param ligne Nombre de lignes du plateau
* @param cellules Liste en 2 dimentions de cellules
*/
public Plateau(int colone, int ligne, ListProperty<List<Cellule>> cellules)
{
this(colone, ligne);
setGrille(cellules);
}
/**
* Clonne un plateau
* @return Le même plateau mais avec une référence différente
*/
@Override
public Plateau cloner() {
return new Plateau(getColone(), getLigne(), getGrille());

@ -1,5 +1,10 @@
package model.plateau;
/**
* Abstraction du clonnage de plateau
* @author Yohann Breuil
* @author Allan Point
*/
public interface PrototypePlateau {
Plateau cloner();
}

@ -1,25 +1,28 @@
package views;
import javafx.beans.property.Property;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ColorPicker;
import javafx.scene.control.Label;
import javafx.scene.control.Spinner;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import model.Manager;
import model.Regle;
import model.actualiseur.ActualiseurTourUnParUn;
import model.cellule.Cellule;
import model.plateau.Plateau;
import java.util.List;
import java.util.Random;
/**
* Code Behind de la vue
* @author Yohann Breuil
* @author Allan Point
*/
public class VueJeu {
@FXML
private Button random;
@FXML
private GridPane map;
@ -42,10 +45,15 @@ public class VueJeu {
@FXML
private Label numTour;
@FXML
private ChoiceBox<Regle> regleChoiceBox;
private Manager manager;
private Color deathColor;
private Plateau plateau;
/**
* Remplie une grille fxml avec des réctangles bindés au cellules
*/
public void createGrid() {
map.getChildren().clear();
for(int i=0; i < rowGame.getValue().intValue(); ++i) {
@ -59,6 +67,9 @@ public class VueJeu {
}
}
/**
* Fait naître des cellules aléatoirement sur la grille
*/
public void generateraRandom() {
resetGrid();
int ligne = manager.getActualiseurCellule().getArbitre().getPlateau().getLigne();
@ -69,38 +80,71 @@ public class VueJeu {
}
}
/**
* Initalisation de la vue
*/
public void initialize() {
// Remplissage des valeurs de la choice box des regles
regleChoiceBox.setItems(FXCollections.observableArrayList(Regle.values()));
manager = new Manager();
deathColor = Color.BLACK;
// Binding bidiréctionel entre les reglès de la vue et celles du model
regleChoiceBox.valueProperty().bindBidirectional(manager.getChangeurRegle().regleEnCoursProperty());
// Binding bidiréctionel entre la ligne de la vue et celle du model
rowGame.getValueFactory().valueProperty().bindBidirectional((Property) manager.getActualiseurCellule().getArbitre().getPlateau().ligneProperty());
//Binding bidiréctionel entre la colone du model et celle de la vue
colGame.getValueFactory().valueProperty().bindBidirectional((Property) manager.getActualiseurCellule().getArbitre().getPlateau().coloneProperty());
// Définition d'action lors de redimentionement
manager.getActualiseurCellule().getArbitre().getPlateau().coloneProperty().addListener((src)->resetGrid());
manager.getActualiseurCellule().getArbitre().getPlateau().ligneProperty().addListener((src)->resetGrid());
// Initialisation des valeurs des legnes et colones
colGame.getValueFactory().setValue(10);
rowGame.getValueFactory().setValue(10);
// Binding entre le colorPicker de la vue et la couleur de la cellule vivante
color.valueProperty().bindBidirectional(Cellule.livingColorProperty());
nbColGame.setText(colGame.getValue().toString());
nbRowGame.setText(rowGame.getValue().toString());
// Binding unidiréctionel des informations à afficher (dimentiobn de la grille et numéro de la génération
numTour.textProperty().bind(((ActualiseurTourUnParUn)manager.getActualiseurTour()).cptTourProperty().asString());
nbColGame.textProperty().bind(manager.getActualiseurCellule().getArbitre().getPlateau().coloneProperty().asString());
nbRowGame.textProperty().bind(manager.getActualiseurCellule().getArbitre().getPlateau().ligneProperty().asString());
}
/**
* Lancer le jeu
* @param actionEvent
*/
public void startGame(ActionEvent actionEvent) {
manager.lancerJeu();
}
/**
* Metre en pause le jeu
* @param actionEvent
*/
public void pauseGame(ActionEvent actionEvent) {
manager.pauseJeu();
}
/**
* Réinitialiser le jeu
* @param actionEvent
*/
public void resetGame(ActionEvent actionEvent){
manager.stoperJeu();
resetGrid();
}
/**
* Réinitialiser la grille
*/
public void resetGrid(){
manager.getActualiseurCellule().getArbitre().getPlateau().resetGrille();
createGrid();

Loading…
Cancel
Save