114 lines
3.8 KiB
C++
114 lines
3.8 KiB
C++
#pragma once
|
|
|
|
#include "Position.h"
|
|
|
|
#include <vector>
|
|
#include <set>
|
|
#include <iostream>
|
|
|
|
|
|
/**
|
|
* A mathematical object consisting of touching squares on a 2D grid
|
|
*/
|
|
class Polyomino {
|
|
private:
|
|
std::set<Position> positions; // the squares composing the polyomino, (0,0) is downleft
|
|
int 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 normalizes it, wheter it is actually a polyonimo is not checked
|
|
*/
|
|
Polyomino(const std::set<Position>& positions);
|
|
|
|
/**
|
|
* Creates a polyomino with the specified positions and length, wheter it is actually a polyonimo of this length is not checked
|
|
*/
|
|
Polyomino(const std::set<Position>& positions, int length);
|
|
|
|
/**
|
|
* 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 of the polyomino
|
|
*/
|
|
const std::set<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);
|
|
};
|