Retire des std::move implicite et simplifie le parsing avec regex

This commit is contained in:
Timothée Leclaire-Fournier 2024-01-29 21:02:37 -05:00
parent a4764cd225
commit 071e24b122
2 changed files with 31 additions and 94 deletions

View File

@ -34,7 +34,7 @@ GOLTeamH::GOLTeamH()
//! \return Une structure contenant les informations sur la simulation. //! \return Une structure contenant les informations sur la simulation.
GOL::Statistics GOLTeamH::statistics() const GOL::Statistics GOLTeamH::statistics() const
{ {
return std::move(GOL::Statistics{ return GOL::Statistics{
.rule = mRule, .rule = mRule,
.borderManagement = mBorderManagement, .borderManagement = mBorderManagement,
.width = width(), .width = width(),
@ -47,7 +47,7 @@ GOL::Statistics GOLTeamH::statistics() const
.totalAliveRel = mData.totalAliveRel(), .totalAliveRel = mData.totalAliveRel(),
.tendencyAbs = mData.tendencyAbs(), .tendencyAbs = mData.tendencyAbs(),
.tendencyRel = mData.tendencyRel() .tendencyRel = mData.tendencyRel()
}); };
} }
//! \brief Accesseurs retournant les informations sur la réalisation //! \brief Accesseurs retournant les informations sur la réalisation
@ -70,14 +70,14 @@ GOL::Statistics GOLTeamH::statistics() const
//! //!
GOL::ImplementationInformation GOLTeamH::information() const GOL::ImplementationInformation GOLTeamH::information() const
{ {
return std::move(ImplementationInformation{ return ImplementationInformation{
.title{"Laboratoire 1"}, .title{"Laboratoire 1"},
.authors{{"Timothée Leclaire-Fournier timothee.leclaire-fournier.1@ens.etsmtl.ca"}, .authors{{"Timothée Leclaire-Fournier timothee.leclaire-fournier.1@ens.etsmtl.ca"},
{"Martin Euzenat martin.euzenat.1@ens.etsmtl.ca"}}, {"Martin Euzenat martin.euzenat.1@ens.etsmtl.ca"}},
.answers{}, .answers{},
.optionnalComments{} .optionnalComments{}
// Réponses aux questions... // Réponses aux questions...
}); };
} }
@ -110,7 +110,7 @@ void GOLTeamH::resize(size_t width, size_t height, State defaultState)
//! et assigne la nouvelle règle pour que les prochaines évolutions //! et assigne la nouvelle règle pour que les prochaines évolutions
//! l'utilisent. //! l'utilisent.
//! //!
//! Si la règle est valide, on assigne la novuelle règle, l'ancienne règle //! Si la règle est valide, on assigne la nouvelle règle, l'ancienne règle
//! est perdue et l'itération courante est remise à 0. Si la règle est //! est perdue et l'itération courante est remise à 0. Si la règle est
//! invalide, on ne fait rien. //! invalide, on ne fait rien.
//! //!
@ -145,43 +145,20 @@ void GOLTeamH::resize(size_t width, size_t height, State defaultState)
bool GOLTeamH::setRule(std::string const& rule) bool GOLTeamH::setRule(std::string const& rule)
{ {
mRule = rule; mParsedRule = 0;
bool firstPart{ true }; std::regex regexp(R"(B(\d+)/S(\d+))");
uint32_t parsedRule{}; std::smatch m;
// On vérifie que la chaine de charactères contient un B au début. if (std::regex_search(rule, m, regexp)) {
// 5 = taille minimale for (auto& i : m[1].str())
if (rule.size() < 3 || !(rule[0] == 'B' || rule[0] == 'b')) mParsedRule |= 1u << convertCharToNumber(i);
return false;
for (size_t i{ 1 }; i < rule.length(); i++) { for (auto& i : m[2].str())
// On utilise std::optional comme levier pour vérifier si un char est un nombre. mParsedRule |= 1u << (convertCharToNumber(i) + 16);
auto opt = convertCharToNumber(rule[i]);
// Si c'est un chiffre, on continue en enregistrant la valeur. return true;
if (opt.has_value()) {
if (firstPart)
parsedRule |= 1u << opt.value();
else
parsedRule |= 1u << (opt.value() + 16);
continue;
}
// S'il n'y a pas de chiffre, on vérifie qu'il y ait
// un backslash avec un S après.
if (firstPart && rule[i] == '/' && rule.size() > i + 1
&& (rule[i + 1] == 'S' || rule[i + 1] == 's')) {
i++; // On saute le S
firstPart = false; // Deuxième partie
continue;
}
else // Aucun slash + s, alors pas bon.
return false;
} }
return false;
mParsedRule |= parsedRule;
return true;
} }
//! \brief Mutateur modifiant la stratégie de gestion de bord. //! \brief Mutateur modifiant la stratégie de gestion de bord.
@ -301,7 +278,7 @@ void GOLTeamH::fillAlternately(State firstCell)
void GOLTeamH::randomize(double percentAlive) void GOLTeamH::randomize(double percentAlive)
{ {
mData.randomize(percentAlive, mBorderManagement == GOL::BorderManagement::immutableAsIs); mData.randomize(percentAlive, mBorderManagement == GOL::BorderManagement::immutableAsIs);
modifyBorderIfNecessary(reinterpret_cast<uint8_t *>(mData.data()), modifyBorderIfNecessary(reinterpret_cast<uint8_t*>(mData.data()),
reinterpret_cast<uint8_t*>(mData.intData())); reinterpret_cast<uint8_t*>(mData.intData()));
mIteration = 0; mIteration = 0;
countLifeStatusCells(); countLifeStatusCells();
@ -543,64 +520,22 @@ void GOLTeamH::updateImage(uint32_t* buffer, size_t buffer_size) const
ptrGrid = nullptr; ptrGrid = nullptr;
} }
std::optional<unsigned char> GOLTeamH::convertCharToNumber(const char c) unsigned char GOLTeamH::convertCharToNumber(const char c)
{ {
if (c < 48 || c > 57)
return std::nullopt;
return (c - 48); return (c - 48);
} }
std::optional<GOLTeamH::sizeQueried> GOLTeamH::parsePattern(std::string const& pattern) std::optional<GOLTeamH::sizeQueried> GOLTeamH::parsePattern(std::string const& pattern)
{ {
// Analyse du pattern // \[ -> on match le caractère [
size_t pos{}, processedNumbers{}; // (\d+) -> on match plusieurs caractères de 0-9
if (pattern.size() < 6) std::regex regexp(R"(\[(\d+)x(\d+)\](\d+))");
std::smatch m;
if (std::regex_search(pattern, m, regexp))
return GOLTeamH::sizeQueried{ .width = std::stoull(m[1]), .height = std::stoull(m[2]), .pos = m[3] };
else
return std::nullopt; return std::nullopt;
// Vérification du '[' initial
if (pattern[pos++] != '[') {
std::cerr << "Erreur de format : '[' manquant." << std::endl;
return std::nullopt;
}
// Lecture de la largeur
size_t width = std::stoi(pattern.substr(pos), &processedNumbers);
pos += processedNumbers;
if (width <= 0) {
std::cerr << "Erreur de format : Largeur invalide." << std::endl;
return std::nullopt;
}
// Vérification du 'x'
if (pattern[pos++] != 'x') {
std::cerr << "Erreur de format : 'x' manquant." << std::endl;
return std::nullopt;
}
// Lecture de la hauteur
size_t height = std::stoi(pattern.substr(pos), &processedNumbers);
pos += processedNumbers;
if (height <= 0) {
std::cerr << "Erreur de format : Hauteur invalide." << std::endl;
return std::nullopt;
}
// Vérification du ']'
if (pattern[pos++] != ']') {
std::cerr << "Erreur de format : ']' manquant." << std::endl;
return std::nullopt;
}
// Vérification de la taille du reste du pattern
if (pattern.length() - pos != width * height) {
std::cerr << "Erreur de format : Taille du patron incorrecte." << std::endl;
return std::nullopt;
}
return std::move(GOLTeamH::sizeQueried{ .width = width, .height = height, .pos = pos });
} }
void GOLTeamH::fillDataFromPattern(std::string const& pattern, sizeQueried& sq, void GOLTeamH::fillDataFromPattern(std::string const& pattern, sizeQueried& sq,
@ -610,7 +545,7 @@ void GOLTeamH::fillDataFromPattern(std::string const& pattern, sizeQueried& sq,
for (size_t y = 0; y < sq.height; ++y) { for (size_t y = 0; y < sq.height; ++y) {
for (size_t x = 0; x < sq.width; ++x) { for (size_t x = 0; x < sq.width; ++x) {
// TODO: Check si in bounds et vérifie que ça répare le problème de quand on ferme, erreur. // TODO: Check si in bounds et vérifie que ça répare le problème de quand on ferme, erreur.
State cellState = (pattern[sq.pos++] == '0') ? State::dead : State::alive; State cellState = (sq.pos[(y * sq.width) + x] == '0') ? State::dead : State::alive;
mData.setAt(centerX + x, centerY + y, cellState); mData.setAt(centerX + x, centerY + y, cellState);
} }
} }

View File

@ -4,6 +4,7 @@
#include <iostream> #include <iostream>
#include <regex>
#include <string> #include <string>
#include <optional> #include <optional>
@ -28,7 +29,8 @@ class GOLTeamH : public GOL
{ {
public: public:
struct sizeQueried { struct sizeQueried {
size_t width, height, pos; size_t width, height;
std::string pos;
}; };
GOLTeamH(); GOLTeamH();
@ -89,7 +91,7 @@ private:
uint64_t mColorEncoded; uint64_t mColorEncoded;
// Fonctions utilisées à l'interne. // Fonctions utilisées à l'interne.
std::optional<unsigned char> convertCharToNumber(const char c); unsigned char convertCharToNumber(const char c);
std::optional<sizeQueried> parsePattern(std::string const& pattern); std::optional<sizeQueried> parsePattern(std::string const& pattern);
void fillDataFromPattern(std::string const& pattern, sizeQueried& sq, void fillDataFromPattern(std::string const& pattern, sizeQueried& sq,
int centerX, int centerY); int centerX, int centerY);