-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjeux_de_la_vie.cpp
160 lines (138 loc) · 6.11 KB
/
jeux_de_la_vie.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
-----------------------------------------------------------------------------------
Laboratoire : 05
Fichier : jeux_de_la_vie.cpp
Auteur(s) : BOUSBAA Eric, BOTTIN Stéphane, FERRARI Teo
Date : 10.01.2019
But : Met à disposition des fonctions ayant pour but de simuler le jeux de
la vie.
Remarque(s) : - Les valeurs définissant si une cellule doit naître ou survivre sont
défini dans des listes constantes. Chaque valeur de la liste
représente une condition à laquelle la règle associé est valide.
- Afin de modifier la configuration initiale du tableau de base,
il suffit de placer un 1 dans toute cellule voulant être
initialement habitée.
- La taille du tableau initial peut être changé en ajoutant/supprimant
les lignes/colonnes dans son initialisation.
- Toutes les altération d'une génération de cellules à une autre
s'effectuent simultanément. Càd qu'il n'y a pas d'ordre de priorité
entre vivre et mourir.
Compilateur : - Apple LLVM version 9.0.0 (clang-900.0.39.2)
- MinGW-g++ 6.3.0
-----------------------------------------------------------------------------------
*/
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include "jeux_de_la_vie.h"
using namespace std;
const char CARACTERE_VIE = 'X';
const char CARACTERE_MORT = '.';
/**
* @brief Affiche le tableau représentant le jeu de la vie en utilisant des
* charactères pour représenter les états de vie et de mort des cellules
* @param tableau : tableau booleen a afficher
* @param caractereVie : caraectere representant un cellule
* @param caractereMort : caraectere representant un abscence de cellule
*/
void afficherTableau(const vector<vector<bool>>&tableau,
char caractereVie, char caractereMort);
/**
* @brief fonction qui retourne l'état futur d'une case specifique du tableau
* representant le jeu de la vie
* @param tableau : tableau booleen representant le jeu de la vie
* @param i : position verticale de la case a tester
* @param j : position horizontale de la case a tester
* @return : l'etat dans lequel devrait etre la case par rapport au cases l'entourant
*/
bool etatFutur(const vector<vector<bool>>&tableau, unsigned i, unsigned j);
/**
* @brief fonction verifiant les occurences de cellules autour d'une cellule donnee
* @param tableau : tableau booleen representant le jeu de la vie
* @param x : position horizontale de la case a tester
* @param y : position verticale de la case a tester
* @return le nombre d'occurences de cellules autour de la cellule donnee
*/
unsigned occ(const vector <vector<bool>>&tableau, unsigned x, unsigned y);
/**
* @brief verifies qu'une valeur est dans un intervalle donnée
* @param V : Liste de valeurs devant être vérifiés
* @param val : valeur à trouver dans l'intervalle
* @return si la valeur se trouve dans l'intervalle ou non
*/
bool estDansIntervalle(const vector<unsigned> &V, const unsigned val);
const unsigned NOMBRE_CASES_VOISINES = 8;
void simulation(unsigned nombreSimulations) {
vector <vector<bool>> tableauPresent = {
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
vector <vector<bool>> tableauFutur(tableauPresent.size(),
vector<bool>(tableauPresent[0].size()));
for (unsigned n = 1; n <= nombreSimulations; ++n) {
cout << "Generation : " << n << endl;
afficherTableau(tableauPresent, CARACTERE_VIE, CARACTERE_MORT);
cout << endl;
for (unsigned i = 0; i < tableauPresent.size(); ++i) {
for (unsigned j = 0; j < tableauPresent[0].size(); ++j) {
tableauFutur[i][j] = etatFutur(tableauPresent, i, j);
}
}
tableauPresent = tableauFutur;
}
}
unsigned occ(const vector < vector<bool>>&tableau, unsigned x, unsigned y) {
unsigned nbCasesVoisines = 0;
int positionAbsolueX, postitionAbsolueY;
// Tableau d'indices autour d'une cellule, permettant d'accéder au contenu de celles-ci
int positionRelativeX[] = {1, -1, 0, 0, 1, 1, -1, -1};
int positionRelativeY[] = {0, 0, 1, -1, 1, -1, 1, -1};
for (int i = 0; i < (int) NOMBRE_CASES_VOISINES; ++i) {
// Afin d'obtenir les réelles positions autour de la cellule à calculer,
// il suffit d'additionner la position relative avec la relation courante.
positionAbsolueX = (int) x + positionRelativeX[i];
postitionAbsolueY = (int) y + positionRelativeY[i];
// Les cellules hors de la grille ne sont pas vérifiés
if (positionAbsolueX < (int) tableau[0].size() && positionAbsolueX >= 0 &&
postitionAbsolueY >= 0 && postitionAbsolueY < (int) tableau.size()) {
if (tableau[(size_t) postitionAbsolueY][(size_t) positionAbsolueX] == 1) {
nbCasesVoisines++;
}
}
}
return nbCasesVoisines;
}
void afficherTableau(const vector <vector<bool>>&tableau, char caractereVie,
char caractereMort) {
for (size_t i = 0; i < tableau.size(); ++i) {
for (size_t j = 0; j < tableau[0].size(); ++j) {
cout << " " << (tableau[i][j] ? caractereVie : caractereMort) << " ";
}
cout << endl;
}
}
bool estDansIntervalle(const vector<unsigned> &V, const unsigned val) {
for (auto i = V.begin(); i != V.end(); ++i) {
if (val == *i) {
return true;
}
}
return false;
}
bool etatFutur(const vector <vector<bool>>&tableau, unsigned i, unsigned j) {
unsigned occurences = occ(tableau, j, i);
if (tableau[i][j]) {
return estDansIntervalle(REGLE_NAISSANCE, occurences) ||
estDansIntervalle(REGLE_SURVIS, occurences) ? 1 : 0;
} else {
return estDansIntervalle(REGLE_NAISSANCE, occurences) ? 1 : 0;
}
}