diff --git a/include/constantes.hpp b/include/constantes.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1f330ae9f9e4e827de7f6ef4d70ad75478f242e0 --- /dev/null +++ b/include/constantes.hpp @@ -0,0 +1,11 @@ +#ifndef CONSTANTES_HPP +#define CONSTANTES_HPP + +#define MAX_ETATS 32 +#if MAX_ETATS > 255 +#error MAX_ETATS ne tient pas dans un unsigned char +#endif + +#define MAX_VOISINS 256 + +#endif // CONSTANTES_HPP diff --git a/include/grid.h b/include/grid.h index 8ba5ceea1894b15bff8f1f21f2382095e25f9957..5a6081976d2b8ca82a8df3e3424c2fdf1a21a21e 100644 --- a/include/grid.h +++ b/include/grid.h @@ -31,7 +31,7 @@ class Structure; class Grid{ int nb_rows; int nb_col; - std::vector<unsigned int> matrix; + std::vector<unsigned char> matrix; public: //! \brief Constructeur par défaut, avec le nombre de ligne et de colonne souhaités Grid(size_t l,size_t c); diff --git a/include/neighborhood.hpp b/include/neighborhood.hpp index ca2e3942120a634891fefc32b3f1f96cb3841d0d..527b1ac271e4620f047f7027a8e3a570199cccf9 100644 --- a/include/neighborhood.hpp +++ b/include/neighborhood.hpp @@ -17,9 +17,11 @@ Cette classe représente le voisinage d'une cellule. #include <utility> #include <string> #include <algorithm> +#include <cstring> #include "coord.hpp" #include "state.hpp" +#include "constantes.hpp" using namespace std; @@ -38,18 +40,27 @@ public: //! \brief Classe représentant un voisinage, c'est à dire une liste de cellules dont leur état et leur position. class Neighborhood { - //! \brief vector de voisins contenant la position relative et l'état du voisin - mutable vector<pair<Coord, unsigned int>> neighborPositions; - //! \brief Contient le nombre de voisins d'état i : counts[i] contient le nb de voisins d'état i, ou 0 si i >= counts.size() - std::vector<unsigned> counts; + //! \brief struct nécéssaire pour éviter l'initalisation par zéro coûteuse d'un std::pair + struct Cell + { + Coord pos; + unsigned char state; + }; + + //! \brief Contient le nombre de voisins d'état i : counts[i] contient le nb de voisins d'état i, ou 0 si i >= MAX_ETATS + unsigned char counts[MAX_ETATS]; + //! \brief Nombre de voisins + unsigned int neighbors; mutable bool sorted; + //! \brief Tableau contenant la liste des voisins + mutable Cell neighborPositions[MAX_VOISINS]; public: //! \brief Initialisation du Neighborhood Neighborhood() { - neighborPositions.reserve(8); - counts.reserve(8); + memset(counts, 0, MAX_ETATS); + neighbors = 0; sorted = false; } @@ -58,7 +69,7 @@ public: //! \return Le nombre de voisin unsigned int getNb(unsigned int s) const { - if (s >= counts.size()) + if (s >= MAX_ETATS) return 0; else return counts[s]; @@ -68,12 +79,13 @@ public: //! \brief Ajoute un voisin au vecteur des voisins. Prend une coordonnée et un état en paramètre //! \param Coord, State : coordonée relative et état du voisin //! \pre La coord ne doit pas déjà exister - void addNeighbor(Coord c, unsigned int s) { + void addNeighbor(Coord c, unsigned char s) { + if (s >= MAX_ETATS) + throw NeighborhoodException("Valeur d'état supérieure à l'état maximal"); + sorted = false; - neighborPositions.push_back({c,s}); - if (s >= counts.size()) - counts.resize(s+1, 0); - ++counts[s]; + neighborPositions[neighbors++] = {c,s}; + ++counts[s]; } //! \brief Retourne une copie du voisinage, miroir selon l'axe vertical. @@ -85,23 +97,23 @@ public: //! \brief Retourne le nombre de voisins dans le Neighborhood. unsigned size() const - { return neighborPositions.size(); } + { return neighbors; } //! \brief Retourne la cellule numéro i (index allant de 0 à size()-1, permettant d'indexer les cellules indépendamment de leur position - pair<Coord, unsigned int> neighbor_at_index(unsigned i) const + pair<Coord, unsigned char> neighbor_at_index(unsigned i) const { if (i >= size()) throw NeighborhoodException("Index invalide\n"); if (!sorted) { - std::sort(neighborPositions.begin(), neighborPositions.end(), - [](const pair<Coord, unsigned int>& lhs, const pair<Coord, unsigned int>& rhs) + std::sort(std::begin(neighborPositions), std::begin(neighborPositions) + neighbors, + [](const Cell& lhs, const Cell& rhs) { - return lhs.first < rhs.first; + return lhs.pos < rhs.pos; }); sorted = true; } - return neighborPositions[i]; + return {neighborPositions[i].pos, neighborPositions[i].state}; } }; diff --git a/src/neighborhood.cpp b/src/neighborhood.cpp index 0792e12e15c2a74414bd0891646e8ac82e06e45f..ce235e7f8f7e02ef272c4f1ca21d34f3a3649f1d 100644 --- a/src/neighborhood.cpp +++ b/src/neighborhood.cpp @@ -3,9 +3,10 @@ Neighborhood Neighborhood::flip_vertically() const { Neighborhood n; - for (const auto& val : neighborPositions) + for (unsigned i = 0; i < size(); ++i) { - n.addNeighbor(Coord{val.first.x, -val.first.y}, val.second); + const auto& val = neighborPositions[i]; + n.addNeighbor(Coord{val.pos.x, -val.pos.y}, val.state); } return n; } @@ -13,9 +14,10 @@ Neighborhood Neighborhood::flip_vertically() const Neighborhood Neighborhood::flip_horizontally() const { Neighborhood n; - for (const auto& val : neighborPositions) + for (unsigned i = 0; i < size(); ++i) { - n.addNeighbor(Coord{-val.first.x, val.first.y}, val.second); + const auto& val = neighborPositions[i]; + n.addNeighbor(Coord{-val.pos.x, val.pos.y}, val.state); } return n; } @@ -23,9 +25,10 @@ Neighborhood Neighborhood::flip_horizontally() const Neighborhood Neighborhood::rotate90() const { Neighborhood n; - for (const auto& val : neighborPositions) + for (unsigned i = 0; i < size(); ++i) { - n.addNeighbor(Coord{-val.first.y, val.first.x}, val.second); + const auto& val = neighborPositions[i]; + n.addNeighbor(Coord{-val.pos.y, val.pos.x}, val.state); } return n; } diff --git a/src/src.pro b/src/src.pro index a46c4dc112379e47b3ed5c0cecd48c4f61b5f751..1de401f2e723c89be433ad9825ff4781780d20f9 100644 --- a/src/src.pro +++ b/src/src.pro @@ -6,7 +6,7 @@ CONFIG += c++14 TEMPLATE = app # Optimisations, flag pour garder les infos de debug -QMAKE_CXXFLAGS += -O2 -g +QMAKE_CXXFLAGS += -O3 -g # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. @@ -69,6 +69,7 @@ HEADERS += \ ../include/stateColor.hpp \ ../include/state.hpp \ ../include/history.h \ + ../include/constantes.hpp \ ../include/structurelibraryview.hpp \ ../include/transitionrule.hpp \ ../include/transition_rules/circulartransition.hpp \