decrease file retrieving time
All checks were successful
Linux arm64 / Build (push) Successful in 2m29s
All checks were successful
Linux arm64 / Build (push) Successful in 2m29s
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
#include <string>
|
||||
|
||||
|
||||
Piece::Piece(const Polyomino& polyomino, Block blockType) :
|
||||
Piece::Piece(Polyomino&& polyomino, Block blockType) :
|
||||
polyomino(polyomino),
|
||||
blockType(blockType),
|
||||
rotationState(NONE),
|
||||
|
||||
@@ -22,7 +22,7 @@ class Piece {
|
||||
/**
|
||||
* Creates a piece with a specified shape and block type
|
||||
*/
|
||||
Piece(const Polyomino& piece, Block blockType);
|
||||
Piece(Polyomino&& piece, Block blockType);
|
||||
|
||||
/**
|
||||
* Rotates the piece in the specified direction
|
||||
|
||||
@@ -50,11 +50,12 @@ bool PiecesFiles::savePieces(int polyominoSize, std::vector<Polyomino>& polyomin
|
||||
std::uint8_t infoByte = (isConvex << 7) + (hasHole << 6) + polyomino.getLength();
|
||||
buffer << infoByte;
|
||||
|
||||
const int bitsNeeded = polyomino.getLength() * polyomino.getLength();
|
||||
const int longsNeeded = bitsNeeded / 64 + 1;
|
||||
|
||||
// write the positions of the piece
|
||||
std::uint8_t positionByte;
|
||||
for (const Position position : polyomino.getPositions()) {
|
||||
positionByte = (position.x << 4) + position.y;
|
||||
buffer << positionByte;
|
||||
for (int i = 0; i < longsNeeded; i++) {
|
||||
buffer << polyomino.getPositionsData()[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,11 +92,11 @@ bool PiecesFiles::loadPieces(int polyominoSize, std::vector<Piece>& pieces, std:
|
||||
nextPieceBlockType(pieceBlock);
|
||||
}
|
||||
|
||||
char convexMask = 0b1000'0000;
|
||||
char holeMask = 0b0100'0000;
|
||||
char lengthMask = 0b0011'1111;
|
||||
char xMask = 0b1111'0000;
|
||||
char yMask = 0b0000'1111;
|
||||
constexpr char convexMask = 0b1000'0000;
|
||||
constexpr char holeMask = 0b0100'0000;
|
||||
constexpr char lengthMask = 0b0011'1111;
|
||||
constexpr char xMask = 0b1111'0000;
|
||||
constexpr char yMask = 0b0000'1111;
|
||||
|
||||
std::uint8_t infoByte;
|
||||
int i = 0;
|
||||
@@ -108,18 +109,17 @@ bool PiecesFiles::loadPieces(int polyominoSize, std::vector<Piece>& pieces, std:
|
||||
bool hasHole = (infoByte & holeMask) >> 6;
|
||||
int length = (infoByte & lengthMask);
|
||||
|
||||
const int bitsNeeded = length * length;
|
||||
const int longsNeeded = bitsNeeded / 64 + 1;
|
||||
|
||||
// read positions
|
||||
std::set<Position> piecePositions;
|
||||
std::uint8_t positionByte;
|
||||
for (int i = 0; i < polyominoSize; i++) {
|
||||
buffer >> positionByte;
|
||||
int x = ((unsigned char) positionByte & xMask) >> 4;
|
||||
int y = positionByte & yMask;
|
||||
piecePositions.insert(Position(x, y));
|
||||
Polyomino::PolyominoData polyominoData{};
|
||||
for (int i = 0; i < longsNeeded; i++) {
|
||||
buffer >> polyominoData[i];
|
||||
}
|
||||
|
||||
// create piece
|
||||
Piece readPiece(Polyomino(std::move(piecePositions), length), pieceBlock);
|
||||
Piece readPiece(Polyomino(std::move(polyominoData), length), pieceBlock);
|
||||
nextPieceBlockType(pieceBlock);
|
||||
|
||||
pieces.push_back(readPiece);
|
||||
|
||||
@@ -31,38 +31,6 @@ Polyomino::Polyomino(std::set<Position>&& positions) {
|
||||
this->positions = std::move(temp.positions);
|
||||
}
|
||||
|
||||
Polyomino::Polyomino(std::set<Position>&& positions, std::int8_t length) : positions(), length(length){
|
||||
for (Position position : positions) {
|
||||
insert(position);
|
||||
}
|
||||
}
|
||||
|
||||
Polyomino::Polyomino(PolyominoData&& positions) : positions(positions) {
|
||||
int minX = INT_MAX;
|
||||
int maxX = INT_MIN;
|
||||
int minY = INT_MAX;
|
||||
int maxY = INT_MIN;
|
||||
|
||||
// tout s'appelle positions, osekour !
|
||||
std::vector<Position> tempPositions = getPositions();
|
||||
|
||||
for (const Position position : tempPositions) {
|
||||
if (position.x < minX) minX = position.x;
|
||||
if (position.x > maxX) maxX = position.x;
|
||||
if (position.y < minY) minY = position.y;
|
||||
if (position.y > maxY) maxY = position.y;
|
||||
}
|
||||
|
||||
this->length = std::max(maxX - minX + 1, maxY - minY + 1);
|
||||
|
||||
// we normalize here instead of calling this->normalize() to reduce the number of calculations for the generation algorithm
|
||||
Polyomino temp(PolyominoData{}, this->length);
|
||||
for (Position position : tempPositions) {
|
||||
temp.insert(Position(position.x - minX, position.y - minY));
|
||||
}
|
||||
this->positions = std::move(temp.positions);
|
||||
}
|
||||
|
||||
Polyomino::Polyomino(PolyominoData&& positions, std::int8_t length) :
|
||||
positions(std::move(positions)),
|
||||
length(length) {
|
||||
@@ -79,7 +47,7 @@ void Polyomino::normalize() {
|
||||
if (position.y < minY) minY = position.y;
|
||||
}
|
||||
|
||||
Polyomino temp(PolyominoData{}, this->length);
|
||||
Polyomino temp({}, this->length);
|
||||
for (const Position position : tempPositions) {
|
||||
temp.insert(Position(position.x - minX, position.y - minY));
|
||||
}
|
||||
@@ -87,7 +55,7 @@ void Polyomino::normalize() {
|
||||
}
|
||||
|
||||
void Polyomino::rotateCW() {
|
||||
Polyomino temp(PolyominoData{}, this->length);
|
||||
Polyomino temp({}, this->length);
|
||||
for (const Position position : getPositions()) {
|
||||
temp.insert(Position(position.y, (length - 1) - (position.x)));
|
||||
}
|
||||
@@ -95,7 +63,7 @@ void Polyomino::rotateCW() {
|
||||
}
|
||||
|
||||
void Polyomino::rotate180() {
|
||||
Polyomino temp(PolyominoData{}, this->length);
|
||||
Polyomino temp({}, this->length);
|
||||
for (const Position position : getPositions()) {
|
||||
temp.insert(Position((length - 1) - (position.x), (length - 1) - (position.y)));
|
||||
}
|
||||
@@ -103,7 +71,7 @@ void Polyomino::rotate180() {
|
||||
}
|
||||
|
||||
void Polyomino::rotateCCW() {
|
||||
Polyomino temp(PolyominoData{}, this->length);
|
||||
Polyomino temp({}, this->length);
|
||||
for (const Position position : getPositions()) {
|
||||
temp.insert(Position((length - 1) - (position.y), position.x));
|
||||
}
|
||||
@@ -200,7 +168,7 @@ void Polyomino::goToSpawnPosition() {
|
||||
}
|
||||
|
||||
// center the piece with an up bias
|
||||
Polyomino temp(PolyominoData{}, this->length);
|
||||
Polyomino temp({}, this->length);
|
||||
for (const Position position : tempPositions) {
|
||||
temp.insert(Position((position.x - minX) + (verticalEmptyLines / 2), (position.y - minY) + ((horizontalEmptyLines + 1) / 2)));
|
||||
}
|
||||
@@ -298,7 +266,7 @@ void Polyomino::tryToInsertPosition(std::set<Position>& emptyPositions, const Po
|
||||
tryToInsertPosition(emptyPositions, Position(candidate.x - 1, candidate.y));
|
||||
}
|
||||
|
||||
const PolyominoData& Polyomino::getPositionsData() const {
|
||||
const Polyomino::PolyominoData& Polyomino::getPositionsData() const {
|
||||
return this->positions;
|
||||
}
|
||||
|
||||
@@ -368,4 +336,11 @@ void Polyomino::insert(const Position& position) {
|
||||
int longIndex = posIndex / (sizeof(std::uint64_t) * 8);
|
||||
int bitIndex = posIndex % (sizeof(std::uint64_t) * 8);
|
||||
this->positions[longIndex] |= static_cast<std::uint64_t>(1) << (sizeof(std::uint64_t) * 8 - bitIndex);
|
||||
}
|
||||
|
||||
void Polyomino::erase(const Position& position) {
|
||||
int posIndex = position.y * this->length + position.x;
|
||||
int longIndex = posIndex / (sizeof(std::uint64_t) * 8);
|
||||
int bitIndex = posIndex % (sizeof(std::uint64_t) * 8);
|
||||
this->positions[longIndex] &= ~(static_cast<std::uint64_t>(1) << (sizeof(std::uint64_t) * 8 - bitIndex));
|
||||
}
|
||||
@@ -7,30 +7,29 @@
|
||||
#include <iostream>
|
||||
#include <array>
|
||||
|
||||
using PolyominoData = std::array<std::uint64_t, 4>;
|
||||
|
||||
/**
|
||||
* 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 normalizes it, wheter it is actually a polyonimo is not checked
|
||||
*/
|
||||
Polyomino(PolyominoData&& positions);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
// this is temporary. They are here for compatibility reasons for now
|
||||
/**
|
||||
* Creates a polyomino with the specified positions and normalizes it, wheter it is actually a polyonimo is not checked
|
||||
*/
|
||||
Polyomino(std::set<Position>&& positions);
|
||||
Polyomino(std::set<Position>&& positions, std::int8_t length);
|
||||
|
||||
/**
|
||||
* Translates the polyomino to the lowest unsigned values (lower row on y = 0, and left-most column on x = 0)
|
||||
@@ -127,9 +126,13 @@ class Polyomino {
|
||||
*/
|
||||
bool contains(const Position& position) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Insert a square at the position
|
||||
*/
|
||||
void insert(const Position& position);
|
||||
|
||||
/**
|
||||
* @brief Removes a square at the position
|
||||
*/
|
||||
void erase(const Position& position);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user