summaryrefslogtreecommitdiff
path: root/sem_3/Programm/jeu_de_la_vie
diff options
context:
space:
mode:
authorGaspard Coulet <gaspard.coulet@mines-ales.org>2021-04-28 23:05:53 +0200
committerGaspard Coulet <gaspard.coulet@mines-ales.org>2021-04-28 23:05:53 +0200
commit9fe033ea88c2f705ec18c232873d056e0c229d72 (patch)
tree0647dc8c51610c7336c88c04de2068ea14b21e17 /sem_3/Programm/jeu_de_la_vie
Initial commit
Diffstat (limited to 'sem_3/Programm/jeu_de_la_vie')
-rw-r--r--sem_3/Programm/jeu_de_la_vie/JDV0-bis-main.cpp14
-rw-r--r--sem_3/Programm/jeu_de_la_vie/JDV0-bis.cpp149
-rw-r--r--sem_3/Programm/jeu_de_la_vie/JDV0-bis.h38
-rw-r--r--sem_3/Programm/jeu_de_la_vie/arch/population.cpp145
-rw-r--r--sem_3/Programm/jeu_de_la_vie/arch/population.h53
-rw-r--r--sem_3/Programm/jeu_de_la_vie/arch/population_vivante.cpp42
-rw-r--r--sem_3/Programm/jeu_de_la_vie/arch/population_vivante.h18
-rw-r--r--sem_3/Programm/jeu_de_la_vie/cellule.cpp95
-rw-r--r--sem_3/Programm/jeu_de_la_vie/cellule.h55
-rw-r--r--sem_3/Programm/jeu_de_la_vie/option.cpp45
-rw-r--r--sem_3/Programm/jeu_de_la_vie/option.h47
-rw-r--r--sem_3/Programm/jeu_de_la_vie/population-vivante-v2.cpp184
-rw-r--r--sem_3/Programm/jeu_de_la_vie/population-vivante-v2.h60
-rw-r--r--sem_3/Programm/jeu_de_la_vie/tabOptions.cpp58
-rw-r--r--sem_3/Programm/jeu_de_la_vie/tabOptions.h22
15 files changed, 1025 insertions, 0 deletions
diff --git a/sem_3/Programm/jeu_de_la_vie/JDV0-bis-main.cpp b/sem_3/Programm/jeu_de_la_vie/JDV0-bis-main.cpp
new file mode 100644
index 0000000..e1ae237
--- /dev/null
+++ b/sem_3/Programm/jeu_de_la_vie/JDV0-bis-main.cpp
@@ -0,0 +1,14 @@
+#include <iostream>
+using namespace std;
+
+#include "JDV0-bis.h"
+
+int main(int argc, char** argv){
+
+ JeuDeLaVie JDV;
+ JDV.parseOptions(argc,argv);
+ JDV.run(4);
+
+ return 0;
+}
+
diff --git a/sem_3/Programm/jeu_de_la_vie/JDV0-bis.cpp b/sem_3/Programm/jeu_de_la_vie/JDV0-bis.cpp
new file mode 100644
index 0000000..587c05a
--- /dev/null
+++ b/sem_3/Programm/jeu_de_la_vie/JDV0-bis.cpp
@@ -0,0 +1,149 @@
+#include "JDV0-bis.h"
+#include <cstdlib>
+#include <iostream>
+#include <fstream>
+#include <exception>
+using namespace std;
+
+
+void JeuDeLaVie::nettoie(std::string &s){
+ size_t pos=s.find_first_of("#");
+ s=s.substr(0,pos);
+ int beg=0,end=s.size()-1;
+ while(beg<end+1 && (s[beg]==' ' || s[beg]=='\t' )) beg++;
+ while(end>beg-1 && (s[end]==' ' || s[end]=='\t' )) end--;
+ s=s.substr(beg,end-beg+1);
+}
+
+
+bool JeuDeLaVie::findCleVal(std::string &s, std::string &s1,std::string &s2){
+ nettoie(s);
+ if (s==string("")) return false;
+ size_t pos=s.find_first_of(":");
+ if (pos==string::npos) {
+ cerr << "Le fichier est mal formé" << endl;
+ terminate();
+ }
+ s1=s.substr(0,pos);
+ s2=s.substr(pos+1);
+ nettoie(s1);
+ nettoie(s2);
+ //cerr<<"Found cle/val -> "<< s1<< " and "<<s2<<endl;
+ return true;
+}
+
+void JeuDeLaVie::TraiteOption(const string &cle, const string &valeur, size_t num_ligne){
+ if (cle == "Dimension") {
+ POP.setDimension(atoi(valeur.c_str()));
+ POP.reset();
+ }
+ if (cle == "Probability") {
+ POP.setProbability(atof(valeur.c_str()));
+ POP.reset();
+ }
+ if (cle == "Cell") {
+ size_t x, y;
+ size_t pos = valeur.find_first_of("x, ");
+ if (pos == string::npos || valeur[pos] == '\0') {
+ cerr << "Le fichier est mal formé. Vérifiez la syntaxe de la ligne "<< num_ligne << endl;
+ }
+ else {
+ x = atoi(valeur.substr(0, pos).c_str());
+ y = atoi(valeur.substr(pos).c_str());
+ POP.birth(x,y);
+ }
+ }
+}
+
+
+void JeuDeLaVie::loadConfig(std::string file){
+ ifstream input(file.c_str());
+ string cle, valeur;
+ size_t num_ligne=0;
+
+ if (!input.is_open()) {
+ cerr << "Le fichier " << file << " n'a pas pu être ouvert." << endl;
+ terminate();
+ }
+ string line;
+ while (!input.eof()) {
+ getline(input,line);
+ //cout<<"reading line ("<<num_ligne<<") -> "<<line<<endl;
+ if (!input.eof()) {
+ if (findCleVal(line,cle,valeur))
+ TraiteOption(cle,valeur,num_ligne);
+ }
+ num_ligne++;
+ }
+ input.close();
+}
+
+void JeuDeLaVie::run(size_t n) {
+ POP.print();
+ for(size_t i=0;i<n;i++){
+ POP=POP.next();
+ POP.print();
+ }
+}
+
+
+JeuDeLaVie::JeuDeLaVie() : POP(8,0.25) {
+
+ opts.addOption(Option(HELP_ID, "--help", "-h",
+ "Affiche l'aide du programme", Option::AUCUN));
+ opts.addOption(Option(VERSION_ID, "--version", "-v",
+ "Affiche la version du programme", Option::AUCUN));
+ opts.addOption(Option(DIMENSION_ID, "--dimension", "-N",
+ "Initialise une matrice carrée de la dimension spécifiée",
+ Option::ENTIER));
+ opts.addOption(Option(PROBABILITY_ID, "--probability", "-p",
+ "Probabilité d'une cellule d'être en vie au démarrage",
+ Option::REEL));
+ opts.addOption(Option(CONFIG_ID, "--config", "-f",
+ "Charge la configuration initiale du jeu "
+ "à partir du fichier passé en paramètre",
+ Option::CHAINE));
+}
+
+
+void JeuDeLaVie::parseOptions(int argc, char** argv){
+ bool opt_error = false;
+ int i = 1;
+ while (!opt_error && i < argc) {
+ int x = opts.getOptionId(argv[i]);
+ switch (x) {
+ case HELP_ID:
+ cout << "usage " << argv[0] << " [Options]" << endl;
+ opts.print(); return;
+ case VERSION_ID:
+ cout << "Programme " << argv[0] << " version 0.0.0" << endl;
+ return;
+ case DIMENSION_ID:
+ POP.setDimension(atoi(argv[++i]));
+ break;
+ case PROBABILITY_ID:
+ POP.setProbability(atof(argv[++i]));
+ break;
+ case CONFIG_ID:
+ loadConfig(argv[++i]);
+ break;
+ default:
+ if (opts.optionHasArgument(argv[i])) {
+ cout << "L'option " << argv[i] << " a été trouvée.";
+ cout << " Elle attend un argument de type "
+ << Type2String(opts.optionArgumentType(argv[i]));
+ cout << " => " << (++i < argc ? argv[i] : "Erreur");
+ } else {
+ cout << "Cette option n'a pas été reconnue.";
+ opt_error = true;
+ }
+ cout << endl;
+ }
+ i++;
+ }
+ if (opt_error) {
+ cout << "Usage : " << argv[0] << " [Options]" << endl;
+ opts.print();
+ terminate();
+ }
+}
diff --git a/sem_3/Programm/jeu_de_la_vie/JDV0-bis.h b/sem_3/Programm/jeu_de_la_vie/JDV0-bis.h
new file mode 100644
index 0000000..763111d
--- /dev/null
+++ b/sem_3/Programm/jeu_de_la_vie/JDV0-bis.h
@@ -0,0 +1,38 @@
+#ifndef __JDV_H
+#define __JDV_H
+
+#include "population-vivante-v2.h"
+#include "tabOptions.h"
+
+#define HELP_ID 1
+#define VERSION_ID 2
+#define DIMENSION_ID 10
+#define PROBABILITY_ID 11
+#define CONFIG_ID 20
+
+
+class JeuDeLaVie {
+ private:
+ PopulationVivante POP;
+ TabOptions opts;
+
+ void nettoie(std::string &s);
+ bool findCleVal(std::string &s, std::string &s1,std::string &s2);
+ void TraiteOption(const std::string &cle, const std::string &valeur, size_t num_ligne);
+
+ public:
+
+ JeuDeLaVie();
+
+ void loadConfig(std::string file);
+ void run(size_t);
+ void parseOptions(int argc, char** argv);
+
+};
+
+
+
+
+
+
+#endif
diff --git a/sem_3/Programm/jeu_de_la_vie/arch/population.cpp b/sem_3/Programm/jeu_de_la_vie/arch/population.cpp
new file mode 100644
index 0000000..5655e2f
--- /dev/null
+++ b/sem_3/Programm/jeu_de_la_vie/arch/population.cpp
@@ -0,0 +1,145 @@
+#include <iostream>
+#include <cstdlib>
+#include <exception>
+#include "population.h"
+using namespace std;
+
+#define CHECK_BOUND(i,j) \
+ if (i>=N || j>=N){ \
+ std::cout<<"Accessing a Cell at ("<<i<<","<<j<<") out of range..." \
+ << " Aborting"<<std::endl; \
+ std::terminate(); \
+ }
+
+
+size_t Population::nb_voisins_vivants(size_t ci, size_t cj) const {
+ size_t cpt=0;
+ size_t imin,imax,jmin,jmax;
+ imin = ci==0?ci:ci-1;
+ imax = ci==(N-1)?ci:ci+1;
+ jmin = cj==0?cj:cj-1;
+ jmax = cj==(N-1)?cj:cj+1;
+
+ for (size_t i = imin ; i <= imax ; i++) {
+ for (size_t j = jmin ; j <= jmax ; j++) {
+ if (T[i][j].getVivante()) {
+ cpt++;
+ }
+ }
+ }
+ return cpt - (T[ci][cj].getVivante() ? 1 : 0);
+}
+
+void Population::updateColors() {
+ //calcule les cellules vivantes qui vont mourir
+ for (size_t i = 0 ; i < N ; i++) {
+ for (size_t j = 0 ; j < N ; j++) {
+ size_t voisin=nb_voisins_vivants(i, j);
+ if (voisin !=3 && voisin!=2 && T[i][j].getVivante())
+ T[i][j].doitMourir();
+ }
+ }
+}
+
+
+
+Population::Population() {
+ for (size_t i = 0 ; i < N ; i++) {
+ for (size_t j = 0 ; j < N ; j++) {
+ T[i][j].setX(i);
+ T[i][j].setY(j);
+ T[i][j].setVivante(false);
+ }
+ }
+}
+
+void Population::init(size_t n) {
+ srand(time(NULL));
+ if (nb_vivants()==0){
+ size_t i,j;
+ for (size_t k = 0 ; k < n ; k++) {
+ do {
+ i=rand()% N;
+ j=rand()% N;
+ } while ((T[i][j]).getVivante());
+ T[i][j].setVivante(true);
+ }
+ updateColors();
+ }
+}
+
+
+size_t Population::nb_cellules(Cellule::Couleur c) const {
+ size_t cpt=0;
+ for (size_t i = 0 ; i < N ; i++) {
+ for (size_t j = 0 ; j < N ; j++) {
+ if (CelluleEstDeLaCouleur(T[i][j],c)) {
+ cpt++;
+ }
+ }
+ }
+ return cpt;
+}
+
+size_t Population::nb_vivants() const { return N*N-nb_morts();}
+size_t Population::nb_deces() const { return nb_cellules(Cellule::ROUGE)+nb_cellules(Cellule::JAUNE);}
+size_t Population::nb_morts() const { return nb_cellules(Cellule::NOIR);}
+size_t Population::nb_naissances() const { return nb_cellules(Cellule::BLEU);}
+
+
+Cellule Population::getCelluleCopie(size_t i, size_t j) const {
+ CHECK_BOUND(i,j);
+ return T[i][j];
+}
+
+const Cellule& Population::getCellule(size_t i, size_t j) const{
+ CHECK_BOUND(i,j);
+ return T[i][j];
+}
+
+void Population::printCell(size_t i, size_t j) const {
+ CHECK_BOUND(i,j);
+ T[i][j].print();
+}
+
+void Population::kill(size_t i, size_t j) {
+ CHECK_BOUND(i,j);
+ T[i][j].setVivante(false);
+}
+
+void Population::birth(size_t i, size_t j) {
+ CHECK_BOUND(i,j);
+ T[i][j].setVivante(true);
+}
+
+void Population::print() const {
+ for (size_t i = 0 ; i < N + 2 ; i++) {
+ cout<<"X";
+ }
+ cout<<endl;
+ for (size_t i = 0 ; i < N ; i++) {
+ cout<<"X";
+ for (size_t j = 0 ; j < N ; j++) {
+ //T[i][j].print();
+ cout<<Couleur2String(T[i][j].getCouleur());
+ }
+ cout<<"X"<<endl;
+ }
+ for (size_t i = 0 ; i < N + 2 ; i++) {
+ cout<<"X";
+ }
+ cout<<endl;
+}
+
+Population Population::next() const {
+ Population POP(*this);
+ for (size_t i = 0 ; i < N ; i++) {
+ for (size_t j = 0 ; j < N ; j++) {
+ size_t voisin=nb_voisins_vivants(i,j);
+ (POP.T[i][j]).setVivante(voisin ==3 || (voisin==2 && T[i][j].getVivante()));
+ }
+ }
+ POP.updateColors();
+ return POP;
+}
+
diff --git a/sem_3/Programm/jeu_de_la_vie/arch/population.h b/sem_3/Programm/jeu_de_la_vie/arch/population.h
new file mode 100644
index 0000000..9f5ad98
--- /dev/null
+++ b/sem_3/Programm/jeu_de_la_vie/arch/population.h
@@ -0,0 +1,53 @@
+#ifndef __POPULATION_H
+#define __POPULATION_H
+#include "cellule.h"
+
+#define N 5
+
+class Population {
+
+ private:
+ Cellule T[N][N];
+
+ // retourne le nbr de voisins vivants de la cellule à (i,j)
+ size_t nb_voisins_vivants(size_t, size_t) const;
+
+ //retourne le nbr de cellule d'une couleur donnée
+ size_t nb_cellules(Cellule::Couleur) const;
+
+ // Mise à jour des couleurs des cellules mourantes
+ void updateColors();
+
+ public:
+
+ // constructeur d'une population vide (sur une grille NxN)
+ Population();
+
+ // création de n cellules vivantes aléatoires (uniquement si population vide)
+ void init(size_t);
+
+ // accesseurs en interrogation
+ size_t nb_vivants() const;
+ size_t nb_deces() const;
+ size_t nb_morts() const;
+ size_t nb_naissances() const;
+
+ // accesseurs en lecture d'une cellule
+ Cellule getCelluleCopie(size_t i, size_t j) const;
+ const Cellule& getCellule(size_t i, size_t j) const;
+
+ // accesseurs en modification
+ void kill(size_t i, size_t j);
+ void birth(size_t i, size_t j);
+
+ // affichage d'une cellule
+ void printCell(size_t i, size_t j) const;
+ // affichage de la population
+ void print() const;
+
+ // calcul de la population suivante
+ Population next() const;
+
+};
+
+#endif
diff --git a/sem_3/Programm/jeu_de_la_vie/arch/population_vivante.cpp b/sem_3/Programm/jeu_de_la_vie/arch/population_vivante.cpp
new file mode 100644
index 0000000..93b328a
--- /dev/null
+++ b/sem_3/Programm/jeu_de_la_vie/arch/population_vivante.cpp
@@ -0,0 +1,42 @@
+#include <iostream>
+#include <cstdlib>
+#include <exception>
+#include "population_vivante.h"
+
+population_vivante::population_vivante(size_t x){
+ if ( x > N ) {
+ std::cout<<" Erreur, taille de population trop grande"<<std::endl;
+ }
+ nmax = x;
+ vivantes=0;
+}
+
+void population_vivante::birth(unsigned int x, unsigned int y) {
+ if (vivantes < nmax){
+ Cellule tmp(true, x,y);
+ pop[vivantes]= tmp;
+ vivantes++;
+}
+else{
+ std::cout<<"Erreur, toutes les cellules sont deja vivantes!"
+}
+}
+void population_vivante::death(unsigned int x, unsigned int y){
+ for (int i =0; i < vivantes; i ++){
+ if ((pop[i].getX == x) && (pop[i].getY==y)) {
+ pop[i].setVivante(false);
+ for ( int j = i; j < vivantes-1; j ++ ){
+ pop[j]= pop[j+1];
+ }
+ i = vivantes;
+ vivantes--;
+ }
+ }
+}
+const Cellule& copiecell(unsigned int x, unsigned int y){
+ for(int i=0; i< vivantes; i ++){
+ if ((pop[i].getX == x) && (pop[i].getY==y)) {
+ return pop[i];
+ }
+ }
+ }
diff --git a/sem_3/Programm/jeu_de_la_vie/arch/population_vivante.h b/sem_3/Programm/jeu_de_la_vie/arch/population_vivante.h
new file mode 100644
index 0000000..5b960b6
--- /dev/null
+++ b/sem_3/Programm/jeu_de_la_vie/arch/population_vivante.h
@@ -0,0 +1,18 @@
+#ifndef __POPULATION_VIVANTE_H
+#define __POPULATION_VIVANTE_H
+
+#include "cellule.h"
+
+#define N 5
+class population_vivante {
+private:
+ size_t nmax;
+ cellule pop[N*N];
+ size_t vivantes;
+public:
+ population_vivante(size_t);
+ void death(unsigned int x, unsigned int y);
+ void birth(unsigned int x, unsigned int y);
+ cellule& copiecell(unsigned int x, unsigned int y);
+};
+#endif
diff --git a/sem_3/Programm/jeu_de_la_vie/cellule.cpp b/sem_3/Programm/jeu_de_la_vie/cellule.cpp
new file mode 100644
index 0000000..7611e7a
--- /dev/null
+++ b/sem_3/Programm/jeu_de_la_vie/cellule.cpp
@@ -0,0 +1,95 @@
+#include "cellule.h"
+#include <iostream>
+#include <string>
+using namespace std;
+
+Cellule::Cellule(): age(0), x(0), y(0), couleur(NOIR) {
+}
+
+Cellule::Cellule(bool etat, unsigned int x, unsigned int y):
+ age(etat ? 1 : 0), x(x), y(y), couleur(etat ? BLEU : NOIR) {
+}
+
+bool Cellule::getVivante() const {
+ return age;
+}
+
+unsigned int Cellule::getX() const {
+ return x;
+}
+
+unsigned int Cellule::getY() const {
+ return y;
+}
+
+Cellule::Couleur Cellule::getCouleur() const {
+ return couleur;
+}
+
+// Accesseurs en écriture
+void Cellule::setX(unsigned int x) {
+ this->x = x;
+}
+
+void Cellule::setY(unsigned int y) {
+ this->y = y;
+}
+
+bool Cellule::estVoisine(const Cellule &c) const {
+ return age &&
+ ((x - c.x) * (x - c.x) + (y - c.y) * (y - c.y) <= 2);
+}
+
+void Cellule::print() const {
+ std::cout<<"("<<x<<","<<y<<") - > "<<Couleur2String(couleur)<<std::endl;
+}
+
+void Cellule::setVivante(bool etat) {
+ if (etat) {
+ couleur = age++ ? VERT : BLEU;
+ } else {
+ age = 0;
+ couleur = NOIR;
+ }
+}
+
+void Cellule::doitMourir() {
+ if (age) { // La cellule est vivante et va mourir
+ couleur = (couleur == BLEU ? JAUNE : ROUGE);
+ }
+}
+
+bool CelluleEstDeLaCouleur(const Cellule &cellule, Cellule::Couleur couleur) {
+ return (cellule.getCouleur() == couleur);
+}
+
+string Couleur2String(Cellule::Couleur c) {
+ string res;
+ switch (c) {
+ case Cellule::NOIR:
+ res = "\033[1;30mX\033[0m"; //"noire";
+ break;
+ case Cellule::BLEU:
+ res = "\033[1;34mX\033[0m";//"bleue";
+ break;
+ case Cellule::VERT:
+ res = "\033[1;32mX\033[0m";//"verte";
+ break;
+ case Cellule::ROUGE:
+ res = "\033[1;31mX\033[0m";//"rouge";
+ break;
+ case Cellule::JAUNE:
+ res = "\033[1;33mX\033[0m";//"jaune";
+ break;
+ default:
+ res = "non définie.";
+ cerr << "Erreur:" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__
+ << ":Couleur non définie. Les couleurs possibles sont:" << endl;
+ for (Cellule::Couleur i = Cellule::NOIR;
+ i != Cellule::NB_COULEURS;
+ i = (Cellule::Couleur) (((int) i)+1)) {
+ cerr << "- " << Couleur2String(i) << endl;
+ }
+ }
+ return res;
+}
diff --git a/sem_3/Programm/jeu_de_la_vie/cellule.h b/sem_3/Programm/jeu_de_la_vie/cellule.h
new file mode 100644
index 0000000..5ad6ef5
--- /dev/null
+++ b/sem_3/Programm/jeu_de_la_vie/cellule.h
@@ -0,0 +1,55 @@
+#ifndef __CELLULE_H
+#define __CELLULE_H
+
+#include <string>
+
+class Cellule {
+ public:
+
+ enum Couleur {
+ NOIR,
+ BLEU,
+ VERT,
+ ROUGE,
+ JAUNE,
+ NB_COULEURS
+ };
+
+ private:
+ size_t age;
+ unsigned int x, y;
+ Couleur couleur;
+
+ public:
+
+ // Constructeurs
+ Cellule(); // morte par défaut
+ Cellule(bool etat, unsigned int x, unsigned int y);
+
+ // Accesseurs en lecture
+ bool getVivante() const;
+ unsigned int getX() const;
+ unsigned int getY() const;
+ Couleur getCouleur() const;
+
+ // Accesseurs en écriture
+ void setX(unsigned int x);
+ void setY(unsigned int y);
+ void setVivante(bool etat);
+
+ // renvoie vrai si la cellule courante est vivante et est voisine de c
+ bool estVoisine(const Cellule &c) const;
+ // affiche la cellule
+ void print() const;
+
+ // spécifie qu'une cellule doit mourir au prochain tour du jeu (-> changement de couleur)
+ void doitMourir();
+};
+
+// Renvoie vrai si la cellule est de la couleur passée en paramètre, faux sinon.
+bool CelluleEstDeLaCouleur(const Cellule &cellule, Cellule::Couleur couleur);
+
+// Retourne la chaîne correspondant à la couleur passée en paramètre
+std::string Couleur2String(Cellule::Couleur c);
+
+#endif
diff --git a/sem_3/Programm/jeu_de_la_vie/option.cpp b/sem_3/Programm/jeu_de_la_vie/option.cpp
new file mode 100644
index 0000000..65d2241
--- /dev/null
+++ b/sem_3/Programm/jeu_de_la_vie/option.cpp
@@ -0,0 +1,45 @@
+#include <iostream>
+#include "option.h"
+#include <string>
+
+using namespace std;
+
+///////////////////
+// Classe Option //
+///////////////////
+
+Option::Option(): id(-1), nom(), raccourci(), description(), type(AUCUN) {}
+
+Option::Option(int _id, const string &_nom, const string &_raccourci,
+ const string &_desc, Option::Type _type):
+ id(_id), nom(_nom), raccourci(_raccourci), description(_desc), type(_type) {}
+
+int Option::getId() const { return id; }
+string Option::getName() const { return nom; }
+string Option::getShortcut() const { return raccourci; }
+string Option::getDescription() const { return description; }
+Option::Type Option::getType() const { return type; }
+
+void Option::setId(int _id) { this->id = _id; }
+void Option::setName(const string &name) { nom = name; }
+void Option::setShortcut(const string &shortcut) { raccourci = shortcut; }
+void Option::setDescription(const string &desc) { description = desc; }
+void Option::setType(Option::Type t) { type = t; }
+
+void Option::print() const {
+ cout << nom << " (" << raccourci << ") " << Type2String(type)
+ << "\t" << description << endl;
+}
+
+string Type2String(Option::Type t) {
+ string tmp;
+ switch (t) {
+ case Option::AUCUN: tmp = ""; break;
+ case Option::BOOLEEN: tmp = "<booléen>"; break;
+ case Option::ENTIER: tmp = "<entier>"; break;
+ case Option::REEL: tmp = "<réel>"; break;
+ case Option::CHAR: tmp = "<caractère>"; break;
+ case Option::CHAINE: tmp = "<chaîne>"; break;
+ }
+ return tmp;
+}
diff --git a/sem_3/Programm/jeu_de_la_vie/option.h b/sem_3/Programm/jeu_de_la_vie/option.h
new file mode 100644
index 0000000..e420c4a
--- /dev/null
+++ b/sem_3/Programm/jeu_de_la_vie/option.h
@@ -0,0 +1,47 @@
+#ifndef __OPTION_H
+#define __OPTION_H
+
+#include <string>
+
+class Option {
+ public:
+ enum Type {
+ AUCUN,
+ BOOLEEN,
+ ENTIER,
+ REEL,
+ CHAR,
+ CHAINE
+ };
+
+ private:
+ int id;
+ std::string nom, raccourci, description;
+ Type type;
+
+ public:
+ Option();
+ Option(int id, const std::string &nom, const std::string &raccourci,
+ const std::string &desc, Type type);
+
+ // Accesseurs en lecture
+ int getId() const;
+ std::string getName() const;
+ std::string getShortcut() const;
+ std::string getDescription() const;
+ Type getType() const;
+
+ // Accesseurs en écriture
+ void setId(int id);
+ void setName(const std::string &name);
+ void setShortcut(const std::string &shortcut);
+ void setDescription(const std::string &desc);
+ void setType(Type t);
+
+ // Affichage
+ void print() const;
+};
+
+std::string Type2String(Option::Type t);
+
+#endif
diff --git a/sem_3/Programm/jeu_de_la_vie/population-vivante-v2.cpp b/sem_3/Programm/jeu_de_la_vie/population-vivante-v2.cpp
new file mode 100644
index 0000000..f59cb97
--- /dev/null
+++ b/sem_3/Programm/jeu_de_la_vie/population-vivante-v2.cpp
@@ -0,0 +1,184 @@
+#include <iostream>
+#include <cstdlib>
+#include <exception>
+#include "population-vivante-v2.h"
+using namespace std;
+
+#define CHECK_BOUND(i,j) \
+ if (i>=N || j>=N){ \
+ std::cout<<"Accessing a Cell at ("<<i<<","<<j<<") out of range ... aborting"<<std::endl; \
+ std::terminate(); \
+ } \
+
+const Cellule* PopulationVivante::at(size_t i, size_t j) const {
+ for (size_t k = 0 ; k < alive ; k++) {
+ if ((T[k].getX() == i) && (T[k].getY() == j)) {
+ return T+k;
+ }
+ }
+ return NULL;
+}
+
+Cellule* PopulationVivante::at(size_t i, size_t j) {
+ for (size_t k = 0 ; k < alive ; k++) {
+ if ((T[k].getX() == i) && (T[k].getY() == j)) {
+ return T+k;
+ }
+ }
+ return NULL;
+}
+
+size_t PopulationVivante::nb_voisins_vivants(size_t ci, size_t cj) const {
+ size_t cpt=0;
+ size_t imin,imax,jmin,jmax;
+ imin = ci==0?ci:ci-1;
+ imax = ci==(N-1)?ci:ci+1;
+ jmin = cj==0?cj:cj-1;
+ jmax = cj==(N-1)?cj:cj+1;
+
+ for (size_t i = imin ; i <= imax ; i++) {
+ for (size_t j = jmin ; j <= jmax ; j++) {
+ if (at(i,j) != NULL) {
+ cpt++;
+ }
+ }
+ }
+ return cpt - (at(ci,cj) != NULL ? 1 : 0);
+}
+
+void PopulationVivante::updateColors() {
+ //calcule les cellules vivantes qui vont mourir
+ for (size_t i = 0; i < alive; i++) {
+ size_t voisin=nb_voisins_vivants(T[i].getX(), T[i].getY());
+ if ((voisin != 2) && (voisin != 3)) T[i].doitMourir();
+ }
+}
+
+PopulationVivante::PopulationVivante(size_t n, float prob) : alive(0), N(n), probability(prob) {
+ reset();
+}
+
+
+size_t PopulationVivante::nb_cellules(Cellule::Couleur c) const {
+ size_t cpt=0;
+ for (size_t i = 0 ; i < alive ; i++) {
+ if (CelluleEstDeLaCouleur(T[i],c)) {
+ cpt++;
+ }
+ }
+ return cpt;
+}
+
+size_t PopulationVivante::nb_vivants() const { return N*N-nb_morts();}
+size_t PopulationVivante::nb_deces() const { return nb_cellules(Cellule::ROUGE)+nb_cellules(Cellule::JAUNE);}
+size_t PopulationVivante::nb_morts() const { return nb_cellules(Cellule::NOIR);}
+size_t PopulationVivante::nb_naissances() const { return nb_cellules(Cellule::BLEU);}
+
+
+
+Cellule PopulationVivante::getCelluleCopie(size_t i, size_t j) const {
+ CHECK_BOUND(i,j);
+ const Cellule* ptr=at(i,j);
+ if (ptr==NULL) {
+ return Cellule(false,i,j);
+ } else {
+ return *ptr;
+ }
+}
+
+
+
+void PopulationVivante::printCell(size_t i, size_t j) const {
+ CHECK_BOUND(i,j);
+ getCelluleCopie(i,j).print();
+}
+
+void PopulationVivante::kill(size_t i, size_t j) {
+ CHECK_BOUND(i,j);
+ const Cellule* ptr=at(i,j);
+ if (ptr!=NULL) {
+ size_t k=ptr-T; // retrouve la position dans le tableau
+ for ( ; k < alive - 1 ; k++) {
+ T[k]=T[k+1];
+ }
+ alive--;
+ }
+}
+
+void PopulationVivante::birth(size_t i, size_t j) {
+ if (alive+1<NMAX){
+ CHECK_BOUND(i,j);
+ Cellule* ptr=at(i,j);
+ if (ptr==NULL) {
+ T[alive]=Cellule(true,i,j);
+ alive++;
+ }
+ else{
+ ptr->setVivante(true);
+ }
+ }
+ else {
+ std::cerr<<"PopulationVivante: Erreur -> trop de cellule vivante pour NMAX="<<NMAX<<std::endl;
+ std::cerr<<"aborting...\n";
+ std::terminate();
+ }
+}
+
+void PopulationVivante::print() const {
+ for (size_t i = 0; i < N + 2 ; i++) {
+ cout << "X";
+ }
+ cout<<endl;
+ for (size_t i = 0 ; i < N ; i++) {
+ cout<<"X";
+ for (size_t j = 0 ; j < N ; j++) {
+ cout<<Couleur2String(getCelluleCopie(i,j).getCouleur());
+ }
+ cout<<"X"<<endl;
+ }
+ for (size_t i = 0 ; i < N + 2 ; i++) {
+ cout<<"X";
+ }
+ cout<<endl;
+}
+
+PopulationVivante PopulationVivante::next() const {
+ PopulationVivante POP(*this);
+ for (size_t i = 0 ; i < N ; i++) {
+ for (size_t j = 0 ; j < N ; j++) {
+ size_t voisin=nb_voisins_vivants(i,j);
+ if ((voisin == 3) || ((voisin == 2) && (at(i,j) != NULL))) {
+ POP.birth(i,j);
+ } else {
+ POP.kill(i,j);
+ }
+ }
+ }
+ POP.updateColors();
+ return POP;
+}
+
+
+/// NEW STUFF TD4
+
+size_t PopulationVivante::getDimension() const {return N;}
+
+float PopulationVivante::getProbability() const {return probability;}
+
+void PopulationVivante::setDimension(size_t n) {N=n; reset();}
+
+void PopulationVivante::setProbability(float p) {probability=p; reset();}
+
+
+void PopulationVivante::reset() {
+ alive=0;
+ srand(time(NULL));
+ for (size_t i = 0 ; i < N ; i++) {
+ for (size_t j = 0 ; j < N ; j++) {
+ if (((rand() % 10000) / 10000.) <= probability) {
+ birth(i,j);
+ }
+ }
+ }
+ updateColors();
+}
diff --git a/sem_3/Programm/jeu_de_la_vie/population-vivante-v2.h b/sem_3/Programm/jeu_de_la_vie/population-vivante-v2.h
new file mode 100644
index 0000000..2ba155c
--- /dev/null
+++ b/sem_3/Programm/jeu_de_la_vie/population-vivante-v2.h
@@ -0,0 +1,60 @@
+#ifndef __POPULATION_VIVANTE_H
+#define __POPULATION_VIVANTE_H
+#include "cellule.h"
+
+#define NMAX 10000
+
+class PopulationVivante {
+ private:
+ Cellule T[NMAX];
+ size_t alive;
+ size_t N;
+ float probability;
+
+ // retourne le nbr de voisins vivants de la cellule à (i,j)
+ size_t nb_voisins_vivants(size_t, size_t) const;
+
+ // access to cell at (i,j) if not alive get NULL
+ const Cellule* at(size_t i, size_t j)const;
+ Cellule* at(size_t i, size_t j);
+ // Mise à jour des couleurs des cellules mourantes
+ void updateColors();
+
+ size_t nb_cellules(Cellule::Couleur c) const;
+
+ public:
+
+ // construction d'une n-population avec une probabilité fixée.
+ PopulationVivante(size_t n, float prob);
+
+ // accesseurs en interrogation
+ size_t nb_vivants() const;
+ size_t nb_deces() const;
+ size_t nb_morts() const;
+ size_t nb_naissances() const;
+ size_t getDimension() const;
+ float getProbability() const;
+
+
+ // accesseurs en lecture d'une cellule
+ Cellule getCelluleCopie(size_t i, size_t j) const;
+
+ // accesseurs en modification
+ void kill(size_t i, size_t j);
+ void birth(size_t i, size_t j);
+ void setDimension(size_t n);
+ void setProbability(float p);
+
+ // affichage d'une cellule
+ void printCell(size_t i, size_t j) const;
+ // affichage de la population
+ void print() const;
+
+ // Re-création de la population
+ void reset();
+
+ // calcul de la population suivante
+ PopulationVivante next() const;
+};
+
+#endif
diff --git a/sem_3/Programm/jeu_de_la_vie/tabOptions.cpp b/sem_3/Programm/jeu_de_la_vie/tabOptions.cpp
new file mode 100644
index 0000000..0e78679
--- /dev/null
+++ b/sem_3/Programm/jeu_de_la_vie/tabOptions.cpp
@@ -0,0 +1,58 @@
+#include <iostream>
+#include <exception>
+#include "tabOptions.h"
+
+using namespace std;
+
+TabOptions::TabOptions(): opts(), nb_opts(0) {}
+
+void TabOptions::addOption(const Option &o) {
+ if (nb_opts == NMAX_OPTS) {
+ cerr << "Erreur: Impossible d'ajouter une nouvelle option." << endl
+ << " Nombre maximum d'option atteint"<< " (" << NMAX_OPTS << ")."
+ << endl;
+ terminate();
+ }
+
+ bool found = (getOptionIndex(o.getName()) != -1) || (getOptionIndex(o.getShortcut()) != -1);
+
+ if (found) {
+ cerr << "Avertissement: L'identifiant " << o.getId() << " est déjà utilisé."
+ << endl;
+ } else {
+ opts[nb_opts] = o;
+ nb_opts++;
+ }
+}
+
+void TabOptions::print() const {
+ cout << "Options :" << endl;
+ for (size_t i = 0; i < nb_opts; i++) {
+ opts[i].print();
+ }
+}
+
+int TabOptions::getOptionIndex(const string &opt) const {
+ bool found = false;
+ size_t i = 0;
+ while (!found && (i < nb_opts)) {
+ found = ((opts[i].getName() == opt) || (opts[i].getShortcut() == opt));
+ i++;
+ }
+ return found ? i - 1 : -1;
+}
+// opt doit etre une option valide
+int TabOptions::getOptionId(const std::string &opt) const {
+ int i = getOptionIndex(opt);
+ return (i>=0 ? opts[i].getId():-1);
+}
+// opt doit etre une option valide
+bool TabOptions::optionHasArgument(const std::string &opt) const {
+ size_t i = getOptionIndex(opt);
+ return (opts[i].getType() != Option::AUCUN);
+}
+// opt doit etre une option valide
+Option::Type TabOptions::optionArgumentType(const std::string &opt) const {
+ size_t i = getOptionIndex(opt);
+ return opts[i].getType();
+}
diff --git a/sem_3/Programm/jeu_de_la_vie/tabOptions.h b/sem_3/Programm/jeu_de_la_vie/tabOptions.h
new file mode 100644
index 0000000..cef8aaa
--- /dev/null
+++ b/sem_3/Programm/jeu_de_la_vie/tabOptions.h
@@ -0,0 +1,22 @@
+#ifndef __TABOPTIONS_H__
+#define __TABOPTIONS_H__
+
+#include <string>
+#include "option.h"
+
+#define NMAX_OPTS 100
+class TabOptions {
+ private:
+ Option opts[NMAX_OPTS];
+ size_t nb_opts;
+ int getOptionIndex(const std::string &opt) const;
+ public:
+ TabOptions();
+ void addOption(const Option &o);
+ void print() const;
+ int getOptionId(const std::string &opt) const;
+ bool optionHasArgument(const std::string &opt) const;
+ Option::Type optionArgumentType(const std::string &opt) const;
+};
+
+#endif