removed bugs. some puzzles take forever. most can be solved

This commit is contained in:
g-spacewhale 2017-11-19 22:53:00 +01:00
parent 15940f41da
commit aa00553bdb
4 changed files with 165 additions and 49 deletions

View File

@ -57,15 +57,12 @@ bool Puzzle::testRotationPiece(unsigned int m, unsigned int n, PuzzlePiece& myPa
{ {
for(int rotation=0; rotation < 4; rotation++) for(int rotation=0; rotation < 4; rotation++)
{ {
if(PlaceOfPartGood(m,n, myPart)) if(PlaceOfPartGood(m,n,myPart))
return 1; return 1;
myPart.shift(1); myPart.shift(1);
} }
#ifdef debug
cout << "bad part: "; //cout << "Was a bad part" << endl;
myPart.printPiece();
cout << endl;
#endif
return 0; return 0;
} }
@ -107,10 +104,9 @@ bool Puzzle::PlaceOfPartGood(unsigned int m,unsigned int n, PuzzlePiece& myPart)
negativePart.shift(2); negativePart.shift(2);
if ( if (
( ((((negativePart.getConnections() & 0b11000000) ^ (myPart.getConnections() & 0b11000000)) != 0b00000000) && (((myPart.getConnections() & 0b11000000) != 0b00000000) && (negativePart.getConnections() & 0b11000000) != 0b00000000)) ( ((((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) == 0b11000000) || ((myPart.getConnections() & 0b11000000) == 0b11000000)) && (((myPart.getConnections() & 0b11000000) != 0b00000000) && (negativePart.getConnections() & 0b11000000) != 0b00000000))
|| (((negativePart.getConnections() & 0b11000000) == 0b00000000) && ((myPart.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) ^ (myPart.getConnections() & 0b00110000)) != 0b00000000) && (((myPart.getConnections() & 0b00110000) != 0b00000000) && (negativePart.getConnections() & 0b00110000) != 0b00000000))
@ -126,13 +122,14 @@ bool Puzzle::PlaceOfPartGood(unsigned int m,unsigned int n, PuzzlePiece& myPart)
|| (((negativePart.getConnections() & 0b00000011) == 0b00000000) && ((myPart.getConnections() & 0b00000011) == 0b00000000)) ) || (((negativePart.getConnections() & 0b00000011) == 0b00000000) && ((myPart.getConnections() & 0b00000011) == 0b00000000)) )
) )
{ {
#ifdef debug //cout << "good Part: ";
cout << "good Part: "; //myPart.printPiece();
myPart.printPiece(); //cout << endl;
cout << endl;
#endif
return 1; return 1;
} }
//cout << "bad Part: ";
//myPart.printPiece();
//cout << endl;
return 0; return 0;

View File

