2017-11-19 22:53:00 +01:00
|
|
|
void status(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat);
|
|
|
|
|
2017-11-18 08:16:05 +01:00
|
|
|
|
2017-11-18 22:48:40 +01:00
|
|
|
bool next(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
2017-11-19 22:53:00 +01:00
|
|
|
//log not yet started
|
2017-12-03 20:12:32 +01:00
|
|
|
/*
|
2017-11-19 17:52:02 +01:00
|
|
|
if(!(log.size()))
|
2017-12-03 20:12:32 +01:00
|
|
|
{
|
2017-11-28 21:35:49 +01:00
|
|
|
log.push_back(LogEntry());
|
2017-12-03 20:12:32 +01:00
|
|
|
log.back().myCoor = calculateNextCoor(log, p_Box, puzzleMat);
|
|
|
|
solve(log, p_Box,puzzleMat);
|
2017-11-18 22:48:40 +01:00
|
|
|
}
|
2017-12-03 20:12:32 +01:00
|
|
|
*/
|
2017-11-18 22:48:40 +01:00
|
|
|
|
2017-11-19 22:53:00 +01:00
|
|
|
//last log element is set, create new log element
|
2017-12-03 20:12:32 +01:00
|
|
|
if(!(log.size()) || log.back().isSet())
|
2017-11-19 22:53:00 +01:00
|
|
|
{
|
|
|
|
if(!(p_Box.size()))
|
|
|
|
{
|
|
|
|
cout << "box done" << endl;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
log.push_back(LogEntry());
|
2017-12-03 20:12:32 +01:00
|
|
|
log.back().myCoor = calculateNextCoor(log, p_Box, puzzleMat);
|
|
|
|
solve(log, p_Box,puzzleMat);
|
2017-11-19 22:53:00 +01:00
|
|
|
}
|
2017-11-21 15:07:15 +01:00
|
|
|
|
2017-11-19 22:53:00 +01:00
|
|
|
//last log element is empty, backtrack
|
|
|
|
else if(!(log.back().PieceCollector.size()))
|
|
|
|
backtrack(log,p_Box,puzzleMat);
|
2017-11-18 08:16:05 +01:00
|
|
|
|
2017-11-19 22:53:00 +01:00
|
|
|
//case last log element has multiple entries
|
2017-11-18 22:48:40 +01:00
|
|
|
else if(log.back().PieceCollector.size() > 1)
|
|
|
|
{
|
2017-11-19 22:53:00 +01:00
|
|
|
//is not yet max abstracted
|
2017-11-19 17:52:02 +01:00
|
|
|
if(log.back().abstractionLevel < MAX_ABSTRAX)
|
2017-11-18 22:48:40 +01:00
|
|
|
{
|
2017-11-28 21:35:49 +01:00
|
|
|
log.back().advance();
|
2017-12-03 20:12:32 +01:00
|
|
|
solve(log,p_Box,puzzleMat);
|
2017-11-18 22:48:40 +01:00
|
|
|
}
|
2017-11-19 22:53:00 +01:00
|
|
|
//no more layers, pick first
|
2017-11-18 22:48:40 +01:00
|
|
|
else
|
|
|
|
{
|
2017-11-19 22:53:00 +01:00
|
|
|
log.back().advanceRandomed();
|
2017-11-18 22:48:40 +01:00
|
|
|
setsolution(log,p_Box,puzzleMat);
|
|
|
|
}
|
|
|
|
}
|
2017-11-18 08:16:05 +01:00
|
|
|
|
2017-11-18 22:48:40 +01:00
|
|
|
//case last log exactly one solution
|
|
|
|
else if(log.back().PieceCollector.size() == 1)
|
2017-12-03 20:12:32 +01:00
|
|
|
{
|
2017-11-19 22:53:00 +01:00
|
|
|
if(log.back().hasRandomed())
|
|
|
|
{
|
|
|
|
if(log.back().abstractionLevel < MAX_ABSTRAX)
|
|
|
|
{
|
2017-11-28 21:35:49 +01:00
|
|
|
log.back().advance();
|
2017-12-03 20:12:32 +01:00
|
|
|
solve(log,p_Box,puzzleMat);
|
2017-11-19 22:53:00 +01:00
|
|
|
}
|
|
|
|
else
|
2017-11-28 21:35:49 +01:00
|
|
|
setsolution(log,p_Box,puzzleMat);
|
2017-11-19 22:53:00 +01:00
|
|
|
}
|
|
|
|
else
|
2017-11-28 21:35:49 +01:00
|
|
|
setsolution(log,p_Box,puzzleMat);
|
2017-11-21 16:05:38 +01:00
|
|
|
}
|
2017-11-21 10:31:48 +01:00
|
|
|
return 1;
|
2017-11-18 22:48:40 +01:00
|
|
|
}
|
2017-11-18 08:16:05 +01:00
|
|
|
|
2017-12-03 20:12:32 +01:00
|
|
|
/*
|
2017-11-18 22:48:40 +01:00
|
|
|
coor calculateFirstCoor(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
|
|
|
|
{
|
|
|
|
//returns coor of first piece
|
|
|
|
coor firstCoor(0,0);
|
|
|
|
return firstCoor;
|
2017-11-18 08:16:05 +01:00
|
|
|
}
|
2017-12-03 20:12:32 +01:00
|
|
|
*/
|
2017-11-18 08:16:05 +01:00
|
|
|
|
2017-11-18 22:48:40 +01:00
|
|
|
coor calculateNextCoor(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
2017-11-18 22:48:40 +01:00
|
|
|
//level 1:
|
|
|
|
//go left to right, then increase current row
|
2017-12-03 20:12:32 +01:00
|
|
|
|
|
|
|
if (log.size() == 1)
|
|
|
|
return coor(0,0);
|
|
|
|
|
|
|
|
|
2017-11-19 22:53:00 +01:00
|
|
|
int m= log.rbegin()[1].myCoor.m;
|
|
|
|
int n= log.rbegin()[1].myCoor.n;
|
2017-12-03 20:12:32 +01:00
|
|
|
|
|
|
|
|
2017-11-19 22:53:00 +01:00
|
|
|
if(m<puzzleMat.getCols()-1) m++;
|
|
|
|
else if(n<puzzleMat.getRows()-1){ m=0; n++;}
|
2017-11-19 17:52:02 +01:00
|
|
|
else return coor();
|
|
|
|
return coor(m,n);
|
2017-11-18 22:48:40 +01:00
|
|
|
//return nextCoor;
|
|
|
|
}
|
|
|
|
|
|
|
|
void solve(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
|
|
|
|
{
|
2017-11-19 22:53:00 +01:00
|
|
|
//status(log,p_Box,puzzleMat);
|
2017-11-19 17:52:02 +01:00
|
|
|
switch(log.back().abstractionLevel)
|
2017-11-18 22:48:40 +01:00
|
|
|
{
|
2017-11-19 17:52:02 +01:00
|
|
|
//abstraction layer = 0
|
|
|
|
//go to abstraction layer 0 solver
|
2017-11-18 22:48:40 +01:00
|
|
|
case 0:
|
2017-11-19 17:52:02 +01:00
|
|
|
abstractionlayer0solver(log,p_Box,puzzleMat);
|
2017-11-18 22:48:40 +01:00
|
|
|
break;
|
|
|
|
|
2017-11-19 17:52:02 +01:00
|
|
|
//abstraction layer = 1
|
|
|
|
//go to abstraction layer 1 solver
|
2017-11-18 22:48:40 +01:00
|
|
|
case 1:
|
2017-11-19 17:52:02 +01:00
|
|
|
abstractionlayer1solver(log,p_Box,puzzleMat);
|
|
|
|
break;
|
2017-11-21 15:07:15 +01:00
|
|
|
|
2017-11-19 17:52:02 +01:00
|
|
|
default:
|
2017-11-18 22:48:40 +01:00
|
|
|
break;
|
|
|
|
}
|
2017-11-18 08:16:05 +01:00
|
|
|
}
|
|
|
|
|
2017-11-19 17:52:02 +01:00
|
|
|
void abstractionlayer0solver(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
2017-11-18 22:48:40 +01:00
|
|
|
//throw all remaining puzzle pieces into newest log
|
2017-11-19 17:52:02 +01:00
|
|
|
for(int i=0;i<p_Box.size();i++)
|
2017-11-19 22:53:00 +01:00
|
|
|
log.back().PieceCollector.push_back(p_Box[i]);
|
2017-11-18 08:16:05 +01:00
|
|
|
}
|
|
|
|
|
2017-11-19 17:52:02 +01:00
|
|
|
void abstractionlayer1solver(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
2017-11-19 17:52:02 +01:00
|
|
|
//remove all that do not fit according to abstraction layer 0
|
2017-11-19 22:53:00 +01:00
|
|
|
for(int i=0;i<(log.back().PieceCollector.size());)
|
2017-11-19 17:52:02 +01:00
|
|
|
{
|
2017-11-22 16:06:23 +01:00
|
|
|
(*(log.back().PieceCollector[i])).resetShift();
|
2017-11-21 11:19:51 +01:00
|
|
|
//TODO: change checker from checking every box piece to only checking the simplifyed version ob the box with abstraction layer one
|
2017-11-19 17:52:02 +01:00
|
|
|
if(!(puzzleMat.testRotationPiece(log.back().myCoor.m, log.back().myCoor.n, *(log.back().PieceCollector[i]))))
|
|
|
|
log.back().PieceCollector.erase(log.back().PieceCollector.begin()+i);
|
2017-11-19 22:53:00 +01:00
|
|
|
else
|
2017-11-28 21:35:49 +01:00
|
|
|
{
|
2017-11-19 22:53:00 +01:00
|
|
|
i++; //otherwise loop stops before end!
|
2017-11-28 21:35:49 +01:00
|
|
|
//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);
|
|
|
|
}
|
2017-11-19 17:52:02 +01:00
|
|
|
}
|
2017-11-18 08:16:05 +01:00
|
|
|
}
|
|
|
|
|
2017-11-19 17:52:02 +01:00
|
|
|
void setsolution(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
2017-11-19 17:52:02 +01:00
|
|
|
//remove first element in last logelement from box
|
2017-11-19 22:53:00 +01:00
|
|
|
for(int i=0;i<p_Box.size();)
|
2017-11-19 17:52:02 +01:00
|
|
|
if(p_Box[i]==log.back().PieceCollector[0])
|
2017-12-03 20:12:32 +01:00
|
|
|
p_Box.erase(p_Box.begin()+i);
|
|
|
|
else
|
2017-11-19 22:53:00 +01:00
|
|
|
i++;
|
2017-12-03 20:12:32 +01:00
|
|
|
|
2017-11-19 22:53:00 +01:00
|
|
|
//turn piece until it fits and then set element into matrix
|
2017-12-03 20:12:32 +01:00
|
|
|
if(puzzleMat.testRotationPiece(log.back().myCoor.m, log.back().myCoor.n,*(log.back().PieceCollector[0])))
|
2017-11-30 22:29:52 +01:00
|
|
|
//error if it turned
|
2017-11-19 17:52:02 +01:00
|
|
|
puzzleMat.setPiece(log.back().myCoor.m, log.back().myCoor.n, *(log.back().PieceCollector[0]));
|
2017-11-19 22:53:00 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
cout << "fatal error, wrong piece saved" << endl;
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
//tell log entry that it is set
|
|
|
|
log.back().Set();
|
|
|
|
|
2017-12-03 20:12:32 +01:00
|
|
|
}
|
2017-11-18 08:16:05 +01:00
|
|
|
|
2017-11-19 17:52:02 +01:00
|
|
|
bool backtrack(vector<LogEntry>& log, vector<PuzzlePiece*>& p_Box, Puzzle& puzzleMat)
|
2017-11-18 08:16:05 +01:00
|
|
|
{
|
|
|
|
//following possibilities:
|
2017-11-28 21:35:49 +01:00
|
|
|
//last log entry empty - delete last log + backtrack
|
2017-11-19 17:52:02 +01:00
|
|
|
if(!(log.back().PieceCollector.size()))
|
2017-12-03 20:12:32 +01:00
|
|
|
{
|
2017-11-19 22:53:00 +01:00
|
|
|
puzzleMat.removePiece(log.back().myCoor.m, log.back().myCoor.n);
|
2017-12-03 20:12:32 +01:00
|
|
|
log.pop_back();
|
2017-11-19 17:52:02 +01:00
|
|
|
backtrack(log,p_Box,puzzleMat);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-11-28 21:35:49 +01:00
|
|
|
//last log entry only one solution - delete last logd put back into box + backtrack
|
2017-11-19 17:52:02 +01:00
|
|
|
else if((log.back().PieceCollector.size())==1)
|
|
|
|
{
|
2017-11-28 21:35:49 +01:00
|
|
|
(log.back().PieceCollector[0])->shift(1);
|
|
|
|
|
2017-11-30 14:19:25 +01:00
|
|
|
//check rotion
|
2017-11-28 21:35:49 +01:00
|
|
|
while((log.back().PieceCollector[0])->getShift() !=0 && (log.back().PieceCollector[0])->getShift() !=3)
|
2017-11-22 16:06:23 +01:00
|
|
|
{
|
2017-11-28 21:35:49 +01:00
|
|
|
log.back().PieceCollector[0]->shift(1);
|
|
|
|
if(puzzleMat.testRotationPiece(log.back().myCoor.m, log.back().myCoor.n, *(log.back().PieceCollector[0]), 1))
|
|
|
|
{
|
|
|
|
setsolution(log,p_Box,puzzleMat);
|
|
|
|
return 1;
|
|
|
|
}
|
2017-11-22 16:06:23 +01:00
|
|
|
}
|
2017-11-28 21:35:49 +01:00
|
|
|
|
|
|
|
p_Box.push_back(log.back().PieceCollector[0]);
|
|
|
|
//shuffleup
|
|
|
|
random_shuffle(p_Box.begin(),p_Box.end());
|
|
|
|
puzzleMat.removePiece(log.back().myCoor.m, log.back().myCoor.n);
|
2017-12-03 20:12:32 +01:00
|
|
|
log.pop_back();
|
2017-11-28 21:35:49 +01:00
|
|
|
//cout << "removed" << endl;
|
2017-12-03 20:12:32 +01:00
|
|
|
//status(log,p_Box,puzzleMat);
|
2017-11-28 21:35:49 +01:00
|
|
|
backtrack(log,p_Box,puzzleMat);
|
|
|
|
|
2017-11-19 17:52:02 +01:00
|
|
|
return 1;
|
|
|
|
}
|
2017-12-03 20:12:32 +01:00
|
|
|
|
2017-11-28 21:35:49 +01:00
|
|
|
//last log entry multiple solutions (and current one was randomed) - delete randomed piece and go to next
|
2017-11-19 17:52:02 +01:00
|
|
|
else if((log.back().PieceCollector.size())>1)
|
|
|
|
{
|
2017-11-22 16:06:23 +01:00
|
|
|
|
|
|
|
//check if piece has second rotation solution
|
2017-11-28 21:35:49 +01:00
|
|
|
(*(log.back().PieceCollector[0])).shift(1);
|
2017-11-22 16:06:23 +01:00
|
|
|
|
2017-11-28 21:35:49 +01:00
|
|
|
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.m, log.back().myCoor.n, *(log.back().PieceCollector[0]), 1))
|
|
|
|
{
|
|
|
|
setsolution(log,p_Box,puzzleMat);
|
|
|
|
return 1;
|
|
|
|
}
|
2017-11-22 16:06:23 +01:00
|
|
|
}
|
|
|
|
|
2017-11-28 21:35:49 +01:00
|
|
|
p_Box.push_back(log.back().PieceCollector[0]);
|
|
|
|
//shuffleup
|
|
|
|
random_shuffle(p_Box.begin(),p_Box.end());
|
2017-12-03 20:12:32 +01:00
|
|
|
log.back().PieceCollector.erase(log.back().PieceCollector.begin());
|
|
|
|
|
2017-11-28 21:35:49 +01:00
|
|
|
if(log.back().PieceCollector.size()==1)
|
|
|
|
log.back().decreaseRandomed();
|
2017-12-03 20:12:32 +01:00
|
|
|
|
2017-11-28 21:35:49 +01:00
|
|
|
//for abstraction layer 1 so that first rotation solution is set.
|
|
|
|
(*(log.back().PieceCollector[0])).resetShift();
|
|
|
|
setsolution(log,p_Box,puzzleMat);
|
|
|
|
|
2017-11-19 17:52:02 +01:00
|
|
|
return 1;
|
|
|
|
//no need to remove from puzzle mat, as sersolution overwrites it anyway
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
|
2017-11-19 22:53:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2017-11-21 10:31:48 +01:00
|
|
|
//cout << "Abstraction: " << log[i].abstractionLevel << endl;
|
2017-11-28 21:35:49 +01:00
|
|
|
cout << "m: " << log[i].myCoor.m << " n: " << log[i].myCoor.n << endl;
|
2017-11-19 22:53:00 +01:00
|
|
|
/*for(int j=0;j<log[i].PieceCollector.size();j++)
|
|
|
|
{
|
|
|
|
(*(log[i].PieceCollector[j])).printPiece();
|
|
|
|
cout << endl;
|
2017-12-03 20:12:32 +01:00
|
|
|
}*/
|
2017-11-19 22:53:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
cout << endl;
|
|
|
|
cout << "Box:" << endl;
|
|
|
|
cout << "size: " << p_Box.size() << endl;
|
2017-11-21 10:31:48 +01:00
|
|
|
for(vector<PuzzlePiece*>::iterator i = p_Box.begin();i!=p_Box.end();i++)
|
|
|
|
{
|
|
|
|
(*(*i)).printPiece();
|
|
|
|
cout << endl;
|
|
|
|
}
|
2017-11-19 22:53:00 +01:00
|
|
|
|
|
|
|
cout << "Puzzle:" << endl;
|
|
|
|
puzzleMat.printPuzzle();
|
|
|
|
cout << "----------------------------" << endl;
|
2017-11-18 08:16:05 +01:00
|
|
|
}
|