#pragma once #include "Position.h" #include #include #include #include /** * A mathematical object consisting of touching squares on a 2D grid */ class Polyomino { public: static const std::size_t POLYOMINO_DATA_SIZE = 4; using PolyominoData = std::array; private: PolyominoData positions; // the squares composing the polyomino, stored in binary. MSB is downleft std::int8_t length; // the size of the smallest square box in which the polyomino can fit on any rotation public: /** * Creates a polyomino with the specified positions and length, wheter it is actually a polyonimo of this length is not checked */ Polyomino(PolyominoData&& positions, std::int8_t length); /** * Creates a polyomino with the specified positions and normalizes it, wheter it is actually a polyonimo is not checked */ Polyomino(std::set&& positions); /** * Translates the polyomino to the lowest unsigned values (lower row on y = 0, and left-most column on x = 0) */ void normalize(); /** * Rotates the polyomino 90° clockwise, the center of rotation being the middle of the box going from (0,0) to (length-1, length-1) */ void rotateCW(); /** * Rotates the polyomino 180°, the center of rotation being the middle of the box going from (0,0) to (length-1, length-1) */ void rotate180(); /** * Rotates the polyomino 90° counter-clockwise, the center of rotation being the middle of the box going from (0,0) to (length-1, length-1) */ void rotateCCW(); /** * Set the polyomino to a normalized default spawn position */ void goToSpawnPosition(); private: /** * Auxiliary method of goToSpawnPosition() */ void checkForFlattestSide(const std::vector>& linesCompleteness, bool currentFlattestSides[4], int& sideToBeOn, bool checkLeftSide) const; public: /** * Check if the polyomino is convex, that is if every line and column has at most one continuous line of positions * @return If the polyomino is convex */ bool isConvex() const; /** * Check if the polyomino has at least one hole * @return If the polyomino has at least one hole */ bool hasHole() const; private: /** * Auxiliary method of hasHole() */ void tryToInsertPosition(std::set& emptypositions, const Position& candidate) const; public: /** * @return The positions data of the polyomino */ const PolyominoData& getPositionsData() const; /** * @return The positions of the polyomino (deduces it from the binary representation) */ std::vector getPositions() const; /** * @return The length of the polyomino */ int getLength() const; /** * @return The number of squares in the polyomino */ int getPolyominoSize() const; /** * Strict inferiority operator, a polyomino is inferior than another if it has a smaller length, or if they are the same length, * while checking from left to right and top to bottom, is the first which has a square while the other don't * @return If the polyomino is inferior than another */ bool operator<(const Polyomino& other) const; /** * Equality operator, two polyominoes are equal if their positions are the same, that means two polyominoes of the same shape at different places will not be equal * @return If the polyomino is equal to another */ bool operator==(const Polyomino& other) const; /** * Stream output operator, adds a 2D grid representing the polyomino * @return A reference to the output stream */ friend std::ostream& operator<<(std::ostream& os, const Polyomino& polyomino); /** * @return True if it contains the position */ bool contains(const Position& position) const; /** * @brief Insert a square at the position */ void insert(const Position& position); /** * @brief Removes a square at the position */ void erase(const Position& position); };