Commit 62a1b218 authored by Maxime Goret's avatar Maxime Goret
Browse files

Merge

parents 4f56c8d3 79d70f00
Pipeline #79750 passed with stage
in 15 seconds
......@@ -8,3 +8,7 @@ Dépendances : compilateur C++11, Qt
qmake
make
```
## Documentation
La documentation du projet et de ses classe est générée automatiquement par la CI et est disponible [ici](https://rdelaage.gitlab.utc.fr/lo21-projet/).
......@@ -26,8 +26,10 @@ class Automate {
std::string author;
std::string desc;
EnsembleEtat ensemble;
int nbStep;
int nbCycle;
Automate(): title(""), delai(500), fonction(nullptr), regleVoisinage(nullptr), itBuffer(buffer.begin()), h(0), l(0), reseauInit(Reseau(0, 0)), year(2000), author("Anonym"), desc("") { timer.automate = this; }
Automate(): title(""), delai(500), fonction(nullptr), regleVoisinage(nullptr), itBuffer(buffer.begin()), h(0), l(0), reseauInit(Reseau(0, 0)), year(2000), author("Anonym"), desc(""), nbStep(0), nbCycle(0) { timer.automate = this; }
Automate(const Automate& a) = delete;
Automate& operator=(const Automate& a) = delete;
class Timer: public QObject {
......@@ -107,12 +109,7 @@ class Automate {
void reset() { buffer.clear(); buffer.push_back(reseauInit); }
/// Se placer sur l'état suivant du buffer et le calculer s'il n'y en a plus de disponible
void step() {
if(itBuffer==(--buffer.end()))
nextTimer();
itBuffer++;
AutoCell::getInstance().afficherGrille(&*itBuffer);
}
void step();
/// Execution multiple de la méthode step
void run(int n) {
for(int i=0;i<n;i++)
......@@ -159,7 +156,15 @@ class Automate {
/// Définir le comportement aux frontières
void setMatriceTorique(const bool val) { regleVoisinage->setMatriceTorique(val); }
/// Obtenir le comportement aux frontières
bool getMatriceTorique() { return regleVoisinage->getMatriceTorique(); }
/// Obtenir le nombre d'étapes effectuées
int getNbStep() const { return nbStep; }
/// Obtenir le nombre d'étapes nécessaires pour effectuer un cycle
///
/// Retourne 0 s'il n'a pas encore pu être calculé
int getNbCycle() const { return nbCycle; }
};
#endif
......@@ -73,6 +73,11 @@ class AutoCell : public QWidget
QPushButton* button_next;
QPushButton* button_reinitialiser;
QLabel* lab_nb_step;
QLineEdit* edit_nb_step;
QLabel* lab_periode;
QLineEdit* edit_periode;
QLabel* lab_sauv_grille;
QLineEdit* edit_nom_grille;
QPushButton* button_save_grid;
......@@ -81,10 +86,6 @@ class AutoCell : public QWidget
QWidget* win_grid;
QTableWidget* grid;
//notice
QWidget* win_notice;
QLabel* lab_notice;
explicit AutoCell(QWidget* parent=nullptr);
friend class NouveauModele;
public:
......@@ -131,7 +132,7 @@ class AutoCell : public QWidget
/// Initialiser un automate par son nom
void initAutomate(const QString& name);
/// Changer le délai de l'automate
void changeDelai(int i);
void changeDelai();
/// Aller en arrière dans la simulation
void previous();
/// Aller en avant dans la simulation
......
......@@ -27,7 +27,7 @@ class ParamAlpha: public QWidget {
public:
/// Construire une fenêtre de paramétrage de l'alphabet
/// @param[in] nbEtats nombre d'états à initialiser
ParamAlpha(const int nbEtats);
ParamAlpha(const int nbEtats, const QWidget* parent);
public slots:
/// Valider le paramétrage de l'alphabet, a pour effet de l'initialiser dans l'automate
void valide();
......
......@@ -19,97 +19,130 @@
using namespace std;
/// Classe conteneur d'un voisinage
///
/// Elle contient l'ensemble des voisins d'une cellule après application d'une règle de voisinage et définit la cellule au centre du voisinage
class Voisinage {
private :
const Cellule* celluleCentre;
vector<Cellule*> voisinage;
friend class RegleVoisinage;
friend class RegleVoisinageMoore;
friend class RegleVoisinageNeumann;
friend class RegleVoisinageArbitraire;
friend class VoisinageIterator;
public:
class VoisinageIterator {
const Voisinage *vsn;
size_t i;
public :
VoisinageIterator(const Voisinage *v){
vsn = v;
}
void first(){
i = 0;
}
void next(){
i++;
}
bool isDone(){
return !(i < vsn->voisinage.size());
}
Cellule* currentItem(){
return vsn->voisinage[i];
}
};
private :
const Cellule* celluleCentre;
vector<Cellule*> voisinage;
Voisinage(const Cellule* centre) : celluleCentre(centre) {}
~Voisinage();
Cellule getCelluleCentre()const {return *celluleCentre;}
friend class RegleVoisinage;
friend class RegleVoisinageMoore;
friend class RegleVoisinageNeumann;
friend class RegleVoisinageArbitraire;
friend class VoisinageIterator;
VoisinageIterator *creerIterator()const{
return new VoisinageIterator(this);
}
public:
/// Classe d'itérateur sur les cellules contenus dans le voisinage
class VoisinageIterator {
const Voisinage *vsn;
size_t i;
public :
///Construire un itérateur sur le voisinage
VoisinageIterator(const Voisinage *v) { vsn = v; }
/// place l'itérateur sur le premier élément
void first() { i = 0; }
/// placer l'itérateur sur l'élément suivant
void next() { i++; }
/// vérifier si les itérations sont terminées
bool isDone() { return !(i < vsn->voisinage.size()); }
/// Récupérer l'élément courant de l'itérateur
Cellule* currentItem() { return vsn->voisinage[i]; }
};
Voisinage(const Cellule* centre): celluleCentre(centre) {}
~Voisinage();
/// Obtenir la cellule au centre du voisinage
Cellule getCelluleCentre() const { return *celluleCentre; }
/// Créer un itérateur sur les cellules du voisinage
VoisinageIterator *creerIterator() const { return new VoisinageIterator(this); }
};
/// Classe mère abtraite de toutes les règles de voisinage
class RegleVoisinage{
private:
bool matriceTorique;
public :
/// Calculer un voisinage sur un réseau à partir de la règle
/// @param[in] v Objet Voisinage dans lequel on souhaite stocker les voisins
/// @param[in] r Réseau à partir duquel on souhaite calculer le voisinage
virtual void calculVoisinage(Voisinage& v, const Reseau& r) const = 0;
/// Obtenir le type de la règle de voisinage
///
/// Principalement utilisé pour la sauvegarde
virtual int getType() const = 0;
/// Renvoie le rayon d'une règle de voisinage, 0 si ce n'est pas pertinant pour ce voisinage (arbitraire, ...)
///
/// Principalement utilisé pour la sauvegarde
virtual unsigned int getr() const { return 0; }
virtual ~RegleVoisinage() = default;
/// Définir le comportement aux frontières du voisinage
///
/// Si true, on se comporte comme une matrice torique, quand on arrive en haut on continu en utilisant les lignes du bas, de même pour quand on est à gauche ou à droite de la matrice
/// Si false, on ne prend pas en compte les voisins au delà de la matrice affichée.
void setMatriceTorique(const bool val) { matriceTorique = val; }
/// Obtenir l'état du comportement aux frontières
bool getMatriceTorique() const { return matriceTorique; }
};
/// Règle générale pour un voisinage de Von Neumann
class RegleVoisinageNeumann : public RegleVoisinage {
private:
unsigned int rayon;
public:
/// Calculer un voisinage sur un réseau à partir de la règle
/// @param[in] v Objet Voisinage dans lequel on souhaite stocker les voisins
/// @param[in] r Réseau à partir duquel on souhaite calculer le voisinage
void calculVoisinage(Voisinage& v, const Reseau& r) const override;
/// Définir le rayon du voisinage
void setr(unsigned int r) { rayon = r; }
unsigned int getr() const override { return rayon; }
int getType() const override { return 1; }
/// Obtenir le rayon du voisinage
unsigned int getr() const override { return rayon; }
/// Obtenir le type de la règle de voisinage
///
/// Principalement utilisé pour la sauvegarde
int getType() const override { return 1; }
};
/// Règle générale pour un voisinage de Moore
class RegleVoisinageMoore : public RegleVoisinage {
private:
unsigned int rayon;
public:
/// Calculer un voisinage sur un réseau à partir de la règle
/// @param[in] v Objet Voisinage dans lequel on souhaite stocker les voisins
/// @param[in] r Réseau à partir duquel on souhaite calculer le voisinage
void calculVoisinage(Voisinage& v, const Reseau& r) const override;
/// Définir le rayon du voisinage
void setr(unsigned int r) { rayon = r; }
unsigned int getr() const override { return rayon; }
int getType() const override { return 2; }
/// Obtenir le rayon du voisinage
unsigned int getr() const override { return rayon; }
/// Obtenir le type de la règle de voisinage
///
/// Principalement utilisé pour la sauvegarde
int getType() const override { return 2; }
};
class RegleVoisinageArbitraire : public RegleVoisinage { //définit la règle pour le voisinage arbitraire
private:
unsigned int nbVoisin;
public:
int getType() const override{ return 3; }
void setNbVoisins(unsigned int r) { nbVoisin = r; }
unsigned int getNbVoisin() { return nbVoisin; }
vector<Coordonnees> coordonnees;
void calculVoisinage(Voisinage& v, const Reseau& r) const override; // Calcul du voisinage en fonction de la cellule centre
vector<Coordonnees> getVoisinage(const QTableWidget* grid ); // Dééfinition des coordonnées relatives pour le calcul du voisinage
///définit la règle pour le voisinage arbitraire
class RegleVoisinageArbitraire : public RegleVoisinage {
public:
/// Obtenir le type de la règle de voisinage
///
/// Principalement utilisé pour la sauvegarde
int getType() const override{ return 3; }
/// Obtenir le nombre de voisins de cette règle de voisinage
unsigned int getNbVoisin() { return coordonnees.size(); }
/// coordonnées relatives des voisins d'une cellule
vector<Coordonnees> coordonnees;
/// Calculer un voisinage sur un réseau à partir de la règle
/// @param[in] v Objet Voisinage dans lequel on souhaite stocker les voisins
/// @param[in] r Réseau à partir duquel on souhaite calculer le voisinage
void calculVoisinage(Voisinage& v, const Reseau& r) const override;
/// Obtenir les coordonnées relative d'un voisinage arbitraire en fonction d'un outil QTableWidget
vector<Coordonnees> getVoisinage(const QTableWidget* grid );
};
#endif /* voisinage_h */
......@@ -44,3 +44,14 @@ void Automate::reinitialiserAutomate() {
desc = "";
ensemble.reset();
}
void Automate::step() {
if(itBuffer==(--buffer.end())) {
nextTimer();
++nbStep;
}
itBuffer++;
if(nbCycle == 0 && *(--buffer.end()) == reseauInit)
nbCycle = nbStep;
AutoCell::getInstance().afficherGrille(&*itBuffer);
}
......@@ -36,8 +36,8 @@ std::unique_ptr<AutoCell> AutoCell::instance = nullptr;
AutoCell::AutoCell(QWidget* parent):QWidget(parent)
{
this->setWindowTitle("Automate cellulaire");
this->setMinimumSize(1150, 650);
this->setWindowTitle("Automate cellulaire");
this->setMinimumSize(1000, 650);
//division en frame de la fenêtre de l'application
......@@ -134,10 +134,10 @@ AutoCell::AutoCell(QWidget* parent):QWidget(parent)
grid_run_control = new QGridLayout(win_run_ctrl);
grid_run_control->setColumnMinimumWidth(1,100);
grid_run_control->setColumnMinimumWidth(2,100);
grid_run_control->setColumnMinimumWidth(1,80);
grid_run_control->setColumnMinimumWidth(2,80);
grid_run_control->setRowMinimumHeight(3,80);
grid_run_control->setRowMinimumHeight(4,400);
grid_run_control->setRowMinimumHeight(7,300);
grid_run_control->addWidget(lab_run_crtl, 0,0,1,3,Qt::AlignTop);
......@@ -150,7 +150,7 @@ AutoCell::AutoCell(QWidget* parent):QWidget(parent)
spin_time_step->setFixedWidth(70);
spin_time_step->setValue(1000);
spin_time_step->setRange(500,2500);
connect(spin_time_step, SIGNAL(valueChanged(int)), this, SLOT(changeDelai(int)));
connect(spin_time_step, SIGNAL(valueChanged()), this, SLOT(changeDelai()));
button_prev = new QPushButton("<<");
button_prev->setStyleSheet("background-color: rgb(255,255,255)");
button_prev->setFixedSize(40,40);
......@@ -167,13 +167,31 @@ AutoCell::AutoCell(QWidget* parent):QWidget(parent)
button_reinitialiser->setStyleSheet("background-color: rgb(255,255,255)");
button_reinitialiser->setFixedWidth(200);
grid_run_control->addWidget(matriceTorique, 1, 0, 1, 2);
lab_nb_step = new QLabel("Nombre d'étapes : ");
edit_nb_step = new QLineEdit;
edit_nb_step->setReadOnly(true);
edit_nb_step->setFixedWidth(30);
edit_nb_step->setText("0");
edit_nb_step->setStyleSheet("background-color: rgb(255,255,255)");
lab_periode = new QLabel("Période observée : ");
edit_periode = new QLineEdit;
edit_periode->setReadOnly(true);
edit_periode->setFixedWidth(30);
edit_periode->setText("0");
edit_periode->setStyleSheet("background-color: rgb(255,255,255)");
grid_run_control->addWidget(matriceTorique, 1, 0, Qt::AlignCenter);
grid_run_control->addWidget(lab_time_step, 2, 0);
grid_run_control->addWidget(spin_time_step, 2, 1);
grid_run_control->addWidget(button_prev, 3, 0);
grid_run_control->addWidget(button_run, 3, 1);
grid_run_control->addWidget(button_next, 3, 2);
grid_run_control->addWidget(button_reinitialiser, 4, 0, Qt::AlignCenter);
grid_run_control->addWidget(button_reinitialiser, 4, 0, Qt::AlignTop);
grid_run_control->addWidget(lab_nb_step, 5,0);
grid_run_control->addWidget(edit_nb_step, 5,1);
grid_run_control->addWidget(lab_periode,6,0);
grid_run_control->addWidget(edit_periode,6,1);
lab_sauv_grille = new QLabel("Sauvegarder la grille courante");
edit_nom_grille = new QLineEdit;
......@@ -186,9 +204,9 @@ AutoCell::AutoCell(QWidget* parent):QWidget(parent)
button_save_grid->setFixedWidth(90);
connect(button_save_grid,SIGNAL(clicked()),this,SLOT(sauvegarderGrille()));
grid_run_control->addWidget(lab_sauv_grille,4,0,1,3, Qt::AlignBottom);
grid_run_control->addWidget(edit_nom_grille,5,0, Qt::AlignBottom);
grid_run_control->addWidget(button_save_grid,5,2,Qt::AlignBottom);
grid_run_control->addWidget(lab_sauv_grille,7,0,1,3, Qt::AlignBottom);
grid_run_control->addWidget(edit_nom_grille,8,0, Qt::AlignBottom);
grid_run_control->addWidget(button_save_grid,8,2,Qt::AlignBottom);
general->addWidget(win_run_ctrl,1,0,2,1);
......@@ -197,16 +215,6 @@ AutoCell::AutoCell(QWidget* parent):QWidget(parent)
win_grid = new QWidget;
grid = new QTableWidget(0,0,win_grid);
//notice
win_notice = new QWidget;
win_notice->setStyleSheet("background-color: rgb(204, 209, 209)");
win_notice->setMaximumWidth(300);
win_notice->setMinimumWidth(200);
lab_notice = new QLabel("Notice :", win_notice);
general->addWidget(win_notice,0,2,3,1);
};
void AutoCell::afficherGrille(Reseau* grille)
......@@ -261,6 +269,9 @@ void AutoCell::afficherGrille(Reseau* grille)
}
connect(grid,SIGNAL(clicked(const QModelIndex&)),this,SLOT(modifierCellule(const QModelIndex&)));
general->addWidget(win_grid,1,1,2,2);
edit_nb_step->setText(to_string(Automate::getInstance().getNbStep()).c_str());
edit_periode->setText(to_string(Automate::getInstance().getNbCycle()).c_str());
};
......@@ -298,9 +309,6 @@ void AutoCell::initialiserGrille(){
edit_hauteur->setText(str_hauteur.setNum(grille.getHauteur(),10));
}
//réinitialiser l'automate
Automate::getInstance().reset();
this->afficherGrille(&grille);
Automate::getInstance().setReseauInit(grille);
Automate::getInstance().initialiserBuffer();
......@@ -310,6 +318,8 @@ void AutoCell::RAZ(){
grid = new QTableWidget(0,0,win_grid);
edit_largeur->setText("");
edit_hauteur->setText("");
edit_nb_step->setText("0");
edit_periode->setText("0");
spin_time_step->setValue(1000);
check_aleatoire->setCheckState(Qt::Unchecked);
check_load_grid->setCheckState(Qt::Unchecked);
......@@ -407,8 +417,8 @@ void AutoCell::initAutomate(const QString& name) {
matriceTorique->setCheckState(Qt::Checked);
}
void AutoCell::changeDelai(int i) {
Automate::getInstance().setDelai(static_cast<unsigned int>(i));
void AutoCell::changeDelai() {
Automate::getInstance().setDelai(static_cast<unsigned int>(spin_time_step->value()));
}
void AutoCell::next() {
......
......@@ -204,8 +204,6 @@ RegleVoisinage* Database::getRegleVoisinage(const QString& name) const {
query.bindValue(":id", name);
query.exec();
regle->setNbVoisins(query.value(0).toUInt());
return regle;
}
}
......
......@@ -2,7 +2,7 @@
#include <Automate.h>
#include <parametragemodele.h>
ParamAlpha::ParamAlpha(const int nbEtats): QWidget(), nb(nbEtats) {
ParamAlpha::ParamAlpha(const int nbEtats, const QWidget *parent): QWidget(), nb(nbEtats) {
this->setWindowTitle("Configuration des états");
this->setMinimumSize(900, 700);
......@@ -28,6 +28,10 @@ ParamAlpha::ParamAlpha(const int nbEtats): QWidget(), nb(nbEtats) {
form[i]->addRow("Vert:", green[i]);
form[i]->addRow("Bleu:", blue[i]);
}
<<<<<<< HEAD
=======
connect(valider, SIGNAL(clicked()), parent, SLOT(changerRegle()));
>>>>>>> 79d70f004b9e06f9113a2a1d2873a97e332be23d
connect(valider, SIGNAL(clicked()), this, SLOT(valide()));
......
......@@ -77,12 +77,16 @@ NouveauModele::NouveauModele(QWidget* parent) : QWidget() {
layoutEtat->addWidget(etat);
layoutEtat->addWidget(nb_etats);
<<<<<<< HEAD
valider_Etat = new QPushButton("Valider le nombre d'états");
=======
connect(boutonEtat, SIGNAL(clicked()), this, SLOT(parametrerEtats()));
>>>>>>> 79d70f004b9e06f9113a2a1d2873a97e332be23d
connect(bouton_valide, SIGNAL(clicked()), this, SLOT(validerParametrage()));
connect(valider_Etat, SIGNAL(clicked()), this, SLOT(changerEtatDefault()));
......@@ -127,7 +131,7 @@ NouveauModele::NouveauModele(QWidget* parent) : QWidget() {
}
void NouveauModele::parametrerEtats() {
paramAlpha.reset(new ParamAlpha(nb_etats->value()));
paramAlpha.reset(new ParamAlpha(nb_etats->value(), this));
paramAlpha->show();
}
......@@ -482,7 +486,7 @@ void NouveauModele::validerParametrage(){
void NouveauModele::changerRegle(){
if (liste_regle_transition != nullptr) delete liste_regle_transition;
if (liste_regle_transition != nullptr) form_choix->removeRow(6);
liste_regle_transition = new QComboBox;
liste_regle_transition->setPlaceholderText("--- select ---");
......@@ -497,7 +501,7 @@ void NouveauModele::changerRegle(){
liste_regle_transition->setCurrentIndex(-1);
form_choix->addRow("Règle de transition : ", liste_regle_transition);
form_choix->insertRow(6, "Règle de transition : ", liste_regle_transition);
connect(liste_regle_transition, SIGNAL(currentTextChanged(const QString&)), this, SLOT(changerVoisinage(const QString&)));
connect(liste_regle_transition, SIGNAL(currentTextChanged(const QString&)), this, SLOT(paramRegle(const QString)));
......
......@@ -135,7 +135,7 @@ Reseau& Reseau::operator=(const Reseau& init_grille) {
bool Reseau::operator==(const Reseau&r){
if (static_cast<int>(hauteur) != r.getHauteur() || static_cast<int>(largeur) != r.getLargeur()) return false;
for(unsigned int i=0; hauteur; i++)
for(unsigned int i=0; i<hauteur; i++)
for(unsigned int j=0; j<largeur; j++)
if (reseau[i][j].getIndEtat() != r.getReseau()[i][j].getIndEtat()) return false;
return true;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment