save game query on exit if game is incomplete
[impuzzle] / src / gameview.cpp
index 3223602..4164b24 100644 (file)
@@ -33,7 +33,6 @@
 #include <QFile>
 #include <QDir>
 #include <QTextStream>
-#include <QCloseEvent>
 #include <QFileInfo>
 #include <QDateTime>
 #include <QTimer>
@@ -96,6 +95,8 @@ QList<PuzzleItem *> GameView::pieces() const
 
 void GameView::setPieces(const QList<PuzzleItem *> pieces, bool shuffle)
 {
+    PuzzleItem::setManuallyMovable(false);
+
     if(pieces.isEmpty()) {
         qDebug() << "Empty list @ GameView::setPieces";
         return;
@@ -148,8 +149,12 @@ void GameView::setPieces(const QList<PuzzleItem *> pieces, bool shuffle)
     if(shuffle) {
         QTimer::singleShot(750, this, SLOT(shufflePieces()));
     }
+    else {
+        PuzzleItem::setManuallyMovable(true);
+    }
 }
 
+//TODO: fixme!
 void GameView::shufflePieces()
 {
     if(pieces_.isEmpty()) {
@@ -164,7 +169,12 @@ void GameView::shufflePieces()
     QPointF topLeft = pieces_.at(0)->correctPlace();
     QPointF bottomRight = pieces_.last()->correctPlace();
 
-    for(int i = 0; i < pieces_.count() * 10; ++i) {
+    int moveCount = pieces_.count() * 10;
+    int movesMade = 0;
+
+    PuzzleItem *item = 0;
+
+    for(int i = 0; i < moveCount; ++i) {
         int rand = qrand() % 4;
 
         switch(rand) {
@@ -172,40 +182,102 @@ void GameView::shufflePieces()
         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);
+                QGraphicsItem *graphicsItem = scene()->itemAt(tmp + QPointF(0, -verticalStep_));
+                if(graphicsItem) {
+                    item = dynamic_cast<PuzzleItem *>(graphicsItem);
+                    if(item->movable()) {
+                        emptyPlace_ = item->currentPlace();
+                        pieces_.at(hiddenIndex_)->setCurrentPlace(item->currentPlace());
+                        pieces_.at(hiddenIndex_)->setPos(item->currentPlace());
+                        item->setCurrentPlace(tmp);
+                        item->setPos(tmp);
+                        invalidateScene();
+                        scene()->update();
+                        setMovingPieces();
+                        movesMade++;
+                    }
+                    else {
+                        qDebug() << "Item right of hidden piece not movable";
+                    }
+                }
+            }
+            else {
+                --i;
             }
             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);
+                QGraphicsItem *graphicsItem = scene()->itemAt(tmp + QPointF(0, verticalStep_));
+                if(graphicsItem) {
+                    item = dynamic_cast<PuzzleItem *>(graphicsItem);
+                    if(item->movable()) {
+                    emptyPlace_ = item->currentPlace();
+                        pieces_.at(hiddenIndex_)->setCurrentPlace(item->currentPlace());
+                        pieces_.at(hiddenIndex_)->setPos(item->currentPlace());
+                        item->setCurrentPlace(tmp);
+                        item->setPos(tmp);
+                        setMovingPieces();
+                        movesMade++;
+                    }
+                    else {
+                        qDebug() << "Item down of hidden piece not movable";
+                    }
+                }
+            }
+            else {
+                --i;
             }
             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);
+                QGraphicsItem *graphicsItem = scene()->itemAt(tmp + QPointF(-horizontalStep_, 0));
+                if(graphicsItem) {
+                    item = dynamic_cast<PuzzleItem *>(graphicsItem);
+                    if(item->movable()) {
+                        emptyPlace_ = item->currentPlace();
+                        pieces_.at(hiddenIndex_)->setCurrentPlace(item->currentPlace());
+                        pieces_.at(hiddenIndex_)->setPos(item->currentPlace());
+                        item->setCurrentPlace(tmp);
+                        item->setPos(tmp);
+                        setMovingPieces();
+                        movesMade++;
+                    }
+                    else {
+                        qDebug() << "Item left of hidden piece not movable";
+                    }
+                }
+            }
+            else {
+                --i;
             }
             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);
+                QGraphicsItem *graphicsItem = scene()->itemAt(tmp + QPointF(horizontalStep_, 0));
+                if(graphicsItem) {
+                    item = dynamic_cast<PuzzleItem *>(graphicsItem);
+                    if(item->movable()) {
+                        emptyPlace_ = item->currentPlace();
+                        pieces_.at(hiddenIndex_)->setCurrentPlace(item->currentPlace());
+                        pieces_.at(hiddenIndex_)->setPos(item->currentPlace());
+                        item->setCurrentPlace(tmp);
+                        item->setPos(tmp);
+                        setMovingPieces();
+                        movesMade++;
+                    }
+                    else {
+                        qDebug() << "Item up of hidden piece not movable";
+                    }
+                }
+            }
+            else {
+                --i;
             }
             break;
         default:
@@ -214,7 +286,10 @@ void GameView::shufflePieces()
         }
     }
 
+    qDebug() << QString("Shuffle moves: %1/%2").arg(movesMade).arg(moveCount);
+
     QParallelAnimationGroup *animationGroup = new QParallelAnimationGroup(this);
+    connect(animationGroup, SIGNAL(finished()), this, SLOT(shuffleAnimationFinished()));
     for(int i = 0; i < pieces_.count(); ++i) {
         QPropertyAnimation *animation = new QPropertyAnimation(pieces_.at(i), "pos");
         animation->setStartValue(pieces_.at(i)->correctPlace());
@@ -224,11 +299,13 @@ void GameView::shufflePieces()
         animationGroup->addAnimation(animation);
     }
     animationGroup->start();
-
-    // Hide
     pieces_.at(hiddenIndex_)->hide();
+}
 
+void GameView::shuffleAnimationFinished()
+{
     setMovingPieces();
+    PuzzleItem::setManuallyMovable(true);
 }
 
 QPointF GameView::emptyPlace()
@@ -511,19 +588,6 @@ void GameView::saveGame()
     qApp->quit();
 }
 
-void GameView::closeEvent(QCloseEvent *event)
-{
-    int answer = QMessageBox::question(this, tr("Save game status?"),
-                                       tr("Saved status will be automatically loaded when you start the application next time"),
-                                       QMessageBox::Yes, QMessageBox::No);
-
-    if(answer == QMessageBox::Yes) {
-        saveGame();
-    }
-
-    event->accept();
-}
-
 int GameView::correctPlaces() const
 {
     int c = 0;