New shuffle implementation
authortimoph <timop.harkonen@gmail.com>
Fri, 23 Apr 2010 18:48:03 +0000 (18:48 +0000)
committertimoph <timop.harkonen@gmail.com>
Fri, 23 Apr 2010 18:48:03 +0000 (18:48 +0000)
git-svn-id: file:///svnroot/impuzzle/trunk@18 e6bec12f-0854-4cc4-ad26-6875f1509f77

debian/changelog
src/gameview.cpp
src/gameview.h
src/mainwindow.cpp
src/mainwindow.h

index e0ce620..99b4fc7 100644 (file)
@@ -1,3 +1,10 @@
+impuzzle (0.4-2maemo0) unstable; urgency=low
+
+  * Fixes: Saving not enabled after game is restored
+  * Fixes: Improved shuffle to make game solvable
+
+ -- Timo Härkönen <timop.harkonen@gmail.com>  Fri, 23 Apr 2010 21:46:00 +0200
+
 impuzzle (0.4-1maemo0) unstable; urgency=low
 
   * Implemented: Game state save and restore
index ba9b827..e0d5b06 100644 (file)
@@ -36,6 +36,9 @@
 #include <QCloseEvent>
 #include <QFileInfo>
 #include <QDateTime>
+#include <QTimer>
+#include <QApplication>
+#include <QDateTime>
 
 #ifdef Q_WS_MAEMO_5
 #include <QMaemo5InformationBox>
@@ -48,6 +51,7 @@ GameView *GameView::instance_ = 0;
 GameView::GameView(QWidget *parent) :
         QGraphicsView(parent)
 {
+    qsrand(QDateTime::currentDateTime().toTime_t());
     scene_ = new QGraphicsScene;
     hiddenIndex_ = -1;
     setScene(scene_);
@@ -66,6 +70,9 @@ GameView::GameView(QWidget *parent) :
             setPieces(ImageImporter::instance()->newPieces(Settings::instance()->image(), Settings::instance()->pieceCount()));
             PuzzleItem::setMoveCount(0);
         }
+        else {
+            QTimer::singleShot(0, this, SIGNAL(gameRestored()));
+        }
     }
     else {
         scene_->addItem(introItem_);
@@ -150,17 +157,59 @@ void GameView::shufflePieces()
     }
 
     // Give pieces ramdom locations
