mis en place la PR de simon sur les couleurs

This commit is contained in:
2025-02-28 18:42:04 +01:00
parent f0f391ade6
commit 26f501f7e8
29 changed files with 713 additions and 665 deletions

View File

@@ -2,36 +2,33 @@
#include "Polyomino.h"
#include <Vector>
#include <Set>
#include <Map>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
Generator::Generator() {
}
std::vector<Polyomino> Generator::generatePolyominos(unsigned int order) {
// initialization
std::vector<Polyomino> Generator::generatePolyominos(unsigned int polyominoSize) {
this->validPolyominos.clear();
this->currentTestedShape.clear();
// no polyomino with 0 cells
if (order == 0) return this->validPolyominos;
// no polyomino of size 0
if (polyominoSize == 0) return this->validPolyominos;
// start generating from the monomino
this->currentTestedShape.insert(Cell{0, 0});
this->currentTestedShape.insert(Position{0, 0});
// generate polyominos
std::map<Cell, int> candidateCells;
this->generate(order, 0, 1, candidateCells);
std::map<Position, int> candidatePositions;
this->generate(polyominoSize, 0, 1, candidatePositions);
return this->validPolyominos;
}
void Generator::generate(unsigned int order, int lastAddedCellNumber, int nextAvaibleNumber, std::map<Cell, int> candidateCells) {
void Generator::generate(unsigned int polyominoSize, int lastAddedPositionNumber, int nextAvaibleNumber, std::map<Position, int> candidatePositions) {
// recursion stop
if (order == this->currentTestedShape.size()) {
// we test the polyomino formed by the current shape
if (polyominoSize == this->currentTestedShape.size()) {
Polyomino candidate(this->currentTestedShape);
// we sort the rotations of the polyominos
@@ -51,35 +48,35 @@ void Generator::generate(unsigned int order, int lastAddedCellNumber, int nextAv
return;
}
// generate the list of candidate cells
for (Cell cell : this->currentTestedShape) {
this->tryToAddCandidateCell(Cell{cell.x, cell.y + 1}, nextAvaibleNumber, candidateCells);
this->tryToAddCandidateCell(Cell{cell.x + 1, cell.y}, nextAvaibleNumber, candidateCells);
this->tryToAddCandidateCell(Cell{cell.x, cell.y - 1}, nextAvaibleNumber, candidateCells);
this->tryToAddCandidateCell(Cell{cell.x - 1, cell.y}, nextAvaibleNumber, candidateCells);
// generate the list of candidate positions
for (Position position : this->currentTestedShape) {
this->tryToAddCandidatePosition(Position{position.x, position.y + 1}, nextAvaibleNumber, candidatePositions);
this->tryToAddCandidatePosition(Position{position.x + 1, position.y}, nextAvaibleNumber, candidatePositions);
this->tryToAddCandidatePosition(Position{position.x, position.y - 1}, nextAvaibleNumber, candidatePositions);
this->tryToAddCandidatePosition(Position{position.x - 1, position.y}, nextAvaibleNumber, candidatePositions);
}
// generate polyominos for all cells with a higher number than the last one
for (auto [key, val] : candidateCells) {
if (val > lastAddedCellNumber) {
// generate polyominos for all positions with a higher number than the last one
for (auto [key, val] : candidatePositions) {
if (val > lastAddedPositionNumber) {
this->currentTestedShape.insert(key);
this->generate(order, val, nextAvaibleNumber, (order == this->currentTestedShape.size()) ? std::map<Cell, int>() : candidateCells);
this->generate(polyominoSize, val, nextAvaibleNumber, (polyominoSize == this->currentTestedShape.size()) ? std::map<Position, int>() : candidatePositions);
this->currentTestedShape.erase(key);
}
}
}
void Generator::tryToAddCandidateCell(const Cell& candidate, int& nextAvaibleNumber, std::map<Cell, int>& candidateCells) {
// we declared the first cell as the lower-left square, since we always start with a monomino at (0,0) we can test with hard values
void Generator::tryToAddCandidatePosition(const Position& candidate, int& nextAvaibleNumber, std::map<Position, int>& candidatepositions) {
// we declared the first position as the lower-left square, since we always start with a monomino at (0,0) we can test with 0 directly
if (candidate.y < 0 || (candidate.y == 0 && candidate.x < 0)) return;
// if the cell was already marked then we should not mark it again
if (candidateCells.contains(candidate)) return;
// if the position was already marked then we should not mark it again
if (candidatepositions.contains(candidate)) return;
// if the candidate overlaps with the shape there is no reason to add it
if (this->currentTestedShape.contains(candidate)) return;
// once all tests passed we can add the cell
candidateCells.insert({candidate, nextAvaibleNumber});
// once all tests passed we can add the position
candidatepositions.insert({candidate, nextAvaibleNumber});
nextAvaibleNumber++;
}