Skip to content

Commit dbddc9f

Browse files
committed
Added 'View Solution' to right-click menu.
Level Solution is now saved to the .sok file. Levels already completed should now be impossible to generate.
1 parent 86130bb commit dbddc9f

File tree

6 files changed

+45
-8
lines changed

6 files changed

+45
-8
lines changed

SokoGenerator.pro.user

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!DOCTYPE QtCreatorProject>
3-
<!-- Written by QtCreator 3.6.0, 2016-03-23T15:01:14. -->
3+
<!-- Written by QtCreator 3.6.0, 2016-03-23T17:46:23. -->
44
<qtcreator>
55
<data>
66
<variable>EnvironmentId</variable>

mainwindow.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ void MainWindow::rightClickMenu(const QPoint &pos){
264264
QMenu submenu;
265265
submenu.addAction("Regenerate Level");
266266
submenu.addAction("Delete Level");
267+
submenu.addAction("View Solution");
267268
QAction* rightClickItem = submenu.exec(PItem);
268269

269270
if(rightClickItem && rightClickItem->text().contains("Delete Level")){
@@ -301,6 +302,19 @@ void MainWindow::rightClickMenu(const QPoint &pos){
301302
displayLevel(row);
302303
}
303304
}
305+
else if(rightClickItem && rightClickItem->text().contains("View Solution")){
306+
int row = ui->list_LevelSet->indexAt(pos).row();
307+
if(row >= 0){
308+
vector<SokoGenerator::Level> levelSet = Generator.getLevels();
309+
QString solution = QString::fromStdString(levelSet[row].solution);
310+
for(int i = 0; i < solution.length(); i++){
311+
if(i % 50 == 0){
312+
solution.insert(i, QChar('\n'));
313+
}
314+
}
315+
QMessageBox::about(this, "Level " + QString::number(row+1) + " Solution", solution);
316+
}
317+
}
304318

305319
}
306320

sokogenerator.cpp

+20-3
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,10 @@ void SokoGenerator::generateLevel(int roomWidth, int roomHeight, int noOfBoxes,
125125
if(generationSuccessful) generationSuccessful = placePlayer(newLevel, _roomW, _roomH);
126126
if(generationSuccessful){
127127
level lvl = LevelToCLevel(newLevel);
128+
struct solution sol;
128129
qDebug() << "Generation Started: ";
129-
generationSuccessful = solver.solve(lvl, timeout);
130+
generationSuccessful = solver.solve(lvl, timeout, sol);
131+
if(generationSuccessful) newLevel.solution = cSolToString(sol);
130132
qDebug() << "Generation Successful: " << generationSuccessful;
131133
}
132134
}
@@ -345,7 +347,7 @@ bool SokoGenerator::placeGoalsAndBoxes(SokoGenerator::Level &level, int roomWidt
345347
}
346348
}
347349
else if(level.grid[yCoord][xCoord] == GOAL){
348-
if(neighbourCheck(level, yCoord, xCoord)){
350+
if(neighbourCheck(level, yCoord, xCoord) && boxCount < noOfBoxes-1){
349351
level.grid[yCoord][xCoord] = BOXONGOAL;
350352
boxCount++;
351353
}
@@ -438,8 +440,10 @@ void SokoGenerator::regenerateLevel(int lvlNum){
438440
if(generationSuccessful) placePlayer(newLevel, _roomW, _roomH);
439441
if(generationSuccessful){
440442
level lvl = LevelToCLevel(newLevel);
443+
struct solution sol;
441444
qDebug() << "Generation Started: ";
442-
generationSuccessful = solver.solve(lvl, timeout);
445+
generationSuccessful = solver.solve(lvl, timeout, sol);
446+
if(generationSuccessful) newLevel.solution = cSolToString(sol);
443447
qDebug() << "Generation Successful: " << generationSuccessful;
444448
}
445449
}
@@ -507,3 +511,16 @@ bool SokoGenerator::isTimeout(clock_t start, float timeout){
507511

508512
return false;
509513
}
514+
515+
string SokoGenerator::cSolToString(struct solution sol){
516+
string characters = "ludrLUDR";
517+
string solution;
518+
for(int i = 0; i < MAXSOLUTION; i++){
519+
char sChar = sol.move[i];
520+
if(characters.find(sChar) != string::npos){
521+
solution += sChar;
522+
}
523+
}
524+
525+
return solution;
526+
}

sokogenerator.h

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ class SokoGenerator : public QObject{
7676
void floodfill(TwoDVector_int &level, int row, int column, int roomWidth, int roomHeigh);
7777
bool neighbourCheck(SokoGenerator::Level &level, int yCoord, int xCoord);
7878
level LevelToCLevel(SokoGenerator::Level lvl);
79+
string cSolToString(struct solution sol);
7980

8081
void deleteLevel(int lvlNum){ levels.erase(levels.begin() + lvlNum); }
8182
bool isTimeout(clock_t start, float timeout);

solvercpp/solver.cpp

+7-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Solver::Solver(QObject *parent):QObject(parent){
44

55
}
66

7-
bool Solver::solve(struct level Level, float t)
7+
bool Solver::solve(struct level Level, float t, struct solution &sol)
88
{
99
initialize_allocator();
1010

@@ -13,6 +13,7 @@ bool Solver::solve(struct level Level, float t)
1313
struct level* last = levels;
1414
int count = 1;
1515
timeout = t;
16+
qDebug() << "Solving";
1617

1718
while (last != NULL && !threadStop)
1819
{
@@ -31,10 +32,13 @@ bool Solver::solve(struct level Level, float t)
3132
{
3233
try_solve_level();
3334
if (solvable)
34-
if (!check_solution(&lvl_sol, last,0))
35+
if (!check_solution(&lvl_sol, last,0)){
3536
solvable = 0;
36-
else
37+
}
38+
else{
39+
sol = lvl_sol;
3740
return 1;
41+
}
3842
}
3943

4044
if(DOUT)printf("Next Level: %p\n", last->next_level);

solvercpp/solver.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <stdlib.h>
88
#include <time.h>
99
#include <QOBject>
10+
#include <QDebug>
1011
#include <chrono>
1112

1213
extern "C" {
@@ -25,7 +26,7 @@ class Solver : public QObject{
2526
Q_OBJECT
2627
public:
2728
Solver(QObject *parent = 0);
28-
bool solve(level Level, float t);
29+
bool solve(level Level, float t, struct solution &sol);
2930
void setThreadStop(bool value) { threadStop = value; }
3031
private:
3132
void print_binary(unsigned int x);

0 commit comments

Comments
 (0)