-    int rounds = 5; //TODO
-    for(int j = 0; j < rounds; ++j) {
-        for(int i = 0; i < pieces_.count(); ++i) {
-            QPointF tmp;
-            int changeIndex = 0;
-            while(changeIndex == i) {
-                changeIndex = qrand() % pieces_.count();
+    hiddenIndex_ = qrand() % pieces_.count();
+    emptyPlace_ = pieces_.at(hiddenIndex_)->currentPlace();
+
+    QPointF topLeft = pieces_.at(0)->correctPlace();
+    QPointF bottomRight = pieces_.last()->correctPlace();
+
+    for(int i = 0; i < pieces_.count() * 10; ++i) {
+        int rand = qrand() % 4;
+
+        switch(rand) {
+        // up
+        case 0:
+            if(pieces_.at(hiddenIndex_)->currentPlace().y() > topLeft.y()) {
+                QPointF tmp = pieces_.at(hiddenIndex_)->currentPlace();
+                PuzzleItem *item = dynamic_cast<PuzzleItem *>(scene()->itemAt(tmp + QPointF(0, -verticalStep_)));
+                emptyPlace_ = item->currentPlace();
+                pieces_.at(hiddenIndex_)->setCurrentPlace(item->currentPlace());
+                item->setCurrentPlace(tmp);
+            }
+            break;
+        // down
+        case 1:
+            if(pieces_.at(hiddenIndex_)->currentPlace().y() < bottomRight.y()) {
+                QPointF tmp = pieces_.at(hiddenIndex_)->currentPlace();
+                PuzzleItem *item = dynamic_cast<PuzzleItem *>(scene()->itemAt(tmp + QPointF(0, verticalStep_)));
+                emptyPlace_ = item->currentPlace();
+                pieces_.at(hiddenIndex_)->setCurrentPlace(item->currentPlace());
+                item->setCurrentPlace(tmp);
+            }
+            break;
+        // left
+        case 2:
+            if(pieces_.at(hiddenIndex_)->currentPlace().x() > topLeft.x()) {
+                QPointF tmp = pieces_.at(hiddenIndex_)->currentPlace();
+                PuzzleItem *item = dynamic_cast<PuzzleItem *>(scene()->itemAt(tmp + QPointF(-horizontalStep_, 0)));
+                emptyPlace_ = item->currentPlace();
+                pieces_.at(hiddenIndex_)->setCurrentPlace(item->currentPlace());
+                item->setCurrentPlace(tmp);
             }
-            tmp = pieces_.at(changeIndex)->currentPlace();
-            pieces_.at(changeIndex)->setCurrentPlace(pieces_.at(i)->currentPlace());
-            pieces_.at(i)->setCurrentPlace(tmp);
+            break;
+        // right
+        case 3:
+            if(pieces_.at(hiddenIndex_)->currentPlace().x() < bottomRight.x()) {
+                QPointF tmp = pieces_.at(hiddenIndex_)->currentPlace();
+                PuzzleItem *item = dynamic_cast<PuzzleItem *>(scene()->itemAt(tmp + QPointF(horizontalStep_, 0)));
+                emptyPlace_ = item->currentPlace();
+                pieces_.at(hiddenIndex_)->setCurrentPlace(item->currentPlace());
+                item->setCurrentPlace(tmp);
+            }
+            break;
+        default:
+            qDebug() << "WTF?";
+            break;
         }
     }
 
@@ -175,11 +224,8 @@ void GameView::shufflePieces()
     }
     animationGroup->start();
 
-    // Hide random piece
-    int hiddenPiece = qrand() % pieces_.count();
-    emptyPlace_ = pieces_.at(hiddenPiece)->currentPlace();
-    pieces_.at(hiddenPiece)->hide();
-    hiddenIndex_ = hiddenPiece;
+    // Hide
+    pieces_.at(hiddenIndex_)->hide();
 
     setMovingPieces();
 }
@@ -319,7 +365,7 @@ bool GameView::restoreGame()
             for(int j = 0; j < pieces_.count(); ++j) {
                 if(!list.at(j + 3).isNull()) {
                     QStringList points = list.at(j + 3).split("#");
-                    //if(points.count() == 2)
+
                     int x = points.at(0).toInt(&ok);
                     if(!ok) {
                         return false;
@@ -395,10 +441,10 @@ bool GameView::restoreGame()
     return true;
 }
 
-bool GameView::saveGame()
+void GameView::saveGame()
 {
     if(pieces_.isEmpty() || pieces_.count() < EASY_PIECE_COUNT) {
-        return false;
+        return;
     }
 
     QDir dir;
@@ -417,7 +463,7 @@ bool GameView::saveGame()
 
     if(!file.open(QIODevice::WriteOnly)) {
         qDebug() << "Failed to open restore file for writing";
-        return false;
+        return;
     }
 
     QTextStream out(&file);
@@ -461,7 +507,7 @@ bool GameView::saveGame()
 
     file.close();
 
-    return true;
+    qApp->quit();
 }
 
 void GameView::closeEvent(QCloseEvent *event)
@@ -476,3 +522,29 @@ void GameView::closeEvent(QCloseEvent *event)
 
     event->accept();
 }
+
+int GameView::correctPlaces() const
+{
+    int c = 0;
+
+    for(int i = 0; i < pieces_.count(); ++i) {
+        if(pieces_.at(i)->currentPlace() == pieces_.at(i)->correctPlace()) {
+            c++;
+        }
+    }
+
+    return c;
+}
+
+QList<int> GameView::movingPlaces() const
+{
+    QList<int> m;
+
+    for(int i = 0; i < pieces_.count(); ++i) {
+        if(pieces_.at(i)->movable()) {
+            m.append(i);
+        }
+    }
+
+    return m;
+}
index 3eb2d7c..7e3e6f1 100644 (file)
@@ -41,16 +41,19 @@ public slots:
     void setPieces(const QList<PuzzleItem *> pieces, bool shuffle = true);
     void shufflePieces();
     bool restoreGame();
-    bool saveGame();
+    void saveGame();
 
 signals:
     void gameWon();
+    void gameRestored();
 
 protected:
     void closeEvent(QCloseEvent *event);
 
 private:
     GameView(QWidget *parent = 0);
+    int correctPlaces() const;
+    QList<int> movingPlaces() const;
 
     static GameView *instance_;
     QGraphicsScene *scene_;
index f9bc5ee..514dcec 100644 (file)
 #include "gameview.h"
 #include "settings.h"
 #include "settingsdialog.h"
+#include "puzzleitem.h"
 
 #include <QAction>
 #include <QMenu>
 #include <QMenuBar>
 
+#include <QDebug>
+
 #include "imageimporter.h"
 
 MainWindow::MainWindow(QWidget *parent) :
@@ -39,6 +42,7 @@ MainWindow::MainWindow(QWidget *parent) :
     setWindowTitle(tr("ImPuzzle"));
 
     connect(GameView::instance(), SIGNAL(gameWon()), this, SLOT(gameEnded()));
+    connect(GameView::instance(), SIGNAL(gameRestored()), this, SLOT(enableSaving()));
 }
 
 void MainWindow::createMenu()
@@ -61,7 +65,7 @@ void MainWindow::createActions()
     settingsAction_ = new QAction(tr("Settings"), this);
     connect(settingsAction_, SIGNAL(triggered()), this, SLOT(settingsClicked()));
 
-    saveAction_ = new QAction(tr("Save game"), this);
+    saveAction_ = new QAction(tr("Save and quit"), this);
     connect(saveAction_, SIGNAL(triggered()), GameView::instance(), SLOT(saveGame()));
     saveAction_->setDisabled(true);
 }
@@ -73,12 +77,10 @@ void MainWindow::importClicked()
 
 void MainWindow::newGameClicked()
 {
-    //SettingsDialog dialog(this);
-    //dialog.exec();
     settingsDialog_->exec();
 
     GameView::instance()->setPieces(ImageImporter::instance()->newPieces(Settings::instance()->image(), Settings::instance()->pieceCount()));
-    saveAction_->setEnabled(true);
+    enableSaving();
 }
 
 void MainWindow::settingsClicked()
@@ -90,5 +92,13 @@ void MainWindow::gameEnded()
 {
     if(saveAction_->isEnabled()) {
         saveAction_->setDisabled(true);
+        PuzzleItem::resetMoveCount();
+    }
+}
+
+void MainWindow::enableSaving()
+{
+    if(!saveAction_->isEnabled()) {
+        saveAction_->setEnabled(true);
     }
 }
index 6623f9c..7367cf0 100644 (file)
@@ -37,6 +37,7 @@ private slots:
     void importClicked();
     void settingsClicked();
     void gameEnded();
+    void enableSaving();
 
 private:
     void createActions();