@ -1,29 +1,55 @@
void status(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat);
bool next(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat) bool next(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
{ {
//case first log entry empty
//status(log,p_Box,puzzleMat);
//log not yet started
if(!(log.size())) if(!(log.size()))
{ {
//cout << "creating new log" << endl;
log.push_back(LogEntry()); log.push_back(LogEntry());
log.back().myCoor = calculateFirstCoor(log, p_Box, puzzleMat);
solve(log, p_Box,puzzleMat); solve(log, p_Box,puzzleMat);
} }
//case puzzle solved
else if(!(p_Box.size()))
return 0;
//case last log multiple entries //last log element is set, create new log element
else if(log.back().isSet())
{
if(!(p_Box.size()))
{
cout << "box done" << endl;
return 0;
}
log.push_back(LogEntry());
log.back().myCoor = calculateNextCoor(log, p_Box, puzzleMat);
solve(log, p_Box,puzzleMat);
}
//last log element is empty, backtrack
else if(!(log.back().PieceCollector.size()))
{
//cout << "backtracking" << endl;
backtrack(log,p_Box,puzzleMat);
}
//case last log element has multiple entries
else if(log.back().PieceCollector.size() > 1) else if(log.back().PieceCollector.size() > 1)
{ {
//advance abstraction layer of last log by one and solve() //is not yet max abstracted
//or pick first if highest level reached
if(log.back().abstractionLevel < MAX_ABSTRAX) if(log.back().abstractionLevel < MAX_ABSTRAX)
{ {
//cout << "advancing abstraction layer" << endl;
log.back().advance(); log.back().advance();
solve(log,p_Box,puzzleMat); solve(log,p_Box,puzzleMat);
} }
//no more layers, pick first
else else
{ {
//cout << "setting first as solution" << endl;
log.back().advanceRandomed();
setsolution(log,p_Box,puzzleMat); setsolution(log,p_Box,puzzleMat);
} }
} }
@ -31,18 +57,28 @@ bool next(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
//case last log exactly one solution //case last log exactly one solution
else if(log.back().PieceCollector.size() == 1) else if(log.back().PieceCollector.size() == 1)
{ {
//create new log, put next coordinates in and go into solve. then git gud //cout << "exactly one solution" << endl;
log.push_back(LogEntry()); if(log.back().hasRandomed())
log.back().myCoor = calculateNextCoor(log, p_Box, puzzleMat); {
solve(log, p_Box,puzzleMat); if(log.back().abstractionLevel < MAX_ABSTRAX)
} {
//cout << "advancing abstraction layer" << endl;
//case last log empty log.back().advance();
//backtrack solve(log,p_Box,puzzleMat);
else if(log.back().PieceCollector.size() == 0) }
{ else
backtrack(log,p_Box,puzzleMat); {
//cout << "setting as solution bec fit" << endl;
setsolution(log,p_Box,puzzleMat);
}
}
else
{
//cout << "setting as solution bec trivial" << endl;
setsolution(log,p_Box,puzzleMat);
}
} }
//cout << "next" << endl;
return 1; return 1;
} }
@ -59,10 +95,10 @@ coor calculateNextCoor(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzl
{ {
//level 1: //level 1:
//go left to right, then increase current row //go left to right, then increase current row
int m= log.back().myCoor.m; int m= log.rbegin()[1].myCoor.m;
int n= log.back().myCoor.n; int n= log.rbegin()[1].myCoor.n;
if(m<puzzleMat.getCols()) m++; if(m<puzzleMat.getCols()-1) m++;
else if(n<puzzleMat.getRows()){ m=0; n++;} else if(n<puzzleMat.getRows()-1){ m=0; n++;}
else return coor(); else return coor();
; ;
@ -72,6 +108,7 @@ coor calculateNextCoor(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzl
void solve(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat) void solve(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
{ {
//status(log,p_Box,puzzleMat);
switch(log.back().abstractionLevel) switch(log.back().abstractionLevel)
{ {
//abstraction layer = 0 //abstraction layer = 0
@ -88,35 +125,55 @@ void solve(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat
default: default:
break; break;
} }
//status(log,p_Box,puzzleMat);
} }
void abstractionlayer0solver(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 //throw all remaining puzzle pieces into newest log
for(int i=0;i<p_Box.size();i++) for(int i=0;i<p_Box.size();i++)
log.back().PieceCollector[i]=p_Box[i]; log.back().PieceCollector.push_back(p_Box[i]);
} }
void abstractionlayer1solver(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat) void abstractionlayer1solver(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
{ {
//remove all that do not fit according to abstraction layer 0 //remove all that do not fit according to abstraction layer 0
for(int i=0;i<log.back().PieceCollector.size();i++) for(int i=0;i<(log.back().PieceCollector.size());)
{ {
if(!(puzzleMat.testRotationPiece(log.back().myCoor.m, log.back().myCoor.n, *(log.back().PieceCollector[i])))) if(!(puzzleMat.testRotationPiece(log.back().myCoor.m, log.back().myCoor.n, *(log.back().PieceCollector[i]))))
{
log.back().PieceCollector.erase(log.back().PieceCollector.begin()+i); log.back().PieceCollector.erase(log.back().PieceCollector.begin()+i);
}
else
i++; //otherwise loop stops before end!
} }
//for(int i=0;i<log.back().PieceCollector.size();i++)
//{
// (*(log.back().PieceCollector[i])).printPiece();
// cout << endl;
//}
} }
void setsolution(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat) void setsolution(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
{ {
//remove first element in last logelement from box //remove first element in last logelement from box
for(int i=0;i<p_Box.size();i++) for(int i=0;i<p_Box.size();)
if(p_Box[i]==log.back().PieceCollector[0]) if(p_Box[i]==log.back().PieceCollector[0])
p_Box.erase(p_Box.begin()+i); p_Box.erase(p_Box.begin()+i);
else
i++;
//set to this element into matrix //turn piece until it fits and then set element into matrix
if(puzzleMat.testRotationPiece(log.back().myCoor.m, log.back().myCoor.n,*(log.back().PieceCollector[0])))
puzzleMat.setPiece(log.back().myCoor.m, log.back().myCoor.n, *(log.back().PieceCollector[0])); puzzleMat.setPiece(log.back().myCoor.m, log.back().myCoor.n, *(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<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
@ -127,7 +184,10 @@ bool backtrack(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzl
if(!(log.back().PieceCollector.size())) if(!(log.back().PieceCollector.size()))
{ {
log.back().PieceCollector.pop_back(); //cout << "none" << endl;
puzzleMat.removePiece(log.back().myCoor.m, log.back().myCoor.n);
log.pop_back();
//status(log,p_Box,puzzleMat);
backtrack(log,p_Box,puzzleMat); backtrack(log,p_Box,puzzleMat);
return 1; return 1;
} }
@ -136,9 +196,12 @@ bool backtrack(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzl
//delete last logd put back into box + backtrack //delete last logd put back into box + backtrack
else if((log.back().PieceCollector.size())==1) else if((log.back().PieceCollector.size())==1)
{ {
//cout << "one" << endl;
p_Box.push_back(log.back().PieceCollector[0]); p_Box.push_back(log.back().PieceCollector[0]);
log.back().PieceCollector.pop_back(); puzzleMat.removePiece(log.back().myCoor.m, log.back().myCoor.n);
//TODO remove from puzzle as well!!! log.pop_back();
//cout << "removed" << endl;
//status(log,p_Box,puzzleMat);
backtrack(log,p_Box,puzzleMat); backtrack(log,p_Box,puzzleMat);
return 1; return 1;
} }
@ -146,8 +209,15 @@ bool backtrack(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzl
//delete randomed piece from PieceCollector and go to next (which might random again depending on function) //delete randomed piece from PieceCollector and go to next (which might random again depending on function)
else if((log.back().PieceCollector.size())>1) else if((log.back().PieceCollector.size())>1)
{ {
//cout << "multiple" << endl;
p_Box.push_back(log.back().PieceCollector[0]); p_Box.push_back(log.back().PieceCollector[0]);
log.back().PieceCollector.erase(log.back().PieceCollector.begin()); log.back().PieceCollector.erase(log.back().PieceCollector.begin());
if(log.back().PieceCollector.size()==1)
log.back().decreaseRandomed();
//cout << "erased first element" << endl;
//status(log,p_Box,puzzleMat);
setsolution(log,p_Box,puzzleMat); setsolution(log,p_Box,puzzleMat);
return 1; return 1;
//no need to remove from puzzle mat, as sersolution overwrites it anyway //no need to remove from puzzle mat, as sersolution overwrites it anyway
@ -156,3 +226,35 @@ bool backtrack(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzl
return 0; return 0;
} }
void status(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
{
cout << "----------------------------" << endl;
cout << "status:" << endl;
cout << "hasrandomed: " << log[0].hasRandomed() << endl;
for(int i=0;i<log.size();i++)
{
cout << "log #" << i << ":" << endl;
cout << "piecenr " << log[i].PieceCollector.size() << endl;
if(log[i].isSet())
cout << "isset: 1" << endl;
else
cout << "isset: 0" << endl;
cout << "Abstraction: " << log[i].abstractionLevel << endl;
cout << "m: " << log[i].myCoor.m << " n: " << log[i].myCoor.n << endl;
/*for(int j=0;j<log[i].PieceCollector.size();j++)
{
(*(log[i].PieceCollector[j])).printPiece();
cout << endl;
}*/
}
cout << endl;
cout << "Box:" << endl;
cout << "size: " << p_Box.size() << endl;
cout << "Puzzle:" << endl;
puzzleMat.printPuzzle();
cout << "----------------------------" << endl;
}

View File

@ -40,7 +40,7 @@ private:
static unsigned int idcount; static unsigned int idcount;
}; };
unsigned int PuzzlePiece::idcount(0);
class Puzzle class Puzzle
{ {
@ -139,14 +139,26 @@ public:
coor myCoor = coor(); coor myCoor = coor();
void advance(){abstractionLevel++;} void advance(){abstractionLevel++;}
void Set(){set=1;}
bool isSet(){return set;}
void advanceRandomed() { randomed++;}
void decreaseRandomed() { randomed--;}
int hasRandomed(){return randomed;}
LogEntry() LogEntry()
{ {
abstractionLevel=0; abstractionLevel=0;
set=0;
} }
private: private:
bool set;
static int randomed;
}; };
int LogEntry::randomed(0);
unsigned int PuzzlePiece::idcount(0);
void printBox(vector<PuzzlePiece> myBox); void printBox(vector<PuzzlePiece> myBox);
vector<PuzzlePiece> createBox(uint m, uint n); vector<PuzzlePiece> createBox(uint m, uint n);
void numerateBox(vector<PuzzlePiece>& myBox); void numerateBox(vector<PuzzlePiece>& myBox);

View File

@ -1,4 +1,5 @@
#define MAX_ABSTRAX 1 #define MAX_ABSTRAX 1
#define structdebug
#include "header.h" #include "header.h"
@ -7,7 +8,7 @@
int main() int main()
{ {
int cols=3, rows=2; int cols=10, rows=10;
//some basic part stuff //some basic part stuff
vector<Part> myFirstPuzzle; vector<Part> myFirstPuzzle;
Part myFirstPart; Part myFirstPart;
@ -18,7 +19,6 @@ int main()
randomBox myRandomBox(cols,rows); randomBox myRandomBox(cols,rows);
myRandomBox.createRandomPuzzle(); myRandomBox.createRandomPuzzle();
vector<PuzzlePiece> myFirstBox = myRandomBox.shuffle(); vector<PuzzlePiece> myFirstBox = myRandomBox.shuffle();
myRandomBox.printPuzzle();
@ -26,9 +26,14 @@ int main()
vector<LogEntry> log; vector<LogEntry> log;
vector<PuzzlePiece*> p_myFirstBox; vector<PuzzlePiece*> p_myFirstBox;
cout << "original puzzle: " << endl;
myRandomBox.printPuzzle();
cout << endl;
for(int i=0;i<myFirstBox.size();i++) for(int i=0;i<myFirstBox.size();i++)
p_myFirstBox[i] = &myFirstBox[i]; p_myFirstBox.push_back(&myFirstBox[i]);
Puzzle puzzleMat(cols, rows); Puzzle puzzleMat(cols, rows);
while(next(log, p_myFirstBox,puzzleMat)); while(next(log, p_myFirstBox,puzzleMat));
puzzleMat.printPuzzle();
} }