diff --git a/GOLAppLib/lib/x64/Debug/GOLAppLib.lib b/GOLAppLib/lib/x64/Debug/GOLAppLib.lib deleted file mode 100644 index c89ee75..0000000 Binary files a/GOLAppLib/lib/x64/Debug/GOLAppLib.lib and /dev/null differ diff --git a/GOLAppLib/lib/x64/Debug/GOLAppLib.pdb b/GOLAppLib/lib/x64/Debug/GOLAppLib.pdb deleted file mode 100644 index 529e667..0000000 Binary files a/GOLAppLib/lib/x64/Debug/GOLAppLib.pdb and /dev/null differ diff --git a/GOLAppLib/lib/x64/Debug/GOLEngine.idb b/GOLAppLib/lib/x64/Debug/GOLEngine.idb deleted file mode 100644 index 0cbe801..0000000 Binary files a/GOLAppLib/lib/x64/Debug/GOLEngine.idb and /dev/null differ diff --git a/GOLAppLib/lib/x64/Debug/GOLEngine.lib b/GOLAppLib/lib/x64/Debug/GOLEngine.lib deleted file mode 100644 index e955159..0000000 Binary files a/GOLAppLib/lib/x64/Debug/GOLEngine.lib and /dev/null differ diff --git a/GOLAppLib/lib/x64/Debug/GOLEngine.pdb b/GOLAppLib/lib/x64/Debug/GOLEngine.pdb deleted file mode 100644 index 451e5ce..0000000 Binary files a/GOLAppLib/lib/x64/Debug/GOLEngine.pdb and /dev/null differ diff --git a/GOLAppLib/lib/x64/Release/GOLAppLib.lib b/GOLAppLib/lib/x64/Release/GOLAppLib.lib deleted file mode 100644 index 28d0ee9..0000000 Binary files a/GOLAppLib/lib/x64/Release/GOLAppLib.lib and /dev/null differ diff --git a/GOLAppLib/lib/x64/Release/GOLEngine.lib b/GOLAppLib/lib/x64/Release/GOLEngine.lib deleted file mode 100644 index 398c452..0000000 Binary files a/GOLAppLib/lib/x64/Release/GOLEngine.lib and /dev/null differ diff --git a/GOLAppLib/lib/x64/Release/GOLEngine.pdb b/GOLAppLib/lib/x64/Release/GOLEngine.pdb deleted file mode 100644 index c875605..0000000 Binary files a/GOLAppLib/lib/x64/Release/GOLEngine.pdb and /dev/null differ diff --git a/GPA675Lab1GOL/GOLTeamH.cpp b/GPA675Lab1GOL/GOLTeamH.cpp index 0c5f456..34f4e52 100644 --- a/GPA675Lab1GOL/GOLTeamH.cpp +++ b/GPA675Lab1GOL/GOLTeamH.cpp @@ -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; - } + mBorderManagement = borderManagement; } + +//! \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() }; - - 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()++; + // 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) { + } } +<<<<<<< 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). + //! + //!
+	//! [           32 bits            ]
+	//! [8 bits][8 bits][8 bits][8 bits]
+	//! [alpha ][red   ][green ][blue  ]
+	//! [alpha ][rouge ][vert  ][bleu  ]
+	//! 
+ //! + //! 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(grid[index]); - - *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); + // On itère sur chaque éléments du tableau et on associe la couleur. + 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 << 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; } } @@ -301,4 +516,4 @@ std::optional GOLTeamH::convertCharToNumber(const char c) return std::nullopt; return (c - 48); -} \ No newline at end of file +} diff --git a/GPA675Lab1GOL/GOLTeamH.h b/GPA675Lab1GOL/GOLTeamH.h index 44b5c7b..5eb7bb4 100644 --- a/GPA675Lab1GOL/GOLTeamH.h +++ b/GPA675Lab1GOL/GOLTeamH.h @@ -6,8 +6,11 @@ #include #include #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 mBorderManagement; std::optional 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 convertCharToNumber(const char c); -}; \ No newline at end of file +}; +>>>>>>> 42a4f5dfba2d2df6f34eecb5fb19fea8a70afc9c diff --git a/GPA675Lab1GOL/GridTeamH.cpp b/GPA675Lab1GOL/GridTeamH.cpp index 375378a..02e9de8 100644 --- a/GPA675Lab1GOL/GridTeamH.cpp +++ b/GPA675Lab1GOL/GridTeamH.cpp @@ -1,5 +1,9 @@ #include "GridTeamH.h" #include "GOL.h" +#include + +//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::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�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(totalDead()) / static_cast(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(totalAlive()) / static_cast(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; - } - } + for (auto& i : mData) + i = 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; + for (size_t i{}; i < mData.size(); i++) + mData[i] = !(i % 2) ? initValue : otherValue; +} - mData[index] = !(index % 2) ? initValue : otherValue; - } +void GridTeamH::randomize(double percentAlive) +{ + for (auto& i : mData) { + if (mDistribution(mEngine) < percentAlive) + i = CellType::alive; + else + i = CellType::dead; } } - -void GridTeamH::randomize(double percentAlive, bool fillBorder) -{ - 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); -} - - diff --git a/GPA675Lab1GOL/GridTeamH.h b/GPA675Lab1GOL/GridTeamH.h index b1dd34c..a8aea62 100644 --- a/GPA675Lab1GOL/GridTeamH.h +++ b/GPA675Lab1GOL/GridTeamH.h @@ -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 fill(CellType value); + void fillAternately(CellType initValue); + void randomize(double percentAlive); - void fillBorder(CellType value); - void fillBorderWarped(); - void fillBorderMirror(); - - void switchToIntermediate(); - bool isInBorder(size_t index) const; - -private: - DataType mData, mIntermediateData; - size_t mWidth, mHeight; - +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)); -} \ No newline at end of file + std::uniform_real_distribution<> mDistribution; \ No newline at end of file diff --git a/GPA675Lab1GOL/main.cpp b/GPA675Lab1GOL/main.cpp index 18a2d52..c951eb3 100644 --- a/GPA675Lab1GOL/main.cpp +++ b/GPA675Lab1GOL/main.cpp @@ -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(); }