#include #define NR_PARTS 1008 #define NR_CORNERS 4 #define NR_EDGES 120 #define NR_INNERS 884 using namespace std; //part from group header file class Part { public: Part(): connections(0){} ~Part() {} uint8_t getConnections() const { return connections; } void setConnections(uint8_t newconnections) { connections = newconnections; } private: uint8_t connections; }; //puzzlepiece extens part with essential identifiers and functions 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; } } 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; }; unsigned int PuzzlePiece::idcount(0); class Puzzle { friend class randomBox; public: //constructor creates matrix with 00 outside and 11 inside Puzzle(uint m = 7, uint n = 4): col(m), row(n) { Matrix = new PuzzlePiece* [n+2]; for(int i = 0;i& myBox, unsigned int separator); unsigned int putBackIntoBox(unsigned int m, unsigned int n, vector& myBox); private: uint row; uint col; PuzzlePiece** Matrix; }; //use this for random puzzle creation class randomBox: public Puzzle { public: randomBox(unsigned int m, unsigned int n) : Puzzle(m,n) {} //passed m n to puzzle constructor void createRandomPuzzle(); vector shuffle(); void printBox(); private: vector Box; }; //functiondefinitions void printBox(vector myBox); vector createBox(uint m, uint n); void numerateBox(vector& myBox); //functions //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() | 0b01000000); else setConnections(getConnections() | 0b10000000); if(rand()%2) setConnections(getConnections() | 0b00010000); else setConnections(getConnections() | 0b00100000); if(rand()%2) setConnections(getConnections() | 0b00000100); else setConnections(getConnections() | 0b00001000); if(rand()%2) setConnections(getConnections() | 0b00000001); else setConnections(getConnections() | 0b00000010); } //tries all pieces in box from separator to end and places fitting into matrix. removes fitting piece //use separator if you have to retract to a position //seperator may be bigger than box size, if all puzzle pieces have already been looked at. // it immediately retracts again then (returns -1) unsigned int Puzzle::tryAllPieces(unsigned int m, unsigned int n, vector& myBox, unsigned int separator) { for(int i=separator; i& myBox) { #ifdef debug cout << "putting back" << endl; cout << "Old Box: "; printBox(myBox); cout << endl; #endif for(int i = 0; i < myBox.size();i++) { if(myBox[i].getBoxIdentifier()>getPiece(m,n).getBoxIdentifier()) { myBox.insert(myBox.begin()+i,getPiece(m,n)); removePiece(m,n); return i+1; } } //using push back, if the element was the last element in the vector chain myBox.push_back(getPiece(m,n)); removePiece(m,n); return myBox.size(); } //checks if the myPart in its current orientation is legal in position m, n bool Puzzle::PlaceOfPartGood(unsigned int m,unsigned int n, PuzzlePiece& myPart) { PuzzlePiece negativePart(0); negativePart.setConnections(negativePart.getConnections() | (getPiece(m,n+1).getConnections() & 0b11000000)); negativePart.setConnections(negativePart.getConnections() | (getPiece(m-1,n).getConnections() & 0b00110000)); negativePart.setConnections(negativePart.getConnections() | (getPiece(m,n-1).getConnections() & 0b00001100)); negativePart.setConnections(negativePart.getConnections() | (getPiece(m+1,n).getConnections() & 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)) ) ) { #ifdef debug cout << "good Part: "; myPart.printPiece(); cout << endl; #endif return 1; } return 0; } //TODO!! //simpler algorithm to the first placeofpartgood //not yet functional!!! bool Puzzle::PlaceOfPart2Good(unsigned int m,unsigned int n, PuzzlePiece& myPart) { /* PuzzlePiece negativePart(0); negativePart.setConnections(negativePart.getConnections() | (getPiece(m,n+1).getConnections() & 0b11000000)); negativePart.setConnections(negativePart.getConnections() | (getPiece(m-1,n).getConnections() & 0b00110000)); negativePart.setConnections(negativePart.getConnections() | (getPiece(m,n-1).getConnections() & 0b00001100)); negativePart.setConnections(negativePart.getConnections() | (getPiece(m+1,n).getConnections() & 0b00000011)); negativePart.shift(2); //A and D or B and C or not A and not B and not C and not D if ( ( ( (negativePart.getConnections() & 0b10000000) & (myPart.getConnections() & 0b01000000)) || ( (negativePart.getConnections() & 0b01000000) & (myPart.getConnections() & 0b10000000)) || ((!(negativePart.getConnections() & 0b10000000) & !(myPart.getConnections() & 0b10000000)) & (!(negativePart.getConnections() & 0b01000000) & !(myPart.getConnections() & 0b01000000))) ) && ( ( (negativePart.getConnections() & 0b00100000) & (myPart.getConnections() & 0b00010000)) || ( (negativePart.getConnections() & 0b00010000) & (myPart.getConnections() & 0b00100000)) || ((!(negativePart.getConnections() & 0b00100000) & !(myPart.getConnections() & 0b00100000)) & (!(negativePart.getConnections() & 0b00010000) & !(myPart.getConnections() & 0b00010000))) ) && ( ( (negativePart.getConnections() & 0b00001000) & (myPart.getConnections() & 0b00000100)) || ( (negativePart.getConnections() & 0b00000100) & (myPart.getConnections() & 0b00001000)) || ((!(negativePart.getConnections() & 0b00001000) & !(myPart.getConnections() & 0b00001000)) & (!(negativePart.getConnections() & 0b00000100) & !(myPart.getConnections() & 0b00000100))) ) && ( ( (negativePart.getConnections() & 0b00000010) & (myPart.getConnections() & 0b00000001)) || ( (negativePart.getConnections() & 0b00000001) & (myPart.getConnections() & 0b00000010)) || ((!(negativePart.getConnections() & 0b00000010) & !(myPart.getConnections() & 0b00000010)) & (!(negativePart.getConnections() & 0b00000001) & !(myPart.getConnections() & 0b00000001))) ) ) return 1; cout << "nogood" << endl; return 0; */ PuzzlePiece tmpPuzzlePiece = myPart; //make tmp a negativ part if((tmpPuzzlePiece.Ringbuffer & 0b11000000) != 192 || 0) tmpPuzzlePiece.Ringbuffer = (tmpPuzzlePiece.Ringbuffer ^ 0b11000000); if((tmpPuzzlePiece.Ringbuffer & 0b00110000) != 48 || 0) tmpPuzzlePiece.Ringbuffer = (tmpPuzzlePiece.Ringbuffer ^ 0b00110000); if((tmpPuzzlePiece.Ringbuffer & 0b00001100) != 12 || 0) tmpPuzzlePiece.Ringbuffer = (tmpPuzzlePiece.Ringbuffer ^ 0b00001100); if((tmpPuzzlePiece.Ringbuffer & 0b00000011) != 3 || 0) tmpPuzzlePiece.Ringbuffer = (tmpPuzzlePiece.Ringbuffer ^ 0b00000011); PuzzlePiece negativePart(0); negativePart.Ringbuffer = negativePart.Ringbuffer | (this->sudogetPiece(m,n+1).Ringbuffer & 0b11000000); negativePart.Ringbuffer = negativePart.Ringbuffer | (this->sudogetPiece(m-1,n).Ringbuffer & 0b00110000); negativePart.Ringbuffer = negativePart.Ringbuffer | (this->sudogetPiece(m,n-1).Ringbuffer & 0b00001100); negativePart.Ringbuffer = negativePart.Ringbuffer | (this->sudogetPiece(m+1,n).Ringbuffer & 0b00000011); negativePart.Shift(2); //check tmp part with environment if(((negativePart.Ringbuffer & 0b11000000) == (tmpPuzzlePiece & 0b11000000)) && ((negativePart.Ringbuffer & 0b00110000) == (tmpPuzzlePiece & 0b00110000)) && ((negativePart.Ringbuffer & 0b00001100) == (tmpPuzzlePiece & 0b00001100)) && ((negativePart.Ringbuffer & 0b00000011) == (tmpPuzzlePiece & 0b00000011))) return 1; return 0; } //prints the true puzzle (without 0 edges) void Puzzle::printPuzzle() { cout << "current Puzzle: " << endl; for(int i=1;i::iterator i = Box.begin(); i != Box.end(); i++) { (*i).printPiece(); cout << ' '; } cout << endl; } //shuffles around a box, randomizing pieces and orientation vector randomBox::shuffle() { random_shuffle(Box.begin(),Box.end()); for (vector::iterator i = Box.begin(); i != Box.end(); i++) (*i).shift(rand()%4); numerateBox(Box); return Box; } //creates a random box size m, n, shuffles it, and then retuns it vector createBox(uint m, uint n) { randomBox myFirstPuzzleBox(m,n); myFirstPuzzleBox.createRandomPuzzle(); return myFirstPuzzleBox.shuffle(); } //prints contents of box void printBox(vector myBox) { cout << "current Box: " << endl; for (vector::iterator i = myBox.begin(); i != myBox.end(); i++) { (*i).printPiece(); cout << ' '; } cout << endl; return; } //gives every element in box a box identifier. void numerateBox(vector& myBox) { for(int i = 0; i< myBox.size();i++) myBox[i].setBoxIdentifier(i); return; }