diff options
Diffstat (limited to 'sem_3/Programm/jeu_de_la_vie')
| -rw-r--r-- | sem_3/Programm/jeu_de_la_vie/JDV0-bis-main.cpp | 14 | ||||
| -rw-r--r-- | sem_3/Programm/jeu_de_la_vie/JDV0-bis.cpp | 149 | ||||
| -rw-r--r-- | sem_3/Programm/jeu_de_la_vie/JDV0-bis.h | 38 | ||||
| -rw-r--r-- | sem_3/Programm/jeu_de_la_vie/arch/population.cpp | 145 | ||||
| -rw-r--r-- | sem_3/Programm/jeu_de_la_vie/arch/population.h | 53 | ||||
| -rw-r--r-- | sem_3/Programm/jeu_de_la_vie/arch/population_vivante.cpp | 42 | ||||
| -rw-r--r-- | sem_3/Programm/jeu_de_la_vie/arch/population_vivante.h | 18 | ||||
| -rw-r--r-- | sem_3/Programm/jeu_de_la_vie/cellule.cpp | 95 | ||||
| -rw-r--r-- | sem_3/Programm/jeu_de_la_vie/cellule.h | 55 | ||||
| -rw-r--r-- | sem_3/Programm/jeu_de_la_vie/option.cpp | 45 | ||||
| -rw-r--r-- | sem_3/Programm/jeu_de_la_vie/option.h | 47 | ||||
| -rw-r--r-- | sem_3/Programm/jeu_de_la_vie/population-vivante-v2.cpp | 184 | ||||
| -rw-r--r-- | sem_3/Programm/jeu_de_la_vie/population-vivante-v2.h | 60 | ||||
| -rw-r--r-- | sem_3/Programm/jeu_de_la_vie/tabOptions.cpp | 58 | ||||
| -rw-r--r-- | sem_3/Programm/jeu_de_la_vie/tabOptions.h | 22 |
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 |
