Fix le parsing de patterns et simplifications

This commit is contained in:
Timothée Leclaire-Fournier 2024-01-25 19:41:34 -05:00
parent 6443a16549
commit baf6addabd
2 changed files with 85 additions and 98 deletions

View File

@ -323,58 +323,15 @@ void GOLTeamH::randomize(double percentAlive)
// TODO // TODO
bool GOLTeamH::setFromPattern(std::string const& pattern, int centerX, int centerY) bool GOLTeamH::setFromPattern(std::string const& pattern, int centerX, int centerY)
{ {
// Analyse du pattern auto sq = parsePattern(pattern);
size_t pos = 0;
// Vérification du '[' initial if (!sq.has_value())
if (pattern[pos++] != '[') {
std::cerr << "Erreur de format : '[' manquant." << std::endl;
return false; return false;
}
// Lecture de la largeur fillDataFromPattern(pattern, sq.value(), centerX, centerY);
size_t width = std::stoi(pattern.substr(pos), &pos);
if (width <= 0) {
std::cerr << "Erreur de format : Largeur invalide." << std::endl;
return false;
}
// Vérification du 'x'
if (pattern[pos++] != 'x') {
std::cerr << "Erreur de format : 'x' manquant." << std::endl;
return false;
}
// Lecture de la hauteur
size_t height = std::stoi(pattern.substr(pos), &pos);
if (height <= 0) {
std::cerr << "Erreur de format : Hauteur invalide." << std::endl;
return false;
}
// Vérification du ']'
if (pattern[pos++] != ']') {
std::cerr << "Erreur de format : ']' manquant." << std::endl;
return false;
}
// 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 false;
}
// Remplissage de la grille aux positions spécifiées par le patron
for (size_t y = 0; y < height; ++y) {
for (size_t x = 0; x < width; ++x) {
char cellChar = pattern[pos++];
State cellState = (cellChar == '0') ? State::dead : State::alive;
mData.setAt(centerX + x, centerY + y, cellState);
}
}
return true;
mIteration = 0; mIteration = 0;
return true;
} }
//! \brief Mutateur remplissant la grille par le patron passé en argument. //! \brief Mutateur remplissant la grille par le patron passé en argument.
@ -388,59 +345,20 @@ bool GOLTeamH::setFromPattern(std::string const& pattern, int centerX, int cente
//! \param pattern Le patron à appliquer. //! \param pattern Le patron à appliquer.
//! \return true si le patron est valide, false sinon. //! \return true si le patron est valide, false sinon.
// TODO
bool GOLTeamH::setFromPattern(std::string const& pattern) bool GOLTeamH::setFromPattern(std::string const& pattern)
{ {
// Analyse du pattern auto sq = parsePattern(pattern);
size_t pos = 0;
// Vérification du '[' initial if (!sq.has_value())
if (static_cast<char>(pattern[pos++]) != '[') {
std::cerr << "Erreur de format : '[' manquant." << std::endl;
return false; return false;
}
// Lecture de la largeur size_t centerX = mData.width() / 2 - (sq.value().width / 2);
size_t width = std::stoi(pattern.substr(pos), &pos); size_t centerY = mData.height() / 2 - (sq.value().height / 2);
if (width <= 0) {
std::cerr << "Erreur de format : Largeur invalide." << std::endl;
return false;
}
pos++;
if (pattern[pos++] != 120 ) {
std::cerr << "Erreur de format : 'x' manquant." << std::endl;
return false;
}
// Lecture de la hauteur
size_t height = std::stoi(pattern.substr(pos), &pos);
pos = pos + 4;
if (height <= 0) {
std::cerr << "Erreur de format : Hauteur invalide." << std::endl;
return false;
}
// Vérification du ']'
if (static_cast<char>(pattern[pos++]) != ']') {
std::cerr << "Erreur de format : ']' manquant." << std::endl;
return false;
}
pos++;
size_t centerX = mData.width() / 2 - width/2;
size_t centerY = mData.height() / 2 - height/2;
// Remplissage de la grille aux positions spécifiées par le patron fillDataFromPattern(pattern, sq.value(), centerX, centerY);
for (size_t y = 0; y < height; ++y) {
for (size_t x = 0; x < width; ++x) {
char cellChar = pattern[pos++];
mData.setAt(centerX + x, centerY + y, State::dead);
State cellState = (cellChar == '0') ? State::dead : State::alive;
mData.setAt(centerX + x, centerY + y, cellState);
}
}
return true;
mIteration = 0; mIteration = 0;
return true;
} }
//! \brief Mutateur modifiant la couleur d'un état. //! \brief Mutateur modifiant la couleur d'un état.
@ -623,3 +541,65 @@ std::optional<unsigned char> GOLTeamH::convertCharToNumber(const char c)
return (c - 48); return (c - 48);
} }
std::optional<GOLTeamH::sizeQueried> GOLTeamH::parsePattern(std::string const& pattern)
{
// Analyse du pattern
size_t pos{}, processedNumbers{};
// 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,
int centerX, int centerY)
{
// Remplissage de la grille aux positions spécifiées par le patron
for (size_t y = 0; y < sq.height; ++y) {
for (size_t x = 0; x < sq.width; ++x) {
State cellState = (pattern[sq.pos++] == '0') ? State::dead : State::alive;
mData.setAt(centerX + x, centerY + y, cellState);
}
}
}

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#ifndef GOLTEAMH_H #ifndef GOLTEAMH_H
#define GOLTEAMH_H #define GOLTEAMH_H
#include <string> #include <string>
#include <optional> #include <optional>
@ -45,17 +45,21 @@ constexpr unsigned char MAX_ALPHA = 255;
class GOLTeamH : public GOL class GOLTeamH : public GOL
{ {
public: public:
struct sizeQueried {
size_t width, height, pos;
};
// - le constructeur par défaut : _class_() // - le constructeur par défaut : _class_()
// - le constructeur d'initialisation proposé : _class_(size_t width, size_t height, State defaultState = State::dead) // - le constructeur d'initialisation proposé : _class_(size_t width, size_t height, State defaultState = State::dead)
// - le destructeur : ~_class_() // - le destructeur : ~_class_()
GOLTeamH(); GOLTeamH();
GOLTeamH(GOLTeamH const &) = delete; GOLTeamH(GOLTeamH const&) = delete;
GOLTeamH(GOLTeamH &&) = delete; GOLTeamH(GOLTeamH&&) = delete;
GOLTeamH& operator =(GOLTeamH const &) = delete; GOLTeamH& operator =(GOLTeamH const&) = delete;
GOLTeamH& operator =(GOLTeamH&&) = delete; GOLTeamH& operator =(GOLTeamH&&) = delete;
virtual ~GOLTeamH()=default; virtual ~GOLTeamH() = default;
// inline puisque trivial. // inline puisque trivial.
size_t width() const override { return mData.width(); } size_t width() const override { return mData.width(); }
size_t height() const override { return mData.height(); } size_t height() const override { return mData.height(); }
@ -107,6 +111,9 @@ private:
// Fonctions utilisées à l'interne. // Fonctions utilisées à l'interne.
std::optional<unsigned char> convertCharToNumber(const char c); std::optional<unsigned char> convertCharToNumber(const char c);
std::optional<sizeQueried> parsePattern(std::string const& pattern);
void fillDataFromPattern(std::string const& pattern, sizeQueried& sq,
int centerX, int centerY);
}; };
#endif GOLTEAMH_H #endif GOLTEAMH_H