clean up de GridTeamH
This commit is contained in:
parent
7e4caa2d01
commit
4a6bd1f5fc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,41 +1,112 @@
|
||||
#include "GOLTeamH.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//! \brief Accesseur retournant la largeur de la grille de simualtion.
|
||||
//!
|
||||
//! \return La largeur de la grille.
|
||||
//!
|
||||
size_t GOLTeamH::width() const
|
||||
{
|
||||
return mData.width();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! \brief Accesseur retournant la hauteur de la grille de simualtion.
|
||||
//!
|
||||
//! \return La hauteur de la grille.
|
||||
//!
|
||||
size_t GOLTeamH::height() const
|
||||
{
|
||||
return mData.height();
|
||||
}
|
||||
|
||||
//! \brief Accesseur retournant le nombre total de cellules de la grille
|
||||
//! de simualtion.
|
||||
//!
|
||||
//! \return Le nombre total de cellules de la grille.
|
||||
size_t GOLTeamH::size() const
|
||||
{
|
||||
return mData.size();
|
||||
}
|
||||
|
||||
//! \brief Accesseur retournant l'état d'une cellule.
|
||||
//!
|
||||
//! \details Cette fonction ne valide pas les entrées pour une raison de
|
||||
//! performance.
|
||||
//! L'origine est le coin supérieur gauche de la grille.
|
||||
//!
|
||||
//! \param x La coordonnée en x de la cellule.
|
||||
//! \param y La coordonnée en y de la cellule.
|
||||
//! \return L'état de la cellule.
|
||||
GOL::State GOLTeamH::state(int x, int y) const
|
||||
{
|
||||
return mData.value(x, y);
|
||||
}
|
||||
|
||||
//! \brief Accesseur retournant la chaîne de caractères correspondant à
|
||||
//! la règle courante.
|
||||
//!
|
||||
//! \details La chaîne de caractères est de la forme "B###/S###".
|
||||
//!
|
||||
//! \return La chaîne de caractères correspondant à la règle courante selon
|
||||
//! le format `B###.../S###...`.
|
||||
|
||||
std::string GOLTeamH::rule() const
|
||||
{
|
||||
return mRule.value_or(std::move(std::string()));
|
||||
}
|
||||
|
||||
//! \brief Accesseur retournant la stratégie courante de gestion des bords.
|
||||
//!
|
||||
//! \return La stratégie courante de gestion des bords.
|
||||
GOL::BorderManagement GOLTeamH::borderManagement() const
|
||||
{
|
||||
return mBorderManagement.value_or(GOL::BorderManagement::immutableAsIs);
|
||||
}
|
||||
|
||||
//! \brief Accesseur retournant la couleur d'un état.
|
||||
//!
|
||||
//! \details Cette fonction retourne la couleur associée à l'état passé
|
||||
//! en argument.
|
||||
//!
|
||||
//! \param state L'état dont on veut connaître la couleur.
|
||||
//! \return La couleur associée à l'état.
|
||||
GOL::Color GOLTeamH::color(State state) const
|
||||
{
|
||||
return state == GOL::State::alive ? mAliveColor : mDeadColor;
|
||||
}
|
||||
|
||||
// TODO
|
||||
//! \brief Accesseurs retournant des informations générales sur la
|
||||
//! simulation en cours.
|
||||
//!
|
||||
//! \details Retourne plusieurs informations sur la simulation. Chaque
|
||||
//! valeur est optionnelle et peut être indéterminée.
|
||||
//!
|
||||
//! Voir la documentation liée à la structure Statistics pour plus de détails.
|
||||
//!
|
||||
//! Toutefois, les tendances sont définies ainsi :
|
||||
//! - La tendance indique la variation entre le nombre de cellules mortes
|
||||
//! et vivantes en valeur absolue et relative.
|
||||
//! - Une tendance est à la hausse s'il y a plus de cellules naissantes
|
||||
//! que mourantes.
|
||||
//! - Un premier caractères indique si la tendance est à la hausse (+) ou
|
||||
//! à la baisse (-).
|
||||
//! - La tendance doit se faire sur un certain nombre d'itérations. Ce
|
||||
//! nombre est défini par l'implémentation mais doit être supérieur à 10
|
||||
//! itérations. L'objectif est d'avoir une lecture relativement stable de
|
||||
//! la tendance afin qu'elle soit agréable à lire dans l'interface usager.
|
||||
//! - Optionnellement, vous pouvez ajouter un second caractère indiquant
|
||||
//! la stabilité de la tendance. Voici la légende :
|
||||
//! - '-' : stable
|
||||
//! - '~' : légèrement instable
|
||||
//! - 'w' : instable
|
||||
//! - 'W' : très instable
|
||||
//!
|
||||
//! \return Une structure contenant les informations sur la simulation.
|
||||
GOL::Statistics GOLTeamH::statistics() const
|
||||
{
|
||||
return std::move(GOL::Statistics{
|
||||
@ -54,22 +125,96 @@ GOL::Statistics GOLTeamH::statistics() const
|
||||
});
|
||||
}
|
||||
|
||||
// TODO
|
||||
//! \brief Accesseurs retournant les informations sur la réalisation
|
||||
//! de l'implémentation.
|
||||
//!
|
||||
//! \details Retourne plusieurs informations sur la réalisation de
|
||||
//! l'implémentation. Chaque valeur est optionnelle et peut être
|
||||
//! indéterminée.
|
||||
//!
|
||||
//! En quelque sorte, c'est l'approche utilisée pour produire un mini
|
||||
//! rapport utilitaire.
|
||||
//!
|
||||
//! Voir la documentation liée à la structure ImplementationInformation
|
||||
//! pour plus de détails.
|
||||
//!
|
||||
//! Pour les réponses 'answers', l'objectif est d'utiliser clairement le
|
||||
//! vocabulaire technique approprié tout en étant très concis et très précis.
|
||||
//!
|
||||
//! \return Une structure contenant les informations sur la réalisation
|
||||
//!
|
||||
GOL::ImplementationInformation GOLTeamH::information() const
|
||||
{
|
||||
return std::move(ImplementationInformation{
|
||||
.title{"Laboratoire 1"},
|
||||
.authors{{"Timothée Leclaire-Fournier"}, {"Martin Euzenat"} }
|
||||
.authors{{"Timothée Leclaire-Fournier"}, {"Martin Euzenat martin.euzenat.1@ens.etsmtl.ca"}},
|
||||
.answers{},
|
||||
.optionnalComments{}
|
||||
// Réponses aux questions...
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//! \brief Mutateur modifiant la taille de la grille de simulation.
|
||||
//!
|
||||
//! \details Cette fonction réinitialise la taille et le contenu de la
|
||||
//! grille. La taille est spécifié peut être 0 x 0. Le contenu de la
|
||||
//! grille est entièrement mis à l'état passé en argument.
|
||||
//!
|
||||
//! Cette fonction s'assure que si l'une des dimensions est 0, alors les
|
||||
//! deux sont mises à 0.
|
||||
//!
|
||||
//! L'ancient motif de la grille est perdu. L'itération courante est remise
|
||||
//! à 0.
|
||||
//!
|
||||
//! \param width La nouvelle largeur de la grille.
|
||||
//! \param height La nouvelle hauteur de la grille.
|
||||
//! \param defaultState L'état d'initialisation des cellules.
|
||||
//!
|
||||
void GOLTeamH::resize(size_t width, size_t height, State defaultState)
|
||||
{
|
||||
mData.resize(width, height, defaultState);
|
||||
}
|
||||
|
||||
// La performance n'est pas tant recherchée puisque cette fonction est appelée très rarement
|
||||
//! \brief Mutateur modifiant la règle de la simulation.
|
||||
//!
|
||||
//! \details Cette fonction s'assure que la chaîne de caractères est valide
|
||||
//! et assigne la nouvelle règle pour que les prochaines évolutions
|
||||
//! l'utilisent.
|
||||
//!
|
||||
//! Si la règle est valide, on assigne la novuelle règle, l'ancienne règle
|
||||
//! est perdue et l'itération courante est remise à 0. Si la règle est
|
||||
//! invalide, on ne fait rien.
|
||||
//!
|
||||
//! La simulation doit être en mesure de supporté les règles valides.
|
||||
//!
|
||||
//! Les règles sont définies par une chaîne de caractère suivant ce format:
|
||||
//! `B###.../S###...`, par exemple : `B3/S23`.
|
||||
//! - La lettre `B` (minuscule ou majuscule) débute la section 'B'orn
|
||||
//! concernant les états morts qui naissent
|
||||
//! - Suit une série de _n_ caractères pouvant contenir une instance de
|
||||
//! chacun de ces caractères : '0', '1', '2', '3', '4', '5', '6', '7', '8'.
|
||||
//! La valeur de _n_ peut varier de 0 à 9. Cette séquence indique toutes
|
||||
//! les combinaisons du nombre de cellules voisines vivantes qui font
|
||||
//! naître une cellule morte.
|
||||
//! - Le caractère barre oblique `/` (_slash_) qui indique la transition
|
||||
//! vers la section suivante.
|
||||
//! - La lettre `S` (minuscule ou majuscule) débute la section 'S'urvive
|
||||
//! concernant les états vivants qui survivent (qui restent vivantes).
|
||||
//! - Suit une série de _n_ caractères pouvant contenir une instance de
|
||||
//! chacun de ces caractères : '0', '1', '2', '3', '4', '5', '6', '7', '8'.
|
||||
//! La valeur de _n_ peut varier de 0 à 9. Cette séquence indique toutes
|
||||
//! les combinaisons du nombre de cellules voisines vivantes qui font
|
||||
//! naître une cellule morte.
|
||||
//!
|
||||
//! Par exemple : `B02/S1357` indique que :
|
||||
//! - si une cellule est morte :
|
||||
//! - elle naît se elle possède 0 ou 2 voisins vivants
|
||||
//! - si la cellule est vivante :
|
||||
//! - elle survie si elle possède 1, 3, 5 ou 7 voisins vivants
|
||||
//!
|
||||
//! La règle de Conway `B3/S23` est celle par défaut.
|
||||
|
||||
bool GOLTeamH::setRule(std::string const& rule)
|
||||
{
|
||||
mRule = rule;
|
||||
@ -117,150 +262,221 @@ bool GOLTeamH::setRule(std::string const& rule)
|
||||
return false;
|
||||
}
|
||||
|
||||
void GOLTeamH::setBorderManagement(GOL::BorderManagement borderManagement)
|
||||
//! \brief Mutateur modifiant la stratégie de gestion de bord.
|
||||
//!
|
||||
//! \details Cette fonction assigne la nouvelle stratégie pour que les
|
||||
//! prochaines évolutions l'utilisent.
|
||||
//!
|
||||
//! L'ancienne stratégie est perdue. L'itération courante est remise à 0.
|
||||
//!
|
||||
//! Vous devez être en mesure de gérer les effets de bord selon 5
|
||||
//! stratégies différentes :
|
||||
//! - BorderManagement::immutableAsIs : immuable tel quel. Les cellules
|
||||
//! du contour ne sont jamais modifiées.
|
||||
//! - BorderManagement::foreverDead : mort pour toujours. Les cellules
|
||||
//! du contour ne sont jamais modifiées, elles sont toujours mortes.
|
||||
//! - BorderManagement::foreverAlive : vivant pour toujours. Les cellules
|
||||
//! du contour ne sont jamais modifiées, elles sont toujours vivantes.
|
||||
//! - BorderManagement::warping : téléportation. Les cellules du contour
|
||||
//! sont évaluées. On utilise les cellules du côté opposé de la grille
|
||||
//! pour les cellules extérieures.
|
||||
//! - BorderManagement::mirror : miroir. Les cellules du contour sont
|
||||
//! évaluées. On utilise les cellules du côté opposé de la cellule pour
|
||||
//! les cellules extérieures.
|
||||
//!
|
||||
//! Pour les 2 exemples suivants, la cellule analysée `-*-` possède 3
|
||||
//! voisins situés à l'extérieur de la grille 'x', 'y' et 'z'. Ces cellules
|
||||
//! sont substituées par les voisins opposés 'X', 'Y' et 'Z'.
|
||||
//!
|
||||
//! BorderManagement::warping utilise les voisins opposés par rapport à la
|
||||
//! **grille**.
|
||||
void GOLTeamH::setBorderManagement(BorderManagement borderManagement)
|
||||
{
|
||||
mBorderManagement = borderManagement;
|
||||
mIteration = 0;
|
||||
|
||||
switch (borderManagement) {
|
||||
case GOL::BorderManagement::foreverDead:
|
||||
mData.fillBorder(GridTeamH::CellType::dead);
|
||||
break;
|
||||
case GOL::BorderManagement::foreverAlive:
|
||||
mData.fillBorder(GridTeamH::CellType::alive);
|
||||
break;
|
||||
case GOL::BorderManagement::warping:
|
||||
mData.fillBorderWarped();
|
||||
break;
|
||||
case GOL::BorderManagement::mirror:
|
||||
mData.fillBorderWarped();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! \brief Mutateur modifiant l'état d'une cellule de la grille.
|
||||
//!
|
||||
//! \details Cette fonction ne valide pas les entrées pour une raison de
|
||||
//! performance. L'origine est le coin supérieur gauche de la grille.
|
||||
//!
|
||||
//! \param x La coordonnée en x de la cellule.
|
||||
//! \param y La coordonnée en y de la cellule.
|
||||
//! \param state Le nouvel état de la cellule.
|
||||
void GOLTeamH::setState(int x, int y, State state)
|
||||
{
|
||||
mData.setAt(x, y, state);
|
||||
mIteration = 0;
|
||||
}
|
||||
|
||||
//! \brief Mutateur remplissant de façon uniforme toutes les cellules de
|
||||
//! la grille.
|
||||
//!
|
||||
//! \details Cette fonction remplit toutes les cellules de la grille avec
|
||||
//! l'état passé en argument.
|
||||
//!
|
||||
//! L'itération courante est remise à 0.
|
||||
//!
|
||||
//! \param state L'état d'initialisation des cellules.
|
||||
void GOLTeamH::fill(State state)
|
||||
{
|
||||
if (mBorderManagement == GOL::BorderManagement::immutableAsIs)
|
||||
mData.fill(state, true);
|
||||
else
|
||||
mData.fill(state, false);
|
||||
|
||||
mData.fill(state);
|
||||
mIteration = 0;
|
||||
}
|
||||
|
||||
//! \brief Mutateur remplissant de façon alternée toutes les cellules de
|
||||
//! la grille.
|
||||
//!
|
||||
//! \details Cette fonction remplit toutes les cellules de la grille avec
|
||||
//! un motif en damier. La première cellule, en haut à gauche, est de
|
||||
//! l'état passée en argument.
|
||||
//!
|
||||
//! L'itération courante est remise à 0.
|
||||
//!
|
||||
//! \param firstCell L'état de la première cellule.
|
||||
void GOLTeamH::fillAlternately(State firstCell)
|
||||
{
|
||||
if (mBorderManagement == GOL::BorderManagement::immutableAsIs)
|
||||
mData.fillAternately(firstCell, true);
|
||||
else
|
||||
mData.fillAternately(firstCell, false);
|
||||
|
||||
mData.fillAternately(firstCell);
|
||||
mIteration = 0;
|
||||
}
|
||||
|
||||
//! \brief Mutateur remplissant de façon aléatoire toutes les cellules de
|
||||
//! la grille.
|
||||
//!
|
||||
//! \details Cette fonction remplit toutes les cellules de la grille avec
|
||||
//! un motif aléatoire. Le pourcentage de probabilité d'une cellule d'être
|
||||
//! vivante est passé en argument.
|
||||
//!
|
||||
//! L'itération courante est remise à 0.
|
||||
//!
|
||||
//! \param percentAlive Le pourcentage de probabilité d'une cellule d'être
|
||||
//! vivante. La valeur doit être comprise entre 0.0 et 1.0 inclusivement.
|
||||
void GOLTeamH::randomize(double percentAlive)
|
||||
{
|
||||
if (mBorderManagement == GOL::BorderManagement::immutableAsIs)
|
||||
mData.randomize(percentAlive, true);
|
||||
else
|
||||
mData.randomize(percentAlive, false);
|
||||
|
||||
mData.randomize(percentAlive);
|
||||
mIteration = 0;
|
||||
}
|
||||
|
||||
// TODO
|
||||
//! \brief Mutateur remplissant la grille par le patron passé en argument.
|
||||
//!
|
||||
//! \details Cette fonction remplit la grille avec le patron donné. Le
|
||||
//! patron est centré sur la coordonnées (centerX, centerY).
|
||||
//!
|
||||
//! Le patron respecte un format précis. Se référer à l'énoncé pour voir
|
||||
//! tous les détails.
|
||||
//!
|
||||
//! Si le patron n'est pas valide, la grille n'est pas modifiée et on
|
||||
//! retourne false. Sinon, on retourne vrai.
|
||||
//!
|
||||
//! L'itération courante est remise à 0.
|
||||
//!
|
||||
//! \param pattern Le patron à appliquer.
|
||||
//! \param centerX La coordonnée en x de la grille où se trouve centré le patron.
|
||||
//! \param centerY La coordonnée en y de la grille où se trouve centré le patron.
|
||||
//! \return true si le patron est valide, false sinon.
|
||||
//!
|
||||
bool GOLTeamH::setFromPattern(std::string const& pattern, int centerX, int centerY)
|
||||
{
|
||||
mIteration = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO
|
||||
//! \brief Mutateur remplissant la grille par le patron passé en argument.
|
||||
//!
|
||||
//! \details Cette fonction est une surcharge utilitaire de la fonction
|
||||
//! setFromPattern(std::string const & pattern, int centerX, int centerY).
|
||||
//! Cette version utilise le centre de la grille comme centre du patron.
|
||||
//!
|
||||
//! L'itération courante est remise à 0.
|
||||
//!
|
||||
//! \param pattern Le patron à appliquer.
|
||||
//! \return true si le patron est valide, false sinon.
|
||||
bool GOLTeamH::setFromPattern(std::string const& pattern)
|
||||
{
|
||||
mIteration = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
//! \brief Mutateur modifiant la couleur d'un état.
|
||||
//!
|
||||
//! \details Cette fonction modifie la couleur d'un état.
|
||||
//!
|
||||
//! Formellement, cette fonction ne modifie rien en soit mais plutôt
|
||||
//! permet de stocker quelle couleur utiliser pour représenter un état
|
||||
//! lors de l'affichage de la grille sur une image.
|
||||
//!
|
||||
//! \param state L'état dont on veut modifier la couleur.
|
||||
//! \param color La nouvelle couleur de l'état.
|
||||
void GOLTeamH::setSolidColor(State state, Color const& color)
|
||||
{
|
||||
if (state == State::dead)
|
||||
mDeadColor = color;
|
||||
else
|
||||
mAliveColor = color;
|
||||
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
//! \details Cette fonction constitue la partie centrale de la simulation.
|
||||
//! Elle est responsable de faire évoluer la grille d'une itération.
|
||||
//!
|
||||
//! Cette fonction doit appliquer la logique de l'automate cellulaire en
|
||||
//! tenant compte pour chaque cellule :
|
||||
//! - de la grille
|
||||
//! - de l'état de chacune des cellules voisines
|
||||
//! - de la règle de la simulation
|
||||
//! - de la stratégie de gestion de bord
|
||||
//!
|
||||
//! Après l'appel de cette fonction, la grille est mise à jour avec le
|
||||
//! nouvel état de chaque cellule suivant l'état précédent. Les statistiques
|
||||
//! doivent tenir compte de cette évolution.
|
||||
=======
|
||||
// TODO: performance
|
||||
>>>>>>> 42a4f5dfba2d2df6f34eecb5fb19fea8a70afc9c
|
||||
void GOLTeamH::processOneStep()
|
||||
{
|
||||
auto& grid{ mData.data() };
|
||||
auto& intGrid{ mData.intData() };
|
||||
// On commence à itérer sur les côtés. En règlant ces cas particuliers, on
|
||||
// peut éviter des branches dans la boucle principale. Le branch predictor
|
||||
// aime cela.
|
||||
for (size_t i{}; i < mData.width(); ++i) {
|
||||
|
||||
if (mBorderManagement == GOL::BorderManagement::foreverDead) {
|
||||
size_t aliveCount{};
|
||||
size_t offset{ width() + 2 };
|
||||
auto* ptr{ &grid[0]};
|
||||
|
||||
for (size_t i{}; i < mData.realSize() - offset - 1; ++i) {
|
||||
|
||||
if (mData.isInBorder(i)) {
|
||||
ptr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
aliveCount = 0;
|
||||
|
||||
// Top
|
||||
ptr -= offset + 1;
|
||||
if (*ptr == GOL::State::alive)
|
||||
aliveCount++;
|
||||
ptr++;
|
||||
if (*ptr == GOL::State::alive)
|
||||
aliveCount++;
|
||||
ptr++;
|
||||
if (*ptr == GOL::State::alive)
|
||||
aliveCount++;
|
||||
|
||||
// Milieu
|
||||
ptr += offset - 2;
|
||||
if (*ptr == GOL::State::alive)
|
||||
aliveCount++;
|
||||
ptr += 2;
|
||||
if (*ptr == GOL::State::alive)
|
||||
aliveCount++;
|
||||
|
||||
|
||||
// Dessous
|
||||
ptr += offset - 2;
|
||||
if (*ptr == GOL::State::alive)
|
||||
aliveCount++;
|
||||
ptr++;
|
||||
if (*ptr == GOL::State::alive)
|
||||
aliveCount++;
|
||||
ptr++;
|
||||
if (*ptr == GOL::State::alive)
|
||||
aliveCount++;
|
||||
|
||||
if (grid[i] == GOL::State::alive)
|
||||
intGrid[i] = (mParsedRuleSurvive.test(aliveCount)) ? GOL::State::alive : GOL::State::dead;
|
||||
else
|
||||
intGrid[i] = (mParsedRuleRevive.test(aliveCount)) ? GOL::State::alive : GOL::State::dead;
|
||||
|
||||
// On retourne à une place plus loin qu'à l'origine.
|
||||
ptr -= offset;
|
||||
}
|
||||
ptr = nullptr;
|
||||
|
||||
mData.switchToIntermediate();
|
||||
mIteration.value()++;
|
||||
}
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
|
||||
//! \brief Fonction dessinant l'état de la simulation sur une image passée
|
||||
//! en paramètre.
|
||||
//!
|
||||
//! \details Cette fonction dessine l'état courant de chaque cellule sur
|
||||
//! l'image donnée. Chaque pixel de l'image correspond à une cellule de
|
||||
//! la grille de simulation.
|
||||
//!
|
||||
//! La couleur de chaque pixel est déterminée par la couleur associée à
|
||||
//! l'état de la cellule.
|
||||
//!
|
||||
//! L'organisation en mémoire est ce qu'on appel 'Packed Pixel' suivant
|
||||
//! l'ordre ARGB. Ainsi, toutes les données d'un pixel est contiguë en
|
||||
//! mémoire. Les 4 canaux de couleurs sont stockés dans un entier non
|
||||
//! signé de 32 bits. Chaque canal est codé sur 8 bits. Le canal alpha est
|
||||
//! le plus significatif et le canal bleu est le moins significatif.
|
||||
//!
|
||||
//! La variable buffer pointe vers un tableau de pixels de taille
|
||||
//! buffer_size. La taille de l'image est donc buffer_size / sizeof(uint32_t).
|
||||
//!
|
||||
//! <pre>
|
||||
//! [ 32 bits ]
|
||||
//! [8 bits][8 bits][8 bits][8 bits]
|
||||
//! [alpha ][red ][green ][blue ]
|
||||
//! [alpha ][rouge ][vert ][bleu ]
|
||||
//! </pre>
|
||||
//!
|
||||
//! Vous pouvez considérer que l'image a été créée avec le format de
|
||||
//! Qt QImage::Format_ARGB32.
|
||||
//!
|
||||
//! Il est attendu que vous fassiez une validation minimum des intrants.
|
||||
//!
|
||||
//! \param buffer Le tableau de pixels de l'image.
|
||||
//! \param buffer_size La taille du tableau de pixels.
|
||||
=======
|
||||
>>>>>>> 42a4f5dfba2d2df6f34eecb5fb19fea8a70afc9c
|
||||
void GOLTeamH::updateImage(uint32_t* buffer, size_t buffer_size) const
|
||||
{
|
||||
if (buffer == nullptr)
|
||||
@ -268,30 +484,29 @@ void GOLTeamH::updateImage(uint32_t* buffer, size_t buffer_size) const
|
||||
|
||||
auto s_ptr = buffer;
|
||||
auto e_ptr = &buffer[buffer_size];
|
||||
auto& grid = mData.data();
|
||||
|
||||
// On itère sur chaque éléments du tableau et on associe la couleur.
|
||||
for (size_t index{ width() + 2 };
|
||||
index < (width() + 2) * (height() + 1);
|
||||
index++) {
|
||||
|
||||
if (mData.isInBorder(index))
|
||||
continue;
|
||||
|
||||
auto var = static_cast<uint8_t>(grid[index]);
|
||||
|
||||
for (const auto& i : mData.data()) {
|
||||
if (i == GridTeamH::CellType::alive) {
|
||||
*s_ptr &= 0; // Clear
|
||||
*s_ptr |= MAX_ALPHA << 24; // Alpha = 255
|
||||
|
||||
*s_ptr |= mAliveColor.red * var << 16;
|
||||
*s_ptr |= mAliveColor.green * var << 8;
|
||||
*s_ptr |= mAliveColor.blue * var;
|
||||
|
||||
*s_ptr |= mDeadColor.red * (1 - var) << 16;
|
||||
*s_ptr |= mDeadColor.green * (1 - var) << 8;
|
||||
*s_ptr |= mDeadColor.blue * (1 - var);
|
||||
*s_ptr |= mAliveColor.red << 16;
|
||||
*s_ptr |= mAliveColor.green << 8;
|
||||
*s_ptr |= mAliveColor.blue;
|
||||
}
|
||||
else {
|
||||
*s_ptr &= 0;
|
||||
*s_ptr |= MAX_ALPHA << 24;
|
||||
*s_ptr |= mDeadColor.red << 16;
|
||||
*s_ptr |= mDeadColor.green << 8;
|
||||
*s_ptr |= mDeadColor.blue;
|
||||
}
|
||||
|
||||
s_ptr++;
|
||||
|
||||
// Sanity check, pour éviter des problèmes
|
||||
if (s_ptr >= e_ptr)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,11 @@
|
||||
#include <bitset>
|
||||
#include <GOL.h>
|
||||
#include "GridTeamH.h"
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
||||
constexpr unsigned char MAX_ALPHA = 255;
|
||||
>>>>>>> 42a4f5dfba2d2df6f34eecb5fb19fea8a70afc9c
|
||||
|
||||
class GOLTeamH : public GOL
|
||||
{
|
||||
@ -15,7 +18,7 @@ public:
|
||||
size_t width() const override;
|
||||
size_t height() const override;
|
||||
size_t size() const override;
|
||||
State state(int x, int y) const override;
|
||||
State state(int x, int y) const override; //details L'état d'une cellule peut être mort ou vivant.
|
||||
std::string rule() const override;
|
||||
BorderManagement borderManagement() const override;
|
||||
Color color(State state) const override;
|
||||
@ -40,11 +43,18 @@ private:
|
||||
std::optional<BorderManagement> mBorderManagement;
|
||||
std::optional<IterationType> mIteration;
|
||||
|
||||
<<<<<<< HEAD
|
||||
Grid mData;
|
||||
std::string mRule;
|
||||
};
|
||||
|
||||
=======
|
||||
// On utilise un bitset qui contient les règles de chaque nombre.
|
||||
std::bitset<9> mParsedRuleRevive, mParsedRuleSurvive;
|
||||
GridTeamH mData;
|
||||
Color mDeadColor, mAliveColor;
|
||||
|
||||
// Fonctions utilisées à l'interne.
|
||||
// Fonction utilisée à l'interne.
|
||||
std::optional<unsigned char> convertCharToNumber(const char c);
|
||||
};
|
||||
>>>>>>> 42a4f5dfba2d2df6f34eecb5fb19fea8a70afc9c
|
||||
|
@ -1,5 +1,9 @@
|
||||
#include "GridTeamH.h"
|
||||
#include "GOL.h"
|
||||
#include <iostream>
|
||||
|
||||
//constructeur Grid par défaut
|
||||
|
||||
|
||||
GridTeamH::GridTeamH()
|
||||
: GridTeamH(100, 100, CellType::alive)
|
||||
@ -23,6 +27,8 @@ size_t GridTeamH::width() const
|
||||
{
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
|
||||
// Accesseur retournant la hauteur de la grille.
|
||||
size_t GridTeamH::height() const
|
||||
{
|
||||
@ -35,79 +41,64 @@ size_t GridTeamH::size() const
|
||||
return mWidth * mHeight;
|
||||
}
|
||||
|
||||
size_t GridTeamH::realSize() const
|
||||
{
|
||||
return (mWidth + 2) * (mHeight + 2);
|
||||
}
|
||||
|
||||
// Mutateur modifiant la taille de la grille et initialise le contenu par la valeur spécifiée.
|
||||
void GridTeamH::resize(size_t width, size_t height, CellType initValue)
|
||||
{
|
||||
mData.resize((width + 2) * (height + 2));
|
||||
mIntermediateData.resize((width + 2) * (width + 2));
|
||||
// TODO: Performance de resize avec beaucoup d'appel?
|
||||
// Investiguer reserve + resize
|
||||
mData.resize(width * height);
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
|
||||
fill(initValue, false);
|
||||
fill(initValue);
|
||||
}
|
||||
|
||||
// Accesseur retournant la valeur d'une cellule à une certaine coordonnée.
|
||||
GridTeamH::CellType GridTeamH::value(int column, int row) const
|
||||
|
||||
{
|
||||
size_t offset{ mWidth + 2 };
|
||||
return mData[offset * row + (column - 1)];
|
||||
return mData[(column - 1) * (row - 1)];
|
||||
}
|
||||
|
||||
// Mutateur modifiant la valeur d'une cellule à une certaine coordonnée.
|
||||
void GridTeamH::setValue(int column, int row, CellType value)
|
||||
{
|
||||
size_t offset{ mWidth + 2 };
|
||||
mData[offset * row + (column - 1)] = value;
|
||||
mData[(column - 1) * (row - 1)] = value;
|
||||
}
|
||||
|
||||
// Accesseur retournant la valeur d'une cellule à une certaine coordonnée.
|
||||
std::optional<GridTeamH::CellType> GridTeamH::at(int column, int row) const
|
||||
{
|
||||
if (column >= mWidth || row >= mHeight)
|
||||
if (column > mWidth || row > mHeight)
|
||||
return std::nullopt;
|
||||
|
||||
size_t offset{ mWidth + 2 };
|
||||
return mData[offset * row + (column - 1)];
|
||||
return mData[(column - 1) * (row - 1)];
|
||||
}
|
||||
|
||||
|
||||
// Mutateur modifiant la valeur d'une cellule à une certaine coordonn<6E>e.
|
||||
void GridTeamH::setAt(int column, int row, CellType value)
|
||||
{
|
||||
if (column > mWidth || row > mHeight)
|
||||
return;
|
||||
|
||||
size_t offset{ mWidth + 2 };
|
||||
mData[offset * row + (column - 1)] = value;
|
||||
mData[(column - 1) * (row - 1)] = value;
|
||||
}
|
||||
|
||||
|
||||
// Accesseur en lecture seule sur le "buffer" de la grille.
|
||||
GridTeamH::DataType const& GridTeamH::data() const
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
// Accesseur en lecture/écriture sur le "buffer" de la grille.
|
||||
GridTeamH::DataType& GridTeamH::data()
|
||||
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
GridTeamH::DataType const& GridTeamH::intData() const
|
||||
{
|
||||
return mIntermediateData;
|
||||
}
|
||||
|
||||
GridTeamH::DataType& GridTeamH::intData()
|
||||
{
|
||||
return mIntermediateData;
|
||||
}
|
||||
|
||||
// TODO: FIX
|
||||
// https://en.cppreference.com/w/cpp/algorithm/count
|
||||
size_t GridTeamH::totalDead() const
|
||||
{
|
||||
@ -119,7 +110,6 @@ float GridTeamH::totalDeadRel() const
|
||||
return static_cast<float>(totalDead()) / static_cast<float>(size());
|
||||
}
|
||||
|
||||
// TODO: FIX
|
||||
size_t GridTeamH::totalAlive() const
|
||||
{
|
||||
return std::count_if(mData.begin(), mData.end(), [](auto& i) { return i == CellType::alive; });
|
||||
@ -130,85 +120,26 @@ float GridTeamH::totalAliveRel() const
|
||||
return static_cast<float>(totalAlive()) / static_cast<float>(size());
|
||||
}
|
||||
|
||||
void GridTeamH::fill(CellType value, bool fillBorder)
|
||||
void GridTeamH::fill(CellType value)
|
||||
{
|
||||
if (fillBorder) {
|
||||
for (auto& i : mData)
|
||||
i = value;
|
||||
}
|
||||
else {
|
||||
for (size_t index{}; index < mData.size(); index++) {
|
||||
if (isInBorder(index))
|
||||
continue;
|
||||
|
||||
mData[index] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GridTeamH::fillAternately(CellType initValue, bool fillBorder)
|
||||
void GridTeamH::fillAternately(CellType initValue)
|
||||
{
|
||||
auto otherValue = (initValue == CellType::alive) ? CellType::dead : CellType::alive;
|
||||
|
||||
if (fillBorder) {
|
||||
for (size_t i{}; i < mData.size(); i++)
|
||||
mData[i] = !(i % 2) ? initValue : otherValue;
|
||||
}
|
||||
else {
|
||||
for (size_t index{}; index < mData.size(); index++) {
|
||||
if (isInBorder(index))
|
||||
continue;
|
||||
|
||||
mData[index] = !(index % 2) ? initValue : otherValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GridTeamH::randomize(double percentAlive, bool fillBorder)
|
||||
void GridTeamH::randomize(double percentAlive)
|
||||
{
|
||||
if (fillBorder) {
|
||||
for (auto& i : mData) {
|
||||
if (mDistribution(mEngine) < percentAlive)
|
||||
i = CellType::alive;
|
||||
else
|
||||
i = CellType::dead;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (size_t index{}; index < mData.size() - 1; index++) {
|
||||
if (isInBorder(index))
|
||||
continue;
|
||||
|
||||
if (mDistribution(mEngine) < percentAlive)
|
||||
mData[index] = CellType::alive;
|
||||
else
|
||||
mData[index] = CellType::dead;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GridTeamH::fillBorder(CellType value)
|
||||
{
|
||||
for (size_t index{}; index < mData.size(); index++) {
|
||||
if (isInBorder(index))
|
||||
mData[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void GridTeamH::fillBorderWarped()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void GridTeamH::fillBorderMirror()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void GridTeamH::switchToIntermediate()
|
||||
{
|
||||
// Swap pour la performance.
|
||||
mData.swap(mIntermediateData);
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,7 +26,6 @@ public:
|
||||
size_t width() const;
|
||||
size_t height() const;
|
||||
size_t size() const;
|
||||
size_t realSize() const;
|
||||
|
||||
void resize(size_t width, size_t height, CellType initValue = CellType{});
|
||||
|
||||
@ -39,10 +38,6 @@ public:
|
||||
|
||||
// Accesseurs du "buffer" de la grille
|
||||
DataType const& data() const;
|
||||
DataType& data();
|
||||
|
||||
DataType const& intData() const;
|
||||
DataType& intData();
|
||||
|
||||
size_t totalDead() const;
|
||||
float totalDeadRel() const;
|
||||
@ -50,31 +45,14 @@ public:
|
||||
size_t totalAlive() const;
|
||||
float totalAliveRel() const;
|
||||
|
||||
void fill(CellType value, bool fillBorder);
|
||||
void fillAternately(CellType initValue, bool fillBorder);
|
||||
void randomize(double percentAlive, bool fillBorder);
|
||||
|
||||
void fillBorder(CellType value);
|
||||
void fillBorderWarped();
|
||||
void fillBorderMirror();
|
||||
|
||||
void switchToIntermediate();
|
||||
bool isInBorder(size_t index) const;
|
||||
|
||||
private:
|
||||
DataType mData, mIntermediateData;
|
||||
size_t mWidth, mHeight;
|
||||
void fill(CellType value);
|
||||
void fillAternately(CellType initValue);
|
||||
void randomize(double percentAlive);
|
||||
|
||||
private: //
|
||||
DataType mData; // Il y a des attributs essentiels au fonctionnement de cette classe.
|
||||
size_t mWidth, mHeight; // À vous de les déterminer.
|
||||
// Pour la génération de nombres aléatoires
|
||||
std::random_device mRandomDevice;
|
||||
std::mt19937 mEngine;
|
||||
std::uniform_real_distribution<> mDistribution;
|
||||
};
|
||||
|
||||
inline bool GridTeamH::isInBorder(size_t index) const
|
||||
{
|
||||
return(index % (mWidth + 2) < 1
|
||||
|| index % (mWidth + 2) > mWidth
|
||||
|| index < mWidth + 2
|
||||
|| index > (mWidth + 2) * (mHeight + 1));
|
||||
}
|
@ -3,6 +3,9 @@
|
||||
#include "GOLApp.h"
|
||||
#include "GOLTeamH.h"
|
||||
|
||||
|
||||
//TEST DE COMMIT
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
QApplication application(argc, argv);
|
||||
@ -10,6 +13,9 @@ int main(int argc, char* argv[])
|
||||
GOLApp window;
|
||||
window.addEngine(new GOLTeamH());
|
||||
|
||||
|
||||
|
||||
|
||||
window.show();
|
||||
return application.exec();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user