mis en place la PR de simon sur les couleurs
This commit is contained in:
@@ -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++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user