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
bool GOLTeamH::setFromPattern(std::string const& pattern, int centerX, int centerY)
{
// Analyse du pattern
size_t pos = 0;
auto sq = parsePattern(pattern);
// Vérification du '[' initial
if (pattern[pos++] != '[') {
std::cerr << "Erreur de format : '[' manquant." << std::endl;
if (!sq.has_value())
return false;
}
// Lecture de la largeur
size_t width = std::stoi(pattern.substr(pos), &pos);
if (width <= 0) {
std::cerr << "Erreur de format : Largeur invalide." << std::endl;
return false;
}
fillDataFromPattern(pattern, sq.value(), centerX, centerY);
// 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;
return true;
}
//! \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.
//! \return true si le patron est valide, false sinon.
// TODO
bool GOLTeamH::setFromPattern(std::string const& pattern)
{
// Analyse du pattern
size_t pos = 0;
auto sq = parsePattern(pattern);
// Vérification du '[' initial
if (static_cast<char>(pattern[pos++]) != '[') {
std::cerr << "Erreur de format : '[' manquant." << std::endl;
if (!sq.has_value())
return false;
}
// Lecture de la largeur
size_t width = std::stoi(pattern.substr(pos), &pos);
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;
}
size_t centerX = mData.width() / 2 - (sq.value().width / 2);
size_t centerY = mData.height() / 2 - (sq.value().height / 2);
// Vérification du ']'
if (static_cast<char>(pattern[pos++]) != ']') {
std::cerr << "Erreur de format : ']' manquant." << std::endl;
return false;
}
pos++;
fillDataFromPattern(pattern, sq.value(), centerX, centerY);
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
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;
return true;
}
//! \brief Mutateur modifiant la couleur d'un état.
@ -623,3 +541,65 @@ std::optional<unsigned char> GOLTeamH::convertCharToNumber(const char c)
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

@ -45,16 +45,20 @@ constexpr unsigned char MAX_ALPHA = 255;
class GOLTeamH : public GOL
{
public:
struct sizeQueried {
size_t width, height, pos;
};
// - le constructeur par défaut : _class_()
// - le constructeur d'initialisation proposé : _class_(size_t width, size_t height, State defaultState = State::dead)
// - le destructeur : ~_class_()
GOLTeamH();
GOLTeamH(GOLTeamH const &) = delete;
GOLTeamH(GOLTeamH &&) = delete;
GOLTeamH& operator =(GOLTeamH const &) = delete;
GOLTeamH(GOLTeamH const&) = delete;
GOLTeamH(GOLTeamH&&) = delete;
GOLTeamH& operator =(GOLTeamH const&) = delete;
GOLTeamH& operator =(GOLTeamH&&) = delete;
virtual ~GOLTeamH()=default;
virtual ~GOLTeamH() = default;
// inline puisque trivial.
size_t width() const override { return mData.width(); }
@ -107,6 +111,9 @@ private:
// Fonctions utilisées à l'interne.
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