diff --git a/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1.cpp b/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1.cpp index aa6aaaf..f7b766f 100644 --- a/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1.cpp +++ b/Source/functions/AbstractionLayers/Layer1/AbstractionLayer_1.cpp @@ -40,6 +40,7 @@ bool AbstractionLayer_1::CreateRandomPuzzle() for(int col=1;col> (moves*2)) | (getConnections() << sizeof(unsigned char)*8 - (moves*2)))); -} -//creates random centerpiece -void PuzzlePiece::randomCenterPiece() -{ - setConnections(0b00000000); - - if(rand()%2) - setConnections(getConnections() | (uint8_t)0b01000000); - else - setConnections(getConnections() | (uint8_t)0b10000000); - - if(rand()%2) - setConnections(getConnections() | (uint8_t)0b00010000); - else - setConnections(getConnections() | (uint8_t)0b00100000); - - if(rand()%2) - setConnections(getConnections() | (uint8_t)0b00000100); - else - setConnections(getConnections() | (uint8_t)0b00001000); - - if(rand()%2) - setConnections(getConnections() | (uint8_t)0b00000001); - else - setConnections(getConnections() | (uint8_t)0b00000010); -} - -//tests the myPart in all 4 rotations at position m, n -bool Puzzle::testRotationPiece(coor myCoor, PuzzlePiece& myPart, int nrOfRotations) -{ - for(int rotation=0; rotation < nrOfRotations; rotation++) - { - //coor myCoor(m,n); - if(PlaceOfPartGood(myCoor,myPart)) - return true; - //cout << "was rotated in testRotationPiece" << endl; - myPart.shift(1); - } - - //cout << "Was a bad part" << endl; - return false; -} - -//insterts piece at position in box according to boxidentifier and removes piece from puzzle -//this returns the position after!! the puzzle piece was put back in! not the boxidentifier of the piece. look that up in other function. -unsigned int Puzzle::putBackIntoBox(coor myCoor, vector& myBox) -{ -#ifdef debug -cout << "putting back" << endl; -cout << "Old Box: "; -printBox(myBox); -cout << endl; -#endif - for(unsigned int i = 0; i < myBox.size();i++) - { - if(myBox[i].getBoxIdentifier()>getPiece(myCoor.col,myCoor.row).getBoxIdentifier()) - { - myBox.insert(myBox.begin()+i,getPiece(myCoor.col,myCoor.row)); - removePiece(myCoor); - return i+1; - } - } - //using push back, if the element was the last element in the vector chain - myBox.push_back(getPiece(myCoor.col,myCoor.row)); - removePiece(myCoor); - return myBox.size(); -} - -//checks if the myPart in its current orientation is legal in position m, n -bool Puzzle::PlaceOfPartGood(coor myCoor, PuzzlePiece& myPart) -{ - - PuzzlePiece negativePart(0); - - negativePart.setConnections(negativePart.getConnections() | (getPiece(myCoor.col,myCoor.row+1).getConnections() & (uint8_t)0b11000000)); - negativePart.setConnections(negativePart.getConnections() | (getPiece(myCoor.col-1,myCoor.row).getConnections() & (uint8_t)0b00110000)); - negativePart.setConnections(negativePart.getConnections() | (getPiece(myCoor.col,myCoor.row-1).getConnections() & (uint8_t)0b00001100)); - negativePart.setConnections(negativePart.getConnections() | (getPiece(myCoor.col+1,myCoor.row).getConnections() & (uint8_t)0b00000011)); - negativePart.shift(2); - - - if ( - ( ((((negativePart.getConnections() & 0b11000000) ^ (myPart.getConnections() & 0b11000000)) != 0b00000000) && (((myPart.getConnections() & 0b11000000) != 0b00000000) && (negativePart.getConnections() & 0b11000000) != 0b00000000)) - || ((((negativePart.getConnections() & 0b11000000) == 0b11000000) || ((myPart.getConnections() & 0b11000000) == 0b11000000)) && (((myPart.getConnections() & 0b11000000) != 0b00000000) && (negativePart.getConnections() & 0b11000000) != 0b00000000)) - || (((negativePart.getConnections() & 0b11000000) == 0b00000000) && ((myPart.getConnections() & 0b11000000) == 0b00000000)) ) - && - ( ((((negativePart.getConnections() & 0b00110000) ^ (myPart.getConnections() & 0b00110000)) != 0b00000000) && (((myPart.getConnections() & 0b00110000) != 0b00000000) && (negativePart.getConnections() & 0b00110000) != 0b00000000)) - || ((((negativePart.getConnections() & 0b00110000) == 0b00110000) || ((myPart.getConnections() & 0b00110000) == 0b00110000)) && (((myPart.getConnections() & 0b00110000) != 0b00000000) && (negativePart.getConnections() & 0b00110000) != 0b00000000)) - || (((negativePart.getConnections() & 0b00110000) == 0b00000000) && ((myPart.getConnections() & 0b00110000) == 0b00000000)) ) - && - ( ((((negativePart.getConnections() & 0b00001100) ^ (myPart.getConnections() & 0b00001100)) != 0b00000000) && (((myPart.getConnections() & 0b00001100) != 0b00000000) && (negativePart.getConnections() & 0b00001100) != 0b00000000)) - || ((((negativePart.getConnections() & 0b00001100) == 0b00001100) || ((myPart.getConnections() & 0b00001100) == 0b00001100)) && (((myPart.getConnections() & 0b00001100) != 0b00000000) && (negativePart.getConnections() & 0b00001100) != 0b00000000)) - || (((negativePart.getConnections() & 0b00001100) == 0b00000000) && ((myPart.getConnections() & 0b00001100) == 0b00000000)) ) - && - ( ((((negativePart.getConnections() & 0b00000011) ^ (myPart.getConnections() & 0b00000011)) != 0b00000000) && (((myPart.getConnections() & 0b00000011) != 0b00000000) && (negativePart.getConnections() & 0b00000011) != 0b00000000)) - || ((((negativePart.getConnections() & 0b00000011) == 0b00000011) || ((myPart.getConnections() & 0b00000011) == 0b00000011)) && (((myPart.getConnections() & 0b00000011) != 0b00000000) && (negativePart.getConnections() & 0b00000011) != 0b00000000)) - || (((negativePart.getConnections() & 0b00000011) == 0b00000000) && ((myPart.getConnections() & 0b00000011) == 0b00000000)) ) - ) - { - //cout << "good Part: "; - //myPart.printPiece(); - //cout << endl; - return true; - } - //cout << "bad Part: "; - //myPart.printPiece(); - //cout << endl; - - return false; - -} -//prints the true puzzle (without 0 edges) -void Puzzle::printPuzzle() -{ - cout << "current Puzzle: " << endl; - for(int i=1;i randomBox::shuffle() +vector randomBox::shuffle() { random_shuffle(Box.begin(),Box.end()); for (auto &i:Box) @@ -241,48 +53,4 @@ vector randomBox::shuffle() numerateBox(Box); return Box; -} - -//creates a random box size m, n, shuffles it, and then retuns it -vector createBox(coor myCoor) -{ - randomBox myFirstPuzzleBox(myCoor.col,myCoor.row); - myFirstPuzzleBox.createRandomAbstraction1(); - myFirstPuzzleBox.createRandomAbstraction2(); - myFirstPuzzleBox.putAllIntoBox(); - - myFirstPuzzleBox.printPuzzle(); - return myFirstPuzzleBox.shuffle(); -} - -//prints contents of box -void printBox(vector myBox) -{ - cout << "current Box: " << endl; - for (auto &i:myBox) - { - i.printPiece(); - cout << ' '; - } - cout << endl; -} - -//gives every element in box a box identifier. -void numerateBox(vector& myBox) -{ - for(int i = 0; i< myBox.size();i++) - myBox[i].setBoxIdentifier(i); - -} - -std::vector convertPart2PuzzlePiece(std::vector simplePartBox) -{ - std::vector advancedPartBox; - for(auto const &i:simplePartBox) - { - PuzzlePiece tmpNewPiece(0); - tmpNewPiece.setConnections(i.getConnections()); - advancedPartBox.push_back(tmpNewPiece); - } - return advancedPartBox; } \ No newline at end of file diff --git a/Source/functions/solve/structure.cpp b/Source/functions/solve/structure.cpp index dd10799..83997a1 100755 --- a/Source/functions/solve/structure.cpp +++ b/Source/functions/solve/structure.cpp @@ -1,15 +1,15 @@ #include "../../header.h" -void status(vector& log, vector& p_Box, Puzzle& puzzleMat); +void status(vector& log, vector& p_Box); -bool next(vector& log, vector& p_Box, Puzzle& puzzleMat) +bool next(vector& log, vector& p_Box) { //last log element is set, create new log element or log not yet started if(!(log.size()) || log.back().isSet()) { if(!(p_Box.size())) return false; //puzzle solved - else createNextLogElement(log,p_Box,puzzleMat); + else createNextLogElement(log,p_Box); } //last log element is empty, backtrack else if(!(log.back().PieceCollector.size())) backtrack(log,p_Box,puzzleMat); @@ -28,27 +28,27 @@ bool next(vector& log, vector& p_Box, Puzzle& puzzleMat) if(log.back().abstractionLevel < MAX_ABSTRAX) { log.back().advance(); - solve(log,p_Box,puzzleMat); + solve(log,p_Box); } else - setsolution(log,p_Box,puzzleMat); + setsolution(log,p_Box); } else - setsolution(log,p_Box,puzzleMat); + setsolution(log,p_Box); } return true; } -void createNextLogElement(vector& log, vector& p_Box, Puzzle& puzzleMat) +void createNextLogElement(vector& log, vector& p_Box) { log.emplace_back(LogEntry()); - log.back().myCoor = calculateNextCoor(log, p_Box, puzzleMat); + log.back().myCoor = calculateNextCoor(log, p_Box); //getLayerDestructionPowerfromSurrounding(); - solve(log, p_Box,puzzleMat); + solve(log, p_Box); } -coor calculateNextCoor(vector& log, vector& p_Box, Puzzle& puzzleMat) +coor calculateNextCoor(vector& log, vector& p_Box) { //level 1: //go left to right, then increase current row @@ -68,15 +68,14 @@ coor calculateNextCoor(vector& log, vector& p_Box, Puzzl //return nextCoor; } -void solve(vector& log, vector& p_Box, Puzzle& puzzleMat) +void solve(vector& log, vector& p_Box) { //getNextHighestLayerworth(puzzleMat); //sets in abstractionLevel //status(log,p_Box,puzzleMat); switch(log.back().abstractionLevel) { - case 0: abstractionlayer0solver(log,p_Box,puzzleMat); - break; - case 1: abstractionlayer1solver(log,p_Box,puzzleMat); + case 1: + puzzleMat.AbstractionLayer_1solver.EvalueteQuality(log.back().PieceCollector); break; default: @@ -90,141 +89,50 @@ void solve(vector& log, vector& p_Box, Puzzle& puzzleMat } -void abstractionlayer0solver(vector& log, vector& p_Box, Puzzle& puzzleMat) -{ - //throw all remaining puzzle pieces into newest log - for(auto i:p_Box) - log.back().PieceCollector.push_back(i); -} - -void abstractionlayer1solver(vector& log, vector& p_Box, Puzzle& puzzleMat) -{ - //remove all that do not fit according to abstraction layer 0 - for(int i=0;i<(log.back().PieceCollector.size());) - { - (*(log.back().PieceCollector[i])).resetShift(); - //TODO: change checker from checking every box piece to only checking the simplifyed version ob the box with abstraction layer one - if(!(puzzleMat.testRotationPiece(log.back().myCoor, *(log.back().PieceCollector[i])))) - log.back().PieceCollector.erase(log.back().PieceCollector.begin()+i); - else - { - //set shift to 0 so that we have a defined starting position for all pieces - while(log.back().PieceCollector[i]->getShift()) - log.back().PieceCollector[i]->shift(1); - i++; //otherwise loop stops before end! - } - } -} - -void setsolution(vector& log, vector& p_Box, Puzzle& puzzleMat) +//removes from box and makes log "set" +void setsolution(vector& log, vector& p_Box) { //advance number of randomed part count if(log.back().PieceCollector.size()>1) log.back().advanceRandomed(); //remove first element in last logelement from box for(int i=0;ifirst)//mach ich das richtig so?! p_Box.erase(p_Box.begin()+i); else i++; - //turn piece until it fits and then set element into matrix - if(puzzleMat.testRotationPiece(log.back().myCoor,*(log.back().PieceCollector[0]))) - //error if it turned - //puzzleMat.setPiece(log.back().myCoor.m, log.back().myCoor.n, *(log.back().PieceCollector[0])); - puzzleMat.setPiece(log.back().myCoor, *(log.back().PieceCollector[0])); - else - { - cout << "fatal error, wrong piece saved" << endl; - exit; - } //tell log entry that it is set log.back().Set(); - } -bool backtrack(vector& log, vector& p_Box, Puzzle& puzzleMat) +bool backtrack(vector& log, vector& p_Box, puzzleMat) { - //following possibilities: - //last log entry empty - delete last log + backtrack - if(!(log.back().PieceCollector.size())) - { - puzzleMat.removePiece(log.back().myCoor); - log.pop_back(); - backtrack(log,p_Box,puzzleMat); - return true; - } - - //last log entry only one solution - delete last logd put back into box + backtrack - else if((log.back().PieceCollector.size())==1) - { - (log.back().PieceCollector[0])->shift(1); - - //check rotion - while((log.back().PieceCollector[0])->getShift() !=0 && (log.back().PieceCollector[0])->getShift() !=3) - { - log.back().PieceCollector[0]->shift(1); - if(puzzleMat.testRotationPiece(log.back().myCoor, *(log.back().PieceCollector[0]), 1)) - { - setsolution(log,p_Box,puzzleMat); - return true; - } - } - - p_Box.push_back(log.back().PieceCollector[0]); - //shuffleup - std::random_device rd; - std::mt19937 g(rd()); - std::shuffle(p_Box.begin(),p_Box.end(),g); - puzzleMat.removePiece(log.back().myCoor); - log.pop_back(); - //cout << "removed" << endl; - //status(log,p_Box,puzzleMat); - backtrack(log,p_Box,puzzleMat); - - return true; - } - - //last log entry multiple solutions (and current one was randomed) - delete randomed piece and go to next - else if((log.back().PieceCollector.size())>1) - { - - //check if piece has second rotation solution - (*(log.back().PieceCollector[0])).shift(1); - - while((log.back().PieceCollector[0])->getShift() !=0 && (log.back().PieceCollector[0])->getShift() !=3) - { - log.back().PieceCollector[0]->shift(1); - if(puzzleMat.testRotationPiece(log.back().myCoor, *(log.back().PieceCollector[0]), 1)) - { - setsolution(log,p_Box,puzzleMat); - return true; - } - } - - p_Box.push_back(log.back().PieceCollector[0]); - //shuffleup - std::random_device rd; - std::mt19937 g(rd()); - std::shuffle(p_Box.begin(),p_Box.end(),g); + //if more pieces possible, take next piece + if((log.back().PieceCollector.size())>1) + { + p_Box.push_back(log.back().PieceCollector.begin()->first); log.back().PieceCollector.erase(log.back().PieceCollector.begin()); if(log.back().PieceCollector.size()==1) log.back().decreaseRandomed(); - //for abstraction layer 1 so that first rotation solution is set. - (*(log.back().PieceCollector[0])).resetShift(); setsolution(log,p_Box,puzzleMat); - return true; - //no need to remove from puzzle mat, as setsolution overwrites it anyway - } - else - return false; - + return true; + } + //else remove log element and backtrack once more + else + { + puzzleMat.removePiece(log.back().myCoor); //this should remove constraints from all layers + if(!(log.back().PieceCollector.size())) + p_Box.emplace_back(log.back().PieceCollector[0]); + log.pop_back(); + backtrack(log,p_Box,puzzleMat); + } } -void status(vector& log, vector& p_Box, Puzzle& puzzleMat) +void status(vector& log, vector& p_Box, puzzleMat) { cout << "----------------------------" << endl; cout << "status:" << endl; @@ -254,7 +162,7 @@ void status(vector& log, vector& p_Box, Puzzle& puzzleMa cout << "----------------------------" << endl; } -void calculateTrueDestructionPower(vector& log, Puzzle& puzzleMat, float Layerworth) +void calculateTrueDestructionPower(vector& log, puzzleMat, float Layerworth) { //hier muss noch rein, wo die zeit der Abstractionlevels gespeichter wird float destructionPower=sqrt(Layerworth * log.back().abstractionLevel); diff --git a/Source/header/solve.h b/Source/header/solve.h index a54d4ff..71ad5e8 100755 --- a/Source/header/solve.h +++ b/Source/header/solve.h @@ -14,136 +14,10 @@ public: {} }; -class PuzzlePiece: public Part -{ -public: - - PuzzlePiece(unsigned int flag = 0) - { - shifts=0; - boxidentifier=-1; - switch(flag) - { - case 0: - setConnections(0b00000000); - break; - case 1: - setConnections(0b11111111); - break; - case 3: - randomCenterPiece(); - break; - } - } - unsigned int getShift(){return shifts;} - void resetShift(){shifts=0;} - void shift(unsigned int moves); - void randomCenterPiece(); - void printPiece() { cout << bitset (getConnections()); } - - void setBoxIdentifier(int new_boxid) { boxidentifier = new_boxid; } - int getBoxIdentifier() { return boxidentifier; } - void assignIdentifier() { identifier = idcount;idcount++; } - unsigned int getIdentifier() { return identifier;} - -private: - unsigned int shifts; - unsigned int boxidentifier; - unsigned int identifier; - - static unsigned int idcount; -}; - - - -class Puzzle -{ - friend class randomBox; -public: - //constructor creates matrix with 00 outside and 11 inside - Puzzle(unsigned int m = 7, unsigned int n = 4): col(m), row(n) - { - Matrix = new PuzzlePiece* [n+2]; - for(int i = 0;i& myBox, unsigned int separator); // 3rd change: works - unsigned int putBackIntoBox(coor myCoor, vector& myBox); // 4th change: works - - -private: - unsigned int row; - unsigned int col; - - PuzzlePiece** Matrix; - -}; - -//use this for random puzzle creation -class randomBox: public Puzzle -{ -public: - - randomBox(unsigned int m, unsigned int n) : Puzzle(m,n) {srand(time(0));} //passed m n to puzzle constructor - - void createRandomAbstraction1(); - void createRandomAbstraction2(); - void putAllIntoBox(); - vector shuffle(); - void printBox(); - -private: - vector Box; - -}; - - class LogEntry { public: - vector PieceCollector; + map PieceCollector; int abstractionLevel; coor myCoor; @@ -165,16 +39,10 @@ private: static int randomed; }; -void printBox(vector myBox); -vector createBox(coor myCoor); -void numerateBox(vector& myBox); - bool next(vector& log, vector& p_Box, Puzzle& puzzleMat); coor calculateNextCoor(vector& log, vector& p_Box, Puzzle& puzzleMat); void solve(vector& log, vector& p_Box, Puzzle& puzzleMat); -void abstractionlayer0solver(vector& log, vector& p_Box, Puzzle& puzzleMat); -void abstractionlayer1solver(vector& log, vector& p_Box, Puzzle& puzzleMat); void setsolution(vector& log, vector& p_Box, Puzzle& puzzleMat); -bool backtrack(vector& log, vector& p_Box, Puzzle& puzzleMat); +bool backtrack(vector& log, vector& p_Box, puzzleMat); void createNextLogElement(vector& log, vector& p_Box, Puzzle& puzzleMat); \ No newline at end of file diff --git a/Source/main.cpp b/Source/main.cpp index bde85f6..72e2ef7 100644 --- a/Source/main.cpp +++ b/Source/main.cpp @@ -10,11 +10,11 @@ int main() unsigned int cols=5, rows=6; //some basic random puzzle stuff - vector myFirstBox = createBox(coor(cols,rows)); + vector myFirstBox = createBox(coor(cols,rows)); //some advanced solver stuff vector log; - vector p_myFirstBox; + vector p_myFirstBox; //BoxClassify myFirstBox(); cout << endl;