diff --git a/include/neighborhood_rules/mooreNeighborhoodRule.hpp b/include/neighborhood_rules/mooreNeighborhoodRule.hpp index daba76f4984e6099dcc76fd9e3a9977dd83ecf32..7e575049891ad14446e9cbd81f8f72caf72310a6 100644 --- a/include/neighborhood_rules/mooreNeighborhoodRule.hpp +++ b/include/neighborhood_rules/mooreNeighborhoodRule.hpp @@ -17,7 +17,8 @@ Contient la classe de la règle de Moore (semblable à VonNeumann avec les diago //! \brief Voisinage de Moore. class mooreNeighborhoodRule : public NeighborhoodRule { - NeighborhoodFormat format; + mutable NeighborhoodFormat format; + mutable int current_format_radius; public: mooreNeighborhoodRule(int _radius = 1); @@ -29,6 +30,9 @@ public: //! \return Retourne les formats de voisinage possible dans un std::vector. std::vector<NeighborhoodFormat> getFormats() const; +private: + void update_format() const; + private: //! \brief Rayon du voisinage (en nombre de cellule) DEFINE_CONFIGURABLE_PROPERTY(IntegerProperty, radius, "Radius", 1); diff --git a/include/neighborhood_rules/vonNeumannNeighborhoodRule.hpp b/include/neighborhood_rules/vonNeumannNeighborhoodRule.hpp index 4dad492df20d0d1596eed2c2a01833bc933205ae..8caed011c30b2f1c398665f34f18a6ad83b8eb71 100644 --- a/include/neighborhood_rules/vonNeumannNeighborhoodRule.hpp +++ b/include/neighborhood_rules/vonNeumannNeighborhoodRule.hpp @@ -17,7 +17,8 @@ Contient la classe de la règle de Von Neumann. //! \brief Voisinage de Von Neumann. class vonNeumannNeighborhoodRule : public NeighborhoodRule { - NeighborhoodFormat format; + mutable NeighborhoodFormat format; + mutable int current_format_radius; public: vonNeumannNeighborhoodRule(int _radius = 1); @@ -29,6 +30,9 @@ public: //! \return Retourne les formats de voisinage possible dans un std::vector. std::vector<NeighborhoodFormat> getFormats() const; +private: + void update_format() const; + private: //! \brief Rayon du voisinage (en nombre de cellule) DEFINE_CONFIGURABLE_PROPERTY(IntegerProperty, radius, "Radius", 1); diff --git a/src/neighborhood_rules/mooreNeighborhoodRule.cpp b/src/neighborhood_rules/mooreNeighborhoodRule.cpp index 35fe0f16ee885e819656bbd7c2eef05d02848c59..c894c7aa18bed5ec2cac947c9090b004daac4ead 100644 --- a/src/neighborhood_rules/mooreNeighborhoodRule.cpp +++ b/src/neighborhood_rules/mooreNeighborhoodRule.cpp @@ -4,26 +4,19 @@ REGISTER_FACTORY_ENTRY(NeighborhoodRule, mooreNeighborhoodRule, "Moore"); mooreNeighborhoodRule::mooreNeighborhoodRule(int _radius) { - radius.val = _radius; + current_format_radius = radius.val = _radius; if(_radius == 0) throw NeighborhoodException("Le rayon ne peut pas être égal à 0"); - // Les coordonnées sont copiées dans le vecteur - // N(i,j) = {(k, l)|abs(k−i) ≤ r et abs(l−j) ≤ r} ; - Coord newCord; - for(int i = -_radius; i <= _radius; i++){ - for(int j = -_radius; j <= _radius; j++){ - newCord.x = i; - newCord.y = j; - if(!(newCord.x == 0 && newCord.y == 0)) { - format.positions.push_back(newCord); - } - } - } + + update_format(); } Neighborhood mooreNeighborhoodRule::getNeighborhood(const Grid& grid, Coord pos) const { + if (current_format_radius != radius.val) + update_format(); + Neighborhood newNeighborhood; // Coordonnées des voisins dans la grille Coord gridCoord; @@ -40,8 +33,31 @@ Neighborhood mooreNeighborhoodRule::getNeighborhood(const Grid& grid, Coord pos) std::vector<NeighborhoodFormat> mooreNeighborhoodRule::getFormats() const { + if (current_format_radius != radius.val) + update_format(); + std::vector<NeighborhoodFormat> vector; vector.push_back(format); return vector; } +void mooreNeighborhoodRule::update_format() const +{ + format.positions.clear(); + + // Les coordonnées sont copiées dans le vecteur + // N(i,j) = {(k, l)|abs(k−i) ≤ r et abs(l−j) ≤ r} ; + Coord newCord; + for(int i = -radius.val; i <= radius.val; i++){ + for(int j = -radius.val; j <= radius.val; j++){ + newCord.x = i; + newCord.y = j; + if(!(newCord.x == 0 && newCord.y == 0)) { + format.positions.push_back(newCord); + } + } + } + + current_format_radius = radius.val; +} + diff --git a/src/neighborhood_rules/vonNeumannNeighborhoodRule.cpp b/src/neighborhood_rules/vonNeumannNeighborhoodRule.cpp index a3cb5077562b0c007fa8be419c55cc89eeac0399..2fbe3e5e7f45eb3a4ebe600d8182c204cfcfc67e 100644 --- a/src/neighborhood_rules/vonNeumannNeighborhoodRule.cpp +++ b/src/neighborhood_rules/vonNeumannNeighborhoodRule.cpp @@ -4,29 +4,19 @@ REGISTER_FACTORY_ENTRY(NeighborhoodRule, vonNeumannNeighborhoodRule, "Von Neuman vonNeumannNeighborhoodRule::vonNeumannNeighborhoodRule(int _radius) { - radius.val = _radius; + current_format_radius = radius.val = _radius; if(_radius == 0) throw NeighborhoodException("Le rayon ne peut pas être égal à 0"); - // Les coordonnées sont copiées dans le vecteur - // J'ai repris l'implémentation du voisinage de Moore, sauf que les cellules qui ne respectent pas la formule sont exclues - // N(i,j) = {(k, l)|abs(k − i) + abs(l − j) ≤ r} - Coord newCord; - for(int i = -_radius; i <= _radius; i++){ - for(int j = -_radius; j <= _radius; j++){ - if((abs(i) + abs(j)) <= _radius) { - newCord.x = i; - newCord.y = j; - if(!(newCord.x == 0 && newCord.y == 0)) { - format.positions.push_back(newCord); - } - } - } - } + + update_format(); } Neighborhood vonNeumannNeighborhoodRule::getNeighborhood(const Grid& grid, Coord pos) const { + if (current_format_radius != radius.val) + update_format(); + Neighborhood newNeighborhood; // Coordonnées des voisins dans la grille Coord gridCoord; @@ -43,8 +33,30 @@ Neighborhood vonNeumannNeighborhoodRule::getNeighborhood(const Grid& grid, Coord std::vector<NeighborhoodFormat> vonNeumannNeighborhoodRule::getFormats() const { + if (current_format_radius != radius.val) + update_format(); + std::vector<NeighborhoodFormat> vector; vector.push_back(format); return vector; } +void vonNeumannNeighborhoodRule::update_format() const +{ + // Les coordonnées sont copiées dans le vecteur + // J'ai repris l'implémentation du voisinage de Moore, sauf que les cellules qui ne respectent pas la formule sont exclues + // N(i,j) = {(k, l)|abs(k − i) + abs(l − j) ≤ r} + Coord newCord; + for(int i = -radius.val; i <= radius.val; i++){ + for(int j = -radius.val; j <= radius.val; j++){ + if((abs(i) + abs(j)) <= radius.val) { + newCord.x = i; + newCord.y = j; + if(!(newCord.x == 0 && newCord.y == 0)) { + format.positions.push_back(newCord); + } + } + } + } +} + diff --git a/src/structurereader.cpp b/src/structurereader.cpp index 20338b4b52e5e41bec4afbec49a68070c9c7fc2b..9420418a99f5f935341044cbc5341a7012b60eca 100644 --- a/src/structurereader.cpp +++ b/src/structurereader.cpp @@ -111,7 +111,7 @@ void StructureReader::read_white() unsigned RLEStructureReader::read_state() { char char_1 = read(); - if (char_1 == 'b' || char_1 == 'B' || char_1 == '.') + if (char_1 == 'b' || char_1 == '.') return 0; else if (char_1 == 'o') return 1; @@ -130,6 +130,7 @@ unsigned RLEStructureReader::read_state() void RLEStructureReader::read_comment_line(Structure &s) { std::string tag = read_word(); + read_white(); std::string line = read_line(); if (tag == "C" || tag == "c") { diff --git a/tests/mooreNeighborhoodRule_test.cpp b/tests/mooreNeighborhoodRule_test.cpp index 9dd3ff7ac8ec374fc7adaec599612cae517d2379..7e528f683d63f85021d50f96c3e3f92357e7f34c 100644 --- a/tests/mooreNeighborhoodRule_test.cpp +++ b/tests/mooreNeighborhoodRule_test.cpp @@ -3,6 +3,7 @@ #include "cellulut_tests.hpp" #include "mooreNeighborhoodRule.hpp" +#include "propertyvisitors.hpp" void CellulutTests::test_mooreNeighborhoodRule() { @@ -19,7 +20,7 @@ void CellulutTests::test_mooreNeighborhoodRule() { Coord pos8={5,3}; Coord pos9={3,5}; Coord pos10={7,7}; - Coord pos11={4,4}; + Coord pos11={4,3}; Coord pos12={6,7}; Coord pos13={7,6}; Coord pos14={3,6}; @@ -41,10 +42,15 @@ void CellulutTests::test_mooreNeighborhoodRule() { g.set_cell(pos13,4); g.set_cell(pos14,2); + // Tester que le chargement des propriétés depuis un JSON fonctionne bien + QJsonObject obj; + obj["radius"] = 2; + mooreNeighborhoodRule newMoore(1); + PropertyLoaderVisitor visit(obj); + for (auto& prop : newMoore.get_properties()) + prop->accept(visit); - - mooreNeighborhoodRule newMoore(2); Neighborhood v=newMoore.getNeighborhood(g,cellule); unsigned int nb_voi=v.getNb(3); unsigned int nb_voi2=v.getNb(5); diff --git a/tests/structurewriter_tests.cpp b/tests/structurewriter_tests.cpp index 295f8903522a3e767ec45c991be1a312d5ad80cd..32e38662d929aa8871e3693d439316e98a52d365 100644 --- a/tests/structurewriter_tests.cpp +++ b/tests/structurewriter_tests.cpp @@ -54,6 +54,42 @@ void CellulutTests::test_rle_structurewriter() fprintf(stderr, "Error is %s\n", ex.what()); QFAIL("Exception thrown"); } + + std::vector<std::pair<Coord, unsigned>> coords; + coords.push_back({{0, 0}, 3}); + coords.push_back({{1, 2}, 1}); + coords.push_back({{5, 8}, 5}); + coords.push_back({{1, 3}, 2}); + coords.push_back({{5, 6}, 6}); + coords.push_back({{3, 7}, 7}); + + try + { + Structure s{coords.begin(), coords.end()}; + s.author = "Bob"; + s.title = "Foo"; + s.date = "28/07/2001"; + s.desc = "Lorem ipsum"; + + RLEStructureWriter writer; + auto out = writer.save_structure(s); + + //printf("%s\n", out.c_str()); + + RLEStructureReader reader(out); + Structure struct_out = reader.read_structure(); + + QVERIFY(std::is_permutation(struct_out.begin(), struct_out.end(), coords.begin())); + //QCOMPARE(struct_out.author, s.author); + //QCOMPARE(struct_out.date, s.date); + QCOMPARE(struct_out.desc, s.desc); + QCOMPARE(struct_out.title, s.title); + } + catch (const std::exception& ex) + { + fprintf(stderr, "Error is %s\n", ex.what()); + QFAIL("Exception thrown"); + } } void CellulutTests::test_json_structurewriter()