Removed lots of slack, edited map functions into dispatcher, puzzleMat missing

Removed overconstructed logic, changed vector to map. PuzzleMat object not defined yet, for implementation, make the functions that have already been called through it.
This commit is contained in:
Raphael Maenle
2017-12-20 18:23:39 +01:00
parent c885e472fb
commit ce5e007bc7
5 changed files with 53 additions and 497 deletions

View File

@ -1,175 +1,9 @@
#include "../../header.h"
//shifts puzzle piece one to the right
void PuzzlePiece::shift(unsigned int moves)
{
shifts = (shifts+moves)%4;
setConnections(((getConnections() >> (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<PuzzlePiece>& 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<row+1;i++)
{
for(int j=1;j<col+1;j++)
{
Matrix[i][j].printPiece();
cout << " ";
}
cout << endl;
}
cout << endl;
}
//creates a legal puzzle out of random pieces
void randomBox::createRandomAbstraction1()
{
coor myCoor;
PuzzlePiece temporaryRandomPiece(0);
for(unsigned int i=0;i<getRows();i++)
{
for(unsigned int j = 0; j < getCols();)
{
//create random piece, set edges according to position and check if piece is good
temporaryRandomPiece.randomCenterPiece();
if(i==0)
temporaryRandomPiece.setConnections((uint8_t)0b00111111 & temporaryRandomPiece.getConnections());
if(i==getRows()-1)
temporaryRandomPiece.setConnections((uint8_t)0b11110011 & temporaryRandomPiece.getConnections());
if(j==0)
temporaryRandomPiece.setConnections((uint8_t)0b11111100 & temporaryRandomPiece.getConnections());
if(j==getCols()-1)
temporaryRandomPiece.setConnections((uint8_t)0b11001111 & temporaryRandomPiece.getConnections());
myCoor.col = j;
myCoor.row = i;
if(PlaceOfPartGood(myCoor,temporaryRandomPiece))
{
temporaryRandomPiece.assignIdentifier();
setPiece(myCoor,temporaryRandomPiece);
j++;
}
}
}
}
void randomBox::createRandomAbstraction2()
//use this in second abstraction layer maybe ey?
void createRandomAbstraction2()
{
//get a picture
cv::Mat PuzzlePicture = cv::imread("../../Codicil/Images/Balloons.jpg");
@ -207,30 +41,8 @@ void randomBox::createRandomAbstraction2()
}
}
void randomBox::putAllIntoBox() {
for (unsigned int i = 0; i < getRows(); i++)
{
for (unsigned int j = 0; j < getCols(); j++)
{
Box.push_back(getPiece(j,i));
}
}
}
//prints a box contents on console
void randomBox::printBox()
{
shuffle();
for (auto i:Box)
{
i.printPiece();
cout << ' ';
}
cout << endl;
}
//shuffles around a box, randomizing pieces and orientation
vector<PuzzlePiece> randomBox::shuffle()
vector<Part> randomBox::shuffle()
{
random_shuffle(Box.begin(),Box.end());
for (auto &i:Box)
@ -241,48 +53,4 @@ vector<PuzzlePiece> randomBox::shuffle()
numerateBox(Box);
return Box;
}
//creates a random box size m, n, shuffles it, and then retuns it
vector<PuzzlePiece> 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<PuzzlePiece> 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<PuzzlePiece>& myBox)
{
for(int i = 0; i< myBox.size();i++)
myBox[i].setBoxIdentifier(i);
}
std::vector<PuzzlePiece> convertPart2PuzzlePiece(std::vector<Part> simplePartBox)
{
std::vector<PuzzlePiece> advancedPartBox;
for(auto const &i:simplePartBox)
{
PuzzlePiece tmpNewPiece(0);
tmpNewPiece.setConnections(i.getConnections());
advancedPartBox.push_back(tmpNewPiece);
}
return advancedPartBox;
}

View File

@ -1,15 +1,15 @@
#include "../../header.h"
void status(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat);
void status(vector<LogEntry>& log, vector<Part*>& p_Box);
bool next(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
bool next(vector<LogEntry>& log, vector<Part*>& 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<LogEntry>& log, vector<PuzzlePiece*>& 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<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
void createNextLogElement(vector<LogEntry>& log, vector<Part*>& 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<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
coor calculateNextCoor(vector<LogEntry>& log, vector<Part*>& p_Box)
{
//level 1:
//go left to right, then increase current row
@ -68,15 +68,14 @@ coor calculateNextCoor(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzl
//return nextCoor;
}
void solve(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
void solve(vector<LogEntry>& log, vector<Part*>& 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<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat
}
void abstractionlayer0solver(vector<LogEntry>& log, vector<PuzzlePiece*>& 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<LogEntry>& log, vector<PuzzlePiece*>& 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<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
//removes from box and makes log "set"
void setsolution(vector<LogEntry>& log, vector<Part*>& 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;i<p_Box.size();)
if(p_Box[i]==log.back().PieceCollector[0])
if(p_Box[i]==log.back().PieceCollector.begin()->first)//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<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
bool backtrack(vector<LogEntry>& log, vector<Part*>& 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<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
void status(vector<LogEntry>& log, vector<Part*>& p_Box, puzzleMat)
{
cout << "----------------------------" << endl;
cout << "status:" << endl;
@ -254,7 +162,7 @@ void status(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMa
cout << "----------------------------" << endl;
}
void calculateTrueDestructionPower(vector<LogEntry>& log, Puzzle& puzzleMat, float Layerworth)
void calculateTrueDestructionPower(vector<LogEntry>& log, puzzleMat, float Layerworth)
{
//hier muss noch rein, wo die zeit der Abstractionlevels gespeichter wird
float destructionPower=sqrt(Layerworth * log.back().abstractionLevel);