Files
jminos/src/Pieces/Polyomino.h
Persson-dev a3ef52c7a1
All checks were successful
Linux arm64 / Build (push) Successful in 2m29s
decrease file retrieving time
2025-07-20 21:08:36 +02:00

139 lines
4.5 KiB
C++

#pragma once
#include "Position.h"
#include <vector>
#include <set>
#include <iostream>
#include <array>
/**
* 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<std::uint64_t, POLYOMINO_DATA_SIZE>;
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<Position>&& 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<std::vector<int>>& 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<Position>& 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<Position> 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);
};