2 Image Puzzle - A set your pieces straight game
3 Copyright (C) 2009 Timo Härkönen
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "puzzleitem.h"
23 #include <QGraphicsScene>
26 #include <QPropertyAnimation>
27 #include <QParallelAnimationGroup>
32 GameView *GameView::instance_ = 0;
34 GameView::GameView(QWidget *parent) :
37 scene_ = new QGraphicsScene;
41 qsrand(QDateTime::currentDateTime().toTime_t());
44 GameView *GameView::instance()
47 instance_ = new GameView;
53 QList<PuzzleItem *> GameView::pieces() const
58 void GameView::setPieces(const QList<PuzzleItem *> pieces)
60 if(pieces.isEmpty()) {
61 qDebug() << "Empty list @ GameView::setPieces";
65 QList<QGraphicsItem *> previousItems = scene_->items();
66 if(!previousItems.isEmpty()) {
67 foreach(QGraphicsItem *item, previousItems) {
68 scene_->removeItem(item);
74 int horizontalCount = 0;
76 // Find out board size
77 if(pieces_.count() == 12) {
80 else if(pieces_.count() == 20) {
84 qDebug() << "Invalid piece count @ GameView::setPieces";
85 qDebug() << QString("Count was %1").arg(pieces_.count());
89 int verticalCount = pieces_.count() / horizontalCount;
90 int horizontalStep = IMAGE_WIDTH / horizontalCount + 5;
91 int verticalStep = IMAGE_HEIGHT / verticalCount + 5;
95 // Set pieces to their correct positions
96 for(int i = 0; i < verticalCount; ++i) {
97 for(int j = 0; j < horizontalCount; ++j) {
98 scene_->addItem(pieces_.at(pieceNumber));
99 QPointF point(j * horizontalStep, i * verticalStep);
100 pieces_.at(pieceNumber)->setPos(point);
101 pieces_.at(pieceNumber)->setCorrectPlace(point);
102 pieces_.at(pieceNumber)->setCurrentPlace(point);
108 QTimer::singleShot(1000, this, SLOT(shufflePieces()));
111 void GameView::shufflePieces()
113 if(pieces_.isEmpty()) {
114 qDebug() << "Empty list @ GameView::shufflePieces";
118 // TODO Give pieces ramdom locations
120 for(int j = 0; j < rounds; ++j) {
121 for(int i = 0; i < pieces_.count(); ++i) {
124 while(changeIndex == i) {
125 changeIndex = qrand() % pieces_.count();
127 tmp = pieces_.at(changeIndex)->currentPlace();
128 pieces_.at(changeIndex)->setCurrentPlace(pieces_.at(i)->currentPlace());
129 pieces_.at(i)->setCurrentPlace(tmp);
133 // TODO Animate transitions to new locations
134 QParallelAnimationGroup *animationGroup = new QParallelAnimationGroup(this);
135 for(int i = 0; i < pieces_.count(); ++i) {
136 QPropertyAnimation *animation = new QPropertyAnimation(pieces_.at(i), "pos");
137 animation->setStartValue(pieces_.at(i)->correctPlace());
138 animation->setEndValue(pieces_.at(i)->currentPlace());
139 animation->setDuration(750);
140 animation->setEasingCurve(QEasingCurve::InOutCirc);
141 animationGroup->addAnimation(animation);
143 animationGroup->start();
146 int hiddenPiece = qrand() % pieces_.count();
147 emptyPlace_ = pieces_.at(hiddenPiece)->currentPlace();
148 pieces_.at(hiddenPiece)->hide();
149 hiddenIndex_ = hiddenPiece;
152 QPointF GameView::emptyPlace()
157 void GameView::setEmptyPlace(const QPointF &place)
162 bool GameView::areAllPiecesOk() const
164 for(int i = 0; i < pieces_.count(); ++i) {
165 if(i == hiddenIndex_) {
168 else if(pieces_.at(i)->correctPlace() != pieces_.at(i)->currentPlace()) {
172 pieces_.at(hiddenIndex_)->show();
173 pieces_.at(hiddenIndex_)->moveMeTo(emptyPlace_);
175 for(int i = 0; i < pieces_.count(); ++i) {
176 pieces_.at(i)->setMovable(false);