2017-12-06 16:25:13 +01:00
|
|
|
#include "../../header.h"
|
2017-11-18 08:16:05 +01:00
|
|
|
|
|
|
|
//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))));
|
|
|
|
}
|
|
|
|
|
2017-11-18 08:36:50 +01:00
|
|
|
|
2017-11-18 08:16:05 +01:00
|
|
|
//creates random centerpiece
|
|
|
|
void PuzzlePiece::randomCenterPiece()
|
|
|
|
{
|
|
|
|
setConnections(0b00000000);
|
|
|
|
|
|
|
|
if(rand()%2)
|
2017-12-16 00:10:52 +01:00
|
|
|
setConnections(getConnections() | (uint8_t)0b01000000);
|
2017-11-18 08:16:05 +01:00
|
|
|
else
|
2017-12-16 00:10:52 +01:00
|
|
|
setConnections(getConnections() | (uint8_t)0b10000000);
|
2017-11-18 08:16:05 +01:00
|
|
|
|
|
|
|
if(rand()%2)
|
2017-12-16 00:10:52 +01:00
|
|
|
setConnections(getConnections() | (uint8_t)0b00010000);
|
2017-11-18 08:16:05 +01:00
|
|
|
else
|
2017-12-16 00:10:52 +01:00
|
|
|
setConnections(getConnections() | (uint8_t)0b00100000);
|
2017-11-18 08:16:05 +01:00
|
|
|
|
|
|
|
if(rand()%2)
|
2017-12-16 00:10:52 +01:00
|
|
|
setConnections(getConnections() | (uint8_t)0b00000100);
|
2017-11-18 08:16:05 +01:00
|
|
|
else
|
2017-12-16 00:10:52 +01:00
|
|
|
setConnections(getConnections() | (uint8_t)0b00001000);
|
2017-11-18 08:16:05 +01:00
|
|
|
|
|
|
|
if(rand()%2)
|
2017-12-16 00:10:52 +01:00
|
|
|
setConnections(getConnections() | (uint8_t)0b00000001);
|
2017-11-18 08:16:05 +01:00
|
|
|
else
|
2017-12-16 00:10:52 +01:00
|
|
|
setConnections(getConnections() | (uint8_t)0b00000010);
|
2017-11-18 08:16:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//tests the myPart in all 4 rotations at position m, n
|
2017-12-06 20:56:01 +01:00
|
|
|
bool Puzzle::testRotationPiece(coor myCoor, PuzzlePiece& myPart, int nrOfRotations)
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
2017-11-22 16:06:23 +01:00
|
|
|
for(int rotation=0; rotation < nrOfRotations; rotation++)
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
2017-12-06 20:56:01 +01:00
|
|
|
//coor myCoor(m,n);
|
|
|
|
if(PlaceOfPartGood(myCoor,myPart))
|
2017-12-13 10:47:15 +01:00
|
|
|
return true;
|
2017-11-28 21:35:49 +01:00
|
|
|
//cout << "was rotated in testRotationPiece" << endl;
|
2017-11-18 08:16:05 +01:00
|
|
|
myPart.shift(1);
|
|
|
|
}
|
2017-11-19 22:53:00 +01:00
|
|
|
|
|
|
|
//cout << "Was a bad part" << endl;
|
2017-12-13 10:47:15 +01:00
|
|
|
return false;
|
2017-11-18 08:16:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//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.
|
2017-12-06 20:56:01 +01:00
|
|
|
unsigned int Puzzle::putBackIntoBox(coor myCoor, vector<PuzzlePiece>& myBox)
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
|
|
|
#ifdef debug
|
|
|
|
cout << "putting back" << endl;
|
|
|
|
cout << "Old Box: ";
|
|
|
|
printBox(myBox);
|
|
|
|
cout << endl;
|
|
|
|
#endif
|
2017-12-16 00:10:52 +01:00
|
|
|
for(unsigned int i = 0; i < myBox.size();i++)
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
2017-12-16 00:10:52 +01:00
|
|
|
if(myBox[i].getBoxIdentifier()>getPiece(myCoor.col,myCoor.row).getBoxIdentifier())
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
2017-12-16 00:10:52 +01:00
|
|
|
myBox.insert(myBox.begin()+i,getPiece(myCoor.col,myCoor.row));
|
2017-12-06 20:56:01 +01:00
|
|
|
removePiece(myCoor);
|
2017-11-18 08:16:05 +01:00
|
|
|
return i+1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//using push back, if the element was the last element in the vector chain
|
2017-12-16 00:10:52 +01:00
|
|
|
myBox.push_back(getPiece(myCoor.col,myCoor.row));
|
2017-12-06 20:56:01 +01:00
|
|
|
removePiece(myCoor);
|
2017-11-18 08:16:05 +01:00
|
|
|
return myBox.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
//checks if the myPart in its current orientation is legal in position m, n
|
2017-12-06 20:56:01 +01:00
|
|
|
bool Puzzle::PlaceOfPartGood(coor myCoor, PuzzlePiece& myPart)
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
2017-11-18 09:50:09 +01:00
|
|
|
|
2017-11-18 08:16:05 +01:00
|
|
|
PuzzlePiece negativePart(0);
|
|
|
|
|
2017-12-16 00:10:52 +01:00
|
|
|
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));
|
2017-11-18 08:16:05 +01:00
|
|
|
negativePart.shift(2);
|
|
|
|
|
|
|
|
|
2017-12-16 00:10:52 +01:00
|
|
|
if (
|
2017-11-18 08:16:05 +01:00
|
|
|
( ((((negativePart.getConnections() & 0b11000000) ^ (myPart.getConnections() & 0b11000000)) != 0b00000000) && (((myPart.getConnections() & 0b11000000) != 0b00000000) && (negativePart.getConnections() & 0b11000000) != 0b00000000))
|
2017-11-19 22:53:00 +01:00
|
|
|
|| ((((negativePart.getConnections() & 0b11000000) == 0b11000000) || ((myPart.getConnections() & 0b11000000) == 0b11000000)) && (((myPart.getConnections() & 0b11000000) != 0b00000000) && (negativePart.getConnections() & 0b11000000) != 0b00000000))
|
2017-12-16 00:10:52 +01:00
|
|
|
|| (((negativePart.getConnections() & 0b11000000) == 0b00000000) && ((myPart.getConnections() & 0b11000000) == 0b00000000)) )
|
2017-11-18 08:16:05 +01:00
|
|
|
&&
|
|
|
|
( ((((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))
|
2017-12-16 00:10:52 +01:00
|
|
|
|| (((negativePart.getConnections() & 0b00110000) == 0b00000000) && ((myPart.getConnections() & 0b00110000) == 0b00000000)) )
|
2017-11-18 08:16:05 +01:00
|
|
|
&&
|
|
|
|
( ((((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))
|
2017-12-16 00:10:52 +01:00
|
|
|
|| (((negativePart.getConnections() & 0b00001100) == 0b00000000) && ((myPart.getConnections() & 0b00001100) == 0b00000000)) )
|
2017-11-18 08:16:05 +01:00
|
|
|
&&
|
|
|
|
( ((((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))
|
2017-12-16 00:10:52 +01:00
|
|
|
|| (((negativePart.getConnections() & 0b00000011) == 0b00000000) && ((myPart.getConnections() & 0b00000011) == 0b00000000)) )
|
2017-11-18 08:16:05 +01:00
|
|
|
)
|
2017-11-19 22:53:00 +01:00
|
|
|
{
|
|
|
|
//cout << "good Part: ";
|
|
|
|
//myPart.printPiece();
|
|
|
|
//cout << endl;
|
2017-12-13 10:47:15 +01:00
|
|
|
return true;
|
2017-11-18 08:16:05 +01:00
|
|
|
}
|
2017-11-19 22:53:00 +01:00
|
|
|
//cout << "bad Part: ";
|
|
|
|
//myPart.printPiece();
|
|
|
|
//cout << endl;
|
2017-11-18 08:16:05 +01:00
|
|
|
|
2017-12-13 10:47:15 +01:00
|
|
|
return false;
|
2017-11-18 09:50:09 +01:00
|
|
|
|
2017-11-18 08:16:05 +01:00
|
|
|
}
|
|
|
|
//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
|
2017-12-06 16:25:13 +01:00
|
|
|
|
|
|
|
void randomBox::createRandomAbstraction1()
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
2017-12-06 20:56:01 +01:00
|
|
|
coor myCoor;
|
2017-11-18 08:16:05 +01:00
|
|
|
PuzzlePiece temporaryRandomPiece(0);
|
2017-12-06 20:56:01 +01:00
|
|
|
|
2017-12-16 00:10:52 +01:00
|
|
|
for(unsigned int i=0;i<getRows();i++)
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
2017-12-16 00:10:52 +01:00
|
|
|
for(unsigned int j = 0; j < getCols();)
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
|
|
|
|
|
|
|
//create random piece, set edges according to position and check if piece is good
|
|
|
|
temporaryRandomPiece.randomCenterPiece();
|
|
|
|
if(i==0)
|
2017-12-16 00:10:52 +01:00
|
|
|
temporaryRandomPiece.setConnections((uint8_t)0b00111111 & temporaryRandomPiece.getConnections());
|
2017-11-18 08:16:05 +01:00
|
|
|
if(i==getRows()-1)
|
2017-12-16 00:10:52 +01:00
|
|
|
temporaryRandomPiece.setConnections((uint8_t)0b11110011 & temporaryRandomPiece.getConnections());
|
2017-11-18 08:16:05 +01:00
|
|
|
if(j==0)
|
2017-12-16 00:10:52 +01:00
|
|
|
temporaryRandomPiece.setConnections((uint8_t)0b11111100 & temporaryRandomPiece.getConnections());
|
2017-11-18 08:16:05 +01:00
|
|
|
if(j==getCols()-1)
|
2017-12-16 00:10:52 +01:00
|
|
|
temporaryRandomPiece.setConnections((uint8_t)0b11001111 & temporaryRandomPiece.getConnections());
|
2017-11-18 08:16:05 +01:00
|
|
|
|
2017-12-16 00:10:52 +01:00
|
|
|
myCoor.col = j;
|
|
|
|
myCoor.row = i;
|
2017-12-06 20:56:01 +01:00
|
|
|
if(PlaceOfPartGood(myCoor,temporaryRandomPiece))
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
|
|
|
temporaryRandomPiece.assignIdentifier();
|
2017-12-06 20:56:01 +01:00
|
|
|
setPiece(myCoor,temporaryRandomPiece);
|
2017-11-18 08:16:05 +01:00
|
|
|
j++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-06 16:25:13 +01:00
|
|
|
void randomBox::createRandomAbstraction2()
|
|
|
|
{
|
|
|
|
//get a picture
|
|
|
|
cv::Mat PuzzlePicture = cv::imread("../../Codicil/Images/Balloons.jpg");
|
|
|
|
if(! PuzzlePicture.data )
|
|
|
|
{
|
|
|
|
cout << "Could not open or find the image" << std::endl ;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
//split a picture into mxn pieces
|
|
|
|
cv::Size smallSize ((int)(PuzzlePicture.cols/getCols()) ,(int)(PuzzlePicture.rows/getRows()));
|
|
|
|
// get the image data
|
|
|
|
|
|
|
|
vector<cv::Mat> smallChannels;
|
|
|
|
unsigned int i=0,j=0;
|
|
|
|
for ( int y=0; y<=PuzzlePicture.rows-smallSize.height; y += smallSize.height )
|
|
|
|
{
|
|
|
|
|
|
|
|
for ( int x=0 ; x<=PuzzlePicture.cols-smallSize.width; x += smallSize.width )
|
|
|
|
{
|
|
|
|
//split into different ROIs
|
|
|
|
cv::Rect rect = cv::Rect (x ,y , smallSize.width, smallSize.height );
|
|
|
|
cv::Mat tmpSmallPicture = cv::Mat(PuzzlePicture,rect);
|
|
|
|
cv::split(tmpSmallPicture, smallChannels);
|
|
|
|
|
|
|
|
//save color into individual PuzzlePieces in Matrix
|
|
|
|
PuzzlePiece tmpPiece = getPiece(j,i);
|
|
|
|
tmpPiece.r = cv::mean(smallChannels[0]).operator[](0);
|
|
|
|
tmpPiece.g = cv::mean(smallChannels[1]).operator[](0);
|
|
|
|
tmpPiece.b = cv::mean(smallChannels[2]).operator[](0);
|
2017-12-07 16:26:45 +01:00
|
|
|
setPiece(coor(j,i),tmpPiece);
|
2017-12-06 16:25:13 +01:00
|
|
|
j++;
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
j=0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void randomBox::putAllIntoBox() {
|
2017-12-16 00:10:52 +01:00
|
|
|
for (unsigned int i = 0; i < getRows(); i++)
|
2017-12-06 16:25:13 +01:00
|
|
|
{
|
2017-12-16 00:10:52 +01:00
|
|
|
for (unsigned int j = 0; j < getCols(); j++)
|
2017-12-06 16:25:13 +01:00
|
|
|
{
|
|
|
|
Box.push_back(getPiece(j,i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-18 08:16:05 +01:00
|
|
|
//prints a box contents on console
|
|
|
|
void randomBox::printBox()
|
|
|
|
{
|
|
|
|
shuffle();
|
2017-12-13 10:47:15 +01:00
|
|
|
for (auto i:Box)
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
2017-12-13 10:47:15 +01:00
|
|
|
i.printPiece();
|
2017-11-18 08:16:05 +01:00
|
|
|
cout << ' ';
|
2017-12-06 16:25:13 +01:00
|
|
|
}
|
2017-11-18 08:16:05 +01:00
|
|
|
cout << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
//shuffles around a box, randomizing pieces and orientation
|
|
|
|
vector<PuzzlePiece> randomBox::shuffle()
|
|
|
|
{
|
|
|
|
random_shuffle(Box.begin(),Box.end());
|
2017-12-13 10:47:15 +01:00
|
|
|
for (auto &i:Box)
|
2017-12-06 16:25:13 +01:00
|
|
|
{
|
2017-12-13 10:47:15 +01:00
|
|
|
i.shift(rand()%4);
|
|
|
|
i.resetShift();
|
2017-12-06 16:25:13 +01:00
|
|
|
}
|
|
|
|
|
2017-11-18 08:16:05 +01:00
|
|
|
numerateBox(Box);
|
|
|
|
return Box;
|
|
|
|
}
|
|
|
|
|
|
|
|
//creates a random box size m, n, shuffles it, and then retuns it
|
2017-12-06 20:56:01 +01:00
|
|
|
vector<PuzzlePiece> createBox(coor myCoor)
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
2017-12-16 00:10:52 +01:00
|
|
|
randomBox myFirstPuzzleBox(myCoor.col,myCoor.row);
|
2017-12-06 16:25:13 +01:00
|
|
|
myFirstPuzzleBox.createRandomAbstraction1();
|
|
|
|
myFirstPuzzleBox.createRandomAbstraction2();
|
|
|
|
myFirstPuzzleBox.putAllIntoBox();
|
|
|
|
|
|
|
|
myFirstPuzzleBox.printPuzzle();
|
|
|
|
return myFirstPuzzleBox.shuffle();
|
2017-11-18 08:16:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//prints contents of box
|
|
|
|
void printBox(vector<PuzzlePiece> myBox)
|
|
|
|
{
|
|
|
|
cout << "current Box: " << endl;
|
2017-12-13 10:47:15 +01:00
|
|
|
for (auto &i:myBox)
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
2017-12-13 10:47:15 +01:00
|
|
|
i.printPiece();
|
2017-11-18 08:16:05 +01:00
|
|
|
cout << ' ';
|
2017-12-06 16:25:13 +01:00
|
|
|
}
|
2017-11-18 08:16:05 +01:00
|
|
|
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);
|
|
|
|
|
2017-11-30 14:19:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<PuzzlePiece> convertPart2PuzzlePiece(std::vector<Part> simplePartBox)
|
|
|
|
{
|
|
|
|
std::vector<PuzzlePiece> advancedPartBox;
|
2017-12-13 10:47:15 +01:00
|
|
|
for(auto const &i:simplePartBox)
|
2017-11-30 14:19:25 +01:00
|
|
|
{
|
|
|
|
PuzzlePiece tmpNewPiece(0);
|
2017-12-13 10:47:15 +01:00
|
|
|
tmpNewPiece.setConnections(i.getConnections());
|
2017-11-30 14:19:25 +01:00
|
|
|
advancedPartBox.push_back(tmpNewPiece);
|
|
|
|
}
|
|
|
|
return advancedPartBox;
|
2017-11-18 08:16:05 +01:00
|
|
|
}
|