meilleurs coms ig
This commit is contained in:
@@ -7,10 +7,10 @@
|
||||
#include <iostream>
|
||||
#include <climits>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
|
||||
Polyomino::Polyomino(const std::set<Position>& positions) {
|
||||
// find min/max
|
||||
int minX = INT_MAX;
|
||||
int maxX = INT_MIN;
|
||||
int minY = INT_MAX;
|
||||
@@ -22,15 +22,14 @@ Polyomino::Polyomino(const std::set<Position>& positions) {
|
||||
if (position.y > maxY) maxY = position.y;
|
||||
}
|
||||
|
||||
// normalize
|
||||
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
|
||||
std::set<Position> newPositions;
|
||||
for (Position position : positions) {
|
||||
newPositions.insert(Position{position.x - minX, position.y - minY});
|
||||
}
|
||||
this->positions = std::move(newPositions);
|
||||
|
||||
// set polyomino length
|
||||
this->length = std::max(maxX - minX + 1, maxY - minY + 1);
|
||||
}
|
||||
|
||||
Polyomino::Polyomino(const std::set<Position>& positions, int length) :
|
||||
@@ -39,7 +38,6 @@ Polyomino::Polyomino(const std::set<Position>& positions, int length) :
|
||||
}
|
||||
|
||||
void Polyomino::normalize() {
|
||||
// find min values
|
||||
int minX = INT_MAX;
|
||||
int minY = INT_MAX;
|
||||
for (Position position : this->positions) {
|
||||
@@ -47,7 +45,6 @@ void Polyomino::normalize() {
|
||||
if (position.y < minY) minY = position.y;
|
||||
}
|
||||
|
||||
// translate the polyomino to the lowest unsigned values
|
||||
std::set<Position> newPositions;
|
||||
for (Position position : this->positions) {
|
||||
newPositions.insert(Position{position.x - minX, position.y - minY});
|
||||
@@ -82,6 +79,7 @@ void Polyomino::rotateCCW() {
|
||||
void Polyomino::goToSpawnPosition() {
|
||||
// initialize array
|
||||
std::vector<std::vector<int>> linesCompleteness;
|
||||
linesCompleteness.reserve(4);
|
||||
std::vector<int> empty;
|
||||
for (int j = 0; j < this->length; j++) {
|
||||
empty.push_back(0);
|
||||
@@ -98,15 +96,15 @@ void Polyomino::goToSpawnPosition() {
|
||||
linesCompleteness.at(3).at(position.x) += 1; // 3 = left to right = CCW
|
||||
}
|
||||
|
||||
// count empty lines
|
||||
// count empty lines and push the non-empty lines to the start of each vector
|
||||
int horizontalEmptyLines = 0;
|
||||
int verticalEmptyLines = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = this->length - 1; j >= 0; j--) {
|
||||
if (linesCompleteness.at(i).at(j) == 0) {
|
||||
// push the non-empty lines to the start of each vector
|
||||
linesCompleteness.at(i).erase(linesCompleteness.at(i).begin() + j);
|
||||
linesCompleteness.at(i).push_back(0);
|
||||
|
||||
if (i == 0) horizontalEmptyLines++;
|
||||
if (i == 1) verticalEmptyLines++;
|
||||
}
|
||||
@@ -124,11 +122,11 @@ void Polyomino::goToSpawnPosition() {
|
||||
currentFlattestSides[3] = false;
|
||||
}
|
||||
|
||||
// checks for the flattest sides
|
||||
// checks for the flattest side
|
||||
int sideToBeOn = -1;
|
||||
this->checkForFlattestSide(linesCompleteness, currentFlattestSides, sideToBeOn, false);
|
||||
|
||||
// if all sides are as flat, checks for the most left-biased side
|
||||
// if ther's no winner, checks for the side which has the flattest side to its left
|
||||
if (sideToBeOn == -1) {
|
||||
this->checkForFlattestSide(linesCompleteness, currentFlattestSides, sideToBeOn, true);
|
||||
}
|
||||
@@ -148,12 +146,16 @@ void Polyomino::goToSpawnPosition() {
|
||||
sideToBeOn = candidateSides.at(std::distance(candidateRotations.begin(), std::min_element(candidateRotations.begin(), candidateRotations.end())));
|
||||
}
|
||||
|
||||
// do the correct rotation
|
||||
if (sideToBeOn == 1) this->rotateCW();
|
||||
if (sideToBeOn == 2) this->rotate180();
|
||||
if (sideToBeOn == 3) this->rotateCCW();
|
||||
switch (sideToBeOn) {
|
||||
case 1 : {this->rotateCW(); break;}
|
||||
case 2 : {this->rotate180(); break;}
|
||||
case 3 : {this->rotateCCW(); break;}
|
||||
default: break;
|
||||
}
|
||||
if (sideToBeOn % 2 == 1) {
|
||||
std::swap(verticalEmptyLines, horizontalEmptyLines);
|
||||
}
|
||||
|
||||
// find min
|
||||
int minX = INT_MAX;
|
||||
int minY = INT_MAX;
|
||||
for (Position position : this->positions) {
|
||||
@@ -161,10 +163,7 @@ void Polyomino::goToSpawnPosition() {
|
||||
if (position.y < minY) minY = position.y;
|
||||
}
|
||||
|
||||
// center the piece with an up bias if it is assymetric
|
||||
if (sideToBeOn % 2 == 1) {
|
||||
std::swap(verticalEmptyLines, horizontalEmptyLines);
|
||||
}
|
||||
// center the piece with an up bias
|
||||
std::set<Position> newPositions;
|
||||
for (Position position : positions) {
|
||||
newPositions.insert(Position{(position.x - minX) + (verticalEmptyLines / 2), (position.y - minY) + ((horizontalEmptyLines + 1) / 2)});
|
||||
@@ -174,19 +173,17 @@ void Polyomino::goToSpawnPosition() {
|
||||
|
||||
void Polyomino::checkForFlattestSide(const std::vector<std::vector<int>>& linesCompleteness, bool currentFlattestSides[4], int& sideToBeOn, bool checkLeftSide) const {
|
||||
for (int j = 0; j < this->length; j++) {
|
||||
// we check which sides are the flattest on this line
|
||||
int max = 0;
|
||||
std::set<int> maxOwners;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
// only the candidate sides are compared
|
||||
if (!currentFlattestSides[i]) continue;
|
||||
|
||||
// if we need to check the flatness of the side to the left
|
||||
int sideToCheck = i;
|
||||
if (checkLeftSide) {
|
||||
sideToCheck = (i + 3) % 4;
|
||||
}
|
||||
|
||||
// we check which sides are the flattest
|
||||
if (linesCompleteness.at(sideToCheck).at(j) > max) {
|
||||
max = linesCompleteness.at(sideToCheck).at(j);
|
||||
maxOwners.clear();
|
||||
@@ -203,7 +200,7 @@ void Polyomino::checkForFlattestSide(const std::vector<std::vector<int>>& linesC
|
||||
return;
|
||||
}
|
||||
|
||||
// else we only keep the flattest from this round and ignore the others
|
||||
// else we only keep the flattest on this line and ignore the others
|
||||
else {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
currentFlattestSides[i] = currentFlattestSides[i] && maxOwners.contains(i);
|
||||
@@ -213,14 +210,12 @@ void Polyomino::checkForFlattestSide(const std::vector<std::vector<int>>& linesC
|
||||
}
|
||||
|
||||
bool Polyomino::isConvex() const {
|
||||
// for each line and column we check if every squares are adjacent to each others
|
||||
for (int j = 0; j < this->length; j++) {
|
||||
bool startedLine = false;
|
||||
bool completedLine = false;
|
||||
bool startedColumn = false;
|
||||
bool completedColumn = false;
|
||||
for (int i = 0; i < this->length; i++) {
|
||||
// line check
|
||||
if (this->positions.contains(Position{i, j})) {
|
||||
if (completedLine) return false;
|
||||
else startedLine = true;
|
||||
@@ -228,7 +223,7 @@ bool Polyomino::isConvex() const {
|
||||
else {
|
||||
if (startedLine) completedLine = true;
|
||||
}
|
||||
// column check
|
||||
|
||||
if (this->positions.contains(Position{j, i})) {
|
||||
if (completedColumn) return false;
|
||||
else startedColumn = true;
|
||||
@@ -282,7 +277,6 @@ int Polyomino::getPolyominoSize() const {
|
||||
bool Polyomino::operator<(const Polyomino& other) const {
|
||||
if (this->length != other.length) return this->length < other.length;
|
||||
|
||||
// we check for all positions from left to right and top to bottom, until one has a square that the other doesn't
|
||||
for (int y = this->length - 1; y >= 0; y--) {
|
||||
for (int x = 0; x < this->length; x++) {
|
||||
bool hasThisPosition = this->positions.contains(Position{x, y});
|
||||
|
||||
Reference in New Issue
Block a user