Ajout de nombreuses fonctions dans Grid.cpp

This commit is contained in:
Timothée Leclaire-Fournier 2024-01-18 23:38:54 -05:00
parent 7c9c1bb210
commit 421526ba66
5 changed files with 107 additions and 30 deletions

View File

@ -35,22 +35,33 @@ GOL::Color GOLTeamH::color(State state) const
return state == GOL::State::alive ? mAliveColor : mDeadColor; return state == GOL::State::alive ? mAliveColor : mDeadColor;
} }
// TODO
GOL::Statistics GOLTeamH::statistics() const GOL::Statistics GOLTeamH::statistics() const
{ {
return GOL::Statistics{ return std::move(GOL::Statistics{
.rule = mRule, .rule = mRule,
.borderManagement = mBorderManagement, .borderManagement = mBorderManagement,
.width = width(), .width = width(),
.height = height(), .height = height(),
.totalCells = size(), .totalCells = size(),
.iteration = mIteration, .iteration = mIteration,
//.totalDeadAbs = mData.totalDead() .totalDeadAbs = mData.totalDead(),
}; .totalAliveAbs = mData.totalAlive(),
.totalDeadRel = mData.totalDeadRel(),
.totalAliveRel = mData.totalAliveRel()
// .tendencyAbs = ...,
// .tendencyRel = ...
});
} }
// TODO
GOL::ImplementationInformation GOLTeamH::information() const GOL::ImplementationInformation GOLTeamH::information() const
{ {
return ImplementationInformation(); return std::move(ImplementationInformation{
.title{"Laboratoire 1"},
.authors{{"Timothée Leclaire-Fournier"}, {"et Martin Euzenat"} }
// Réponses aux questions...
});
} }
void GOLTeamH::resize(size_t width, size_t height, State defaultState) void GOLTeamH::resize(size_t width, size_t height, State defaultState)
@ -66,16 +77,21 @@ bool GOLTeamH::setRule(std::string const& rule)
std::bitset<9> parsedRuleRevive, parsedRuleSurvive; std::bitset<9> parsedRuleRevive, parsedRuleSurvive;
// On vérifie que la chaine de charactères contient un B au début. // On vérifie que la chaine de charactères contient un B au début.
// 5 = chaine minimale // 5 = taille minimale
if (rule.size() < 5 || !(rule[0] == 'B' || rule[0] == 'b')) if (rule.size() < 5 || !(rule[0] == 'B' || rule[0] == 'b'))
return false; return false;
for (size_t i{ 1 }; i < rule.length(); i++) { for (size_t i{ 1 }; i < rule.length(); i++) {
// On utilise std::optional comme levier pour vérifier si un char est un nombre.
auto opt = convertCharToNumber(rule[i]); auto opt = convertCharToNumber(rule[i]);
// Si c'est un chiffre, on continue. // Si c'est un chiffre, on continue en enregistrant la valeur.
if (opt.has_value()) { if (opt.has_value()) {
firstPart ? parsedRuleRevive.set(opt.value()) : parsedRuleSurvive.set(opt.value()); if (firstPart)
parsedRuleRevive.set(opt.value());
else
parsedRuleSurvive.set(opt.value());
continue; continue;
} }
@ -86,10 +102,11 @@ bool GOLTeamH::setRule(std::string const& rule)
firstPart = false; firstPart = false;
continue; continue;
} }
else // Aucun slash + s else // Aucun slash + s, alors pas bon.
return false; return false;
} }
// Si les les deux règles ont au moins un nombre, alors OK.
if (parsedRuleRevive.any() && parsedRuleSurvive.any()) { if (parsedRuleRevive.any() && parsedRuleSurvive.any()) {
mParsedRuleRevive = parsedRuleRevive; mParsedRuleRevive = parsedRuleRevive;
mParsedRuleSurvive = parsedRuleSurvive; mParsedRuleSurvive = parsedRuleSurvive;
@ -102,39 +119,53 @@ bool GOLTeamH::setRule(std::string const& rule)
void GOLTeamH::setBorderManagement(BorderManagement borderManagement) void GOLTeamH::setBorderManagement(BorderManagement borderManagement)
{ {
mBorderManagement = borderManagement; mBorderManagement = borderManagement;
mIteration = 0;
} }
void GOLTeamH::setState(int x, int y, State state) void GOLTeamH::setState(int x, int y, State state)
{ {
mData.setAt(x, y, state); mData.setAt(x, y, state);
mIteration = 0;
} }
void GOLTeamH::fill(State state) void GOLTeamH::fill(State state)
{ {
mData.resize(mData.width(), mData.height(), state); mData.fill(state);
mIteration = 0;
} }
void GOLTeamH::fillAlternately(State firstCell) void GOLTeamH::fillAlternately(State firstCell)
{ {
mData.fillAternately(firstCell);
mIteration = 0;
} }
void GOLTeamH::randomize(double percentAlive) void GOLTeamH::randomize(double percentAlive)
{ {
mData.randomize(percentAlive);
mIteration = 0;
} }
// TODO
bool GOLTeamH::setFromPattern(std::string const& pattern, int centerX, int centerY) bool GOLTeamH::setFromPattern(std::string const& pattern, int centerX, int centerY)
{ {
mIteration = 0;
return false; return false;
} }
// TODO
bool GOLTeamH::setFromPattern(std::string const& pattern) bool GOLTeamH::setFromPattern(std::string const& pattern)
{ {
mIteration = 0;
return false; return false;
} }
void GOLTeamH::setSolidColor(State state, Color const& color) void GOLTeamH::setSolidColor(State state, Color const& color)
{ {
if (state == State::dead)
mDeadColor = color;
else
mAliveColor = color;
} }
void GOLTeamH::processOneStep() void GOLTeamH::processOneStep()

View File

@ -32,6 +32,7 @@ public:
void setSolidColor(State state, Color const& color) override; void setSolidColor(State state, Color const& color) override;
void processOneStep() override; void processOneStep() override;
void updateImage(uint32_t* buffer, size_t buffer_size) const override; void updateImage(uint32_t* buffer, size_t buffer_size) const override;
private: private:
std::optional<std::string> mRule; std::optional<std::string> mRule;
std::optional<GOL::BorderManagement> mBorderManagement; std::optional<GOL::BorderManagement> mBorderManagement;

View File

@ -7,6 +7,7 @@ Grid::Grid()
} }
Grid::Grid(size_t width, size_t height, CellType initValue) Grid::Grid(size_t width, size_t height, CellType initValue)
:mWidth{ width }, mHeight{ height }, mEngine(mRandomDevice), mDistribution(0.0, 1.0)
{ {
resize(width, height, initValue); resize(width, height, initValue);
} }
@ -37,9 +38,13 @@ size_t Grid::size() const
// Mutateur modifiant la taille de la grille et initialise le contenu par la valeur spécifiée. // Mutateur modifiant la taille de la grille et initialise le contenu par la valeur spécifiée.
void Grid::resize(size_t width, size_t height, CellType initValue) void Grid::resize(size_t width, size_t height, CellType initValue)
{ {
mData.reserve(width * height); // TODO: Performance de resize avec beaucoup d'appel?
// Investiguer reserve + resize
mData.resize(width * height);
mWidth = width; mWidth = width;
mHeight = height; mHeight = height;
fill(initValue);
} }
// Accesseur retournant la valeur d'une cellule à une certaine coordonnée. // Accesseur retournant la valeur d'une cellule à une certaine coordonnée.
@ -82,9 +87,45 @@ Grid::DataType& Grid::data()
return mData; return mData;
} }
// TODO // https://en.cppreference.com/w/cpp/algorithm/count
Grid::DataType Grid::totalDead() size_t Grid::totalDead() const
{ {
return DataType(); return std::count_if(mData.begin(), mData.end(), [](auto& i) { return i == CellType::dead; });
}
float Grid::totalDeadRel() const
{
return static_cast<float>(totalDead()) / static_cast<float>(size());
}
size_t Grid::totalAlive() const
{
return std::count_if(mData.begin(), mData.end(), [](auto& i) { return i == CellType::alive; });
}
float Grid::totalAliveRel() const
{
return static_cast<float>(totalAlive()) / static_cast<float>(size());
}
void Grid::fill(CellType value)
{
for (auto& i : mData)
i = value;
}
void Grid::fillAternately(CellType initValue)
{
auto otherValue = (initValue == CellType::alive) ? CellType::dead : CellType::alive;
for (size_t i{}; i < mData.size(); i++)
mData[i] = !(i % 2) ? initValue : otherValue;
}
void Grid::randomize(double percentAlive)
{
for (auto& i : mData) {
if (mDistribution(mEngine) < percentAlive)
i = CellType::alive;
}
} }

View File

@ -1,6 +1,8 @@
#pragma once #pragma once
#include <algorithm>
#include <vector> #include <vector>
#include <random>
#include "GOL.h" #include "GOL.h"
class Grid // Classe facilitant la gestion d'un tableau dynamique 2d. class Grid // Classe facilitant la gestion d'un tableau dynamique 2d.
@ -37,8 +39,22 @@ public: //
DataType const& data() const; // Accesseur en lecture seule sur le "buffer" de la grille. DataType const& data() const; // Accesseur en lecture seule sur le "buffer" de la grille.
DataType& data(); // Accesseur en lecture/écriture sur le "buffer" de la grille. DataType& data(); // Accesseur en lecture/écriture sur le "buffer" de la grille.
DataType totalDead(); size_t totalDead() const;
float totalDeadRel() const;
size_t totalAlive() const;
float totalAliveRel() const;
void fill(CellType value);
void fillAternately(CellType initValue);
void randomize(double percentAlive);
private: // private: //
DataType mData; // Il y a des attributs essentiels au fonctionnement de cette classe. DataType mData; // Il y a des attributs essentiels au fonctionnement de cette classe.
size_t mWidth, mHeight; // À vous de les déterminer. size_t mWidth, mHeight; // À vous de les déterminer.
// Random
std::random_device mRandomDevice;
std::mt19937 mEngine;
std::uniform_real_distribution<> mDistribution;
}; };

View File

@ -1,26 +1,14 @@
#include <QtWidgets/QApplication> #include <QtWidgets/QApplication>
#include "GOLApp.h" #include "GOLApp.h"
#include "GOLTeamH.h"
//TEST DE COMMIT
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
QApplication application(argc, argv); QApplication application(argc, argv);
GOLApp window; GOLApp window;
window.addEngine(new GOLTeamH());
//
// Ajouter votre implémentation ici.
// Évidemment, n'oubliez pas de faire l'inclusion du fichier contenant
// votre classe.
//
// Par exemple :
//
// window.addEngine(new MonImplementationGOL);
//
window.show(); window.show();
return application.exec(); return application.exec();