111 lines
3.4 KiB
C++
111 lines
3.4 KiB
C++
#include "Bag.h"
|
|
|
|
#include "../Pieces/Piece.h"
|
|
#include "PiecesList.h"
|
|
|
|
#include <vector>
|
|
#include <utility>
|
|
#include <cstdlib>
|
|
|
|
static const double SMALLEST_CONSIDERED_PROPORTION = 0.01; // the smallest a proportion can get before it is considered equal to 0
|
|
|
|
|
|
Bag::Bag(const std::shared_ptr<PiecesList>& piecesList) :
|
|
piecesList(piecesList) {
|
|
|
|
this->highestSize = this->piecesList->getHighestLoadedSize();
|
|
this->selectedPieces = this->piecesList->getSelectedPieces();
|
|
this->distributionMode = this->piecesList->getDistributionMode();
|
|
this->propotionsPerSize = this->piecesList->getProportionsPerSize();
|
|
|
|
this->currentBags.clear();
|
|
this->nextBags.clear();
|
|
this->sizesBag.clear();
|
|
this->sizesProgression.clear();
|
|
|
|
if (this->distributionMode == DEFAULT) {
|
|
this->currentBags.push_back(this->selectedPieces);
|
|
this->nextBags.push_back({});
|
|
}
|
|
else {
|
|
for (int i = 0; i <= this->highestSize; i++) {
|
|
this->currentBags.push_back(PieceBag());
|
|
this->nextBags.push_back(PieceBag());
|
|
this->sizesProgression.push_back(0);
|
|
}
|
|
|
|
for (const auto& piece : this->selectedPieces) {
|
|
int pieceSize = this->piecesList->lookAtPiece(piece).getPositions().size();
|
|
this->currentBags.at(pieceSize).push_back(piece);
|
|
}
|
|
}
|
|
|
|
this->prepareNext();
|
|
}
|
|
|
|
void Bag::jumpToNextBag() {
|
|
for (int i = 0; i < this->currentBags.size(); i++) {
|
|
if (this->currentBags.at(i).size() < this->nextBags.at(i).size()) {
|
|
std::swap(this->currentBags.at(i), this->nextBags.at(i));
|
|
}
|
|
|
|
for (const auto& piece : this->nextBags.at(i)) {
|
|
this->currentBags.at(i).push_back(piece);
|
|
}
|
|
this->nextBags.at(i).clear();
|
|
}
|
|
|
|
this->prepareNext();
|
|
}
|
|
|
|
Piece Bag::lookNext() {
|
|
return this->piecesList->getPiece(this->next);
|
|
}
|
|
|
|
Piece Bag::getNext() {
|
|
std::pair<int, int> nextIndex = this->next;
|
|
|
|
this->prepareNext();
|
|
|
|
return this->piecesList->getPiece(nextIndex);
|
|
}
|
|
|
|
void Bag::prepareNext() {
|
|
if (this->distributionMode == DEFAULT) {
|
|
this->getNextPieceFromBag(0);
|
|
}
|
|
else {
|
|
if (this->sizesBag.empty()) {
|
|
for (int i = 0; i <= this->highestSize; i++) {
|
|
if (this->propotionsPerSize.at(i) >= SMALLEST_CONSIDERED_PROPORTION
|
|
&& !(this->currentBags.at(i).empty() && this->nextBags.at(i).empty())) {
|
|
while (this->sizesProgression.at(i) < 1) {
|
|
this->sizesBag.push_back(i);
|
|
this->sizesProgression.at(i) += this->propotionsPerSize.at(i);
|
|
}
|
|
|
|
this->sizesProgression.at(i) -= 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
int nextSizeIndex = std::rand() % this->sizesBag.size();
|
|
int nextSize = this->sizesBag.at(nextSizeIndex);
|
|
this->sizesBag.erase(this->sizesBag.begin() + nextSizeIndex);
|
|
|
|
this->getNextPieceFromBag(nextSize);
|
|
}
|
|
}
|
|
|
|
void Bag::getNextPieceFromBag(int bagIndex) {
|
|
if (this->currentBags.at(bagIndex).empty()) {
|
|
std::swap(this->currentBags.at(bagIndex), this->nextBags.at(bagIndex));
|
|
}
|
|
|
|
int indexIndex = std::rand() % this->currentBags.at(bagIndex).size();
|
|
this->next = this->currentBags.at(bagIndex).at(indexIndex);
|
|
|
|
this->nextBags.at(bagIndex).push_back(this->next);
|
|
this->currentBags.at(bagIndex).erase(this->currentBags.at(bagIndex).begin() + indexIndex);
|
|
}
|