impuzzle (0.3-2maemo1) unstable; urgency=low
- * Added application icon
* Added bug tracking link to control
+ * Dependency changes required by pr1.2 autobuilder
- -- Timo Härkönen <timop.harkonen@gmail.com> Tue, 09 Mar 2010 19:09:13 +0200
+ -- Timo Härkönen <timop.harkonen@gmail.com> Wed, 24 Mar 2010 17:51:13 +0200
impuzzle (0.3-2maemo0) unstable; urgency=low
Section: user/games
Priority: optional
Maintainer: Timo Härkönen <timop.harkonen@gmail.com>
-Build-Depends: debhelper (>= 5), libqt4-maemo5-dev
+Build-Depends: debhelper (>= 5), libqt4-dev (>= 4.6.0)
Standards-Version: 3.7.2
XSBC-Bugtracker: mailto:timop.harkonen@gmail.com
Package: impuzzle
Architecture: any
-Depends: libqt4-maemo5-core, libqt4-maemo5-gui
+Depends: libqt4-core (>= 4.6.0), libqt4-gui (>= 4.6.0)
Description: Image puzzle game
-XB-Maemo-Icon-26:
-MB5!.1PT*&@H````-24A$4@```#`````P"`8```!7`OF'`````7-21T(`KLX<
-MZ0````9B2T=$`+``,0`QG?,\]@````EP2%ES```+$P``"Q,!`)J<&`````=T
-M24U%!]H#"1$"$'>\&Q(````9=$58=$-O;6UE;G0`0W)E871E9"!W:71H($=)
-M35!7@0X7```-DDE$051HWM6:2XYDV7%$C_F]+S*SNBE^-]``(:@'$K0M:2)`
-M(^U!,VI?FA(D"`B:$P1%UB<SWKUN&KB_R&IR!2R@4)&5\?&ON9E["#!?_0GP
-M1)J!!]*0/"1"@OJ9D!B"D/C?+U_XY<N+0Z$0#E`@"Q082=?[`B",`1L$_/>G
-M3_SCAP^DC3'J7TX@7,_=-MMF`6<F;\`]DSLP_\IXP0&>!$?@B8@0@9!D2[J,
-MGVW6;00R3`DA0F5<M/&RD$`V(`1L07;LCA!88"/!L!D8+-)F"Y9A&%"0F%/"
-M[6A'!@Z)F\0A,24?$N/ZBQ2"5)A`T_+H\!X$$3#:^.CWDU2/]?XAMAZ9J&?!
-MDZ)^ELIX05@D9@,;=>9,1&5O*!CDNP.'\"'YUH:W$\QR0%-R1&`JRQ'E&,#3
-MJ*@&E1TAQ:-L*OK898;H$M*C>I]#R&+:E3T+RZ3%LI'-0D`"5Z"20.5``)/@
-MN1S@D'P;P:&XG*C:KCY@M4V7`U-2O6E%O/YUEUW9:963OCI.[F*";SH#HXU/
-M@6UV.[B!T>\7ANHM\.7`B."&?$CY'.U(!%.A+B.%Y)"4X&5;$I8,Z(@HP]N)
-M`4P$JM1+53!5-:[R\GMI?>C>H?-KQ+;!K@QD7ADF(B$-!.'-G!(',(5?(O(E
-MQ',,;A&Z29X1#'7:@)1T-CID6W`C'(&^=B*`<940%2V%B>X!;(Y.QC<CRB:,
-M#:O3=':7S`A6FB"A064DO(3*@6[8?)'\$H.G")XCF!'<)`5RA!X&G4ZG1'8,
-MGT<0DF4K'HTKHE'%KK(:%3A&(]8%K4\:7?-F82RQG,RLI"40%3VB04-A5@;S
-M)NV;Y)>(/$;X*<1SA&X1U0]C,`03Q06-RZHW[1+Z1H'+0<O64&&&%`1BA.&!
-M'.54&>(&@2B<;[R/3*:"B/I96<T["P81B6P">4ZTII1'025'#(X1/"EX&H/9
-M]3Q&N$M$B^J!:!S\\1RF<%ETY%,0AJ?N"=N/1CZZO*X,C,9&9W)@(@+WP(H>
-MG`=`H]-A/"5VF'F(UYND0YH-H;HA9H0F<"A\&Z$K[9*\A68AC`&^':,\*2>\
-M0*,-/2+(K)$UNYYGE]O;`\+%P(P((N'$9`1G5J2'"FT>`0CAA)-@/D5\>9*>
-MCE",,6)&>)1#-0M"3.098M;$C4/RU`6K\&$,I*JG#3S;[]3!]AR#J'ZBAS2Y
-MMX^>:B\1[(35T=^-.D/!H22V'P/5X.5@*1F8.>'U.>+VA/(&FJ`K2C."6Q24
-M3JFB'O(<H?`[T7D:-?BSHJD!F9G"=HZA6X1GSY&1Z6W#"'86M[A)S@@IDP7<
-M+@HB,PE6F$A[7I2BAB6+8#Y+ZX"\17![D#D870:S!]91F6F<ER)$A%P?5%"+
-M(=0\+<*'1$0P)&1;W2-_.0<.B04>$3HRR:8TLHDJ(8=@.0@E)P4*%QGY`1O]
-M6_LS__GY^3?/$3]^AI>7.>-'$?%AC/QP''Z2=-0\&"-"0T+5*I+$B-!__.8W
-M\S__X?N-4]O5R!%1,R,*D0(()ZJH*7K**I-__=WO]*OOOK,!K\4;Z'5O[@6I
-M7C;W3+;-6R9WN_YF48V9L!,R(GR+T(<Y\T7R<Y6/AZ2HSZ4)J8OVQL4QR;5P
-M_:;*`T@G<1IFC3]K$$H%H&U"JM<4D2Q_)*>+*A_@B]7ZG7.Q$`=)#)$2TP7M
-MS#%XB<@GR4\1#HD80Y*D&"@*0JG/QDX5_8+$S8Z+O/F"&H$S8;031'&:H.N[
-MRP"1^!&66Y%'WBX(;<-GP`NP-=@UH==TA(Z(]4U$_&B,?1N#`$=$Z9+^<&)P
-M$>&J"CL;!C?O`L8/RAF@[.CKD9FP'\\-]-`B``HQS#4DF448&<`3D!ID6['M
-M]9JY9TH_OT5\^O8X]C&&6T)*$D2XZ7T+$,*V+!G%\,6-V[JDI*9KX!6)Z:Q$
-M8^Z#;OLK['@HGI[,JO*X0A9C7$,4`Y\SO?;VMG,^1[S\W9Q/W\QYGQ%YT0-%
-MH`@I`B)*#^V*:,%WTO0(7]19Q5#'@T8'48U?[-0U.BX:\7"A!8TRK:\,UR6_
-M&HK/O5GUBKUMIW3.7\SY]O/G9Q]C9-A6A/2>5=N.*"J@=TZ/W$J)IM7CTKT(
-M-?M4,]BX],+>+=9Y4(\JL0K;E2$B(+,XT!BP%I;("+YD<L]DV1LXYS_]Y"?G
-M_8(ZD&S(+&U'E5)%'*=K^NCB98KWC8.^T@(*IK.W%^H%P#M"H8K&;A2*"-(F
-MQH!,$AAS<G2YY1B\`E_.DSOL*>6,V-O^OSDBUD%1;^TM,HO,J]S))E38(J(>
-MA^IQ[G;`C*[_`"(W&O'@+Z4+KME;)>%,1Z?@8J-I,PI$:IX`"_C36IPV<\X]
-M]LX[V#67_C#G&$5<]@YWO5W*M?D,`H61,J4(PD3L)#J"H_E)&9\M5O2H0VQ<
-M@MU57K";[0*X2TRM]*[7?;K?6<`Q!CLSS[5H="0@7B)>IHO:NM!.71129M86
-M"(2M[@W&E1]?DK%*I_D.(T8WI:^)5@9V*6DMB"!T[1A:FKJ>-X"]=\'E&+SM
-MC6L21U94N8W!RYP3^Z=3F5L01%BYV6G1Q@,H+95Q"@6"B$>Y=`UW9?0RJ(SI
-MB8OB@?V/IFUTR.S/:'1IY$,2K^?)DC@S&1*[7SHB4A%GP.N"->M]:Q6X$<Y=
-M?#)-C1$4/1<4C>4AM#:ZAEPF&J.*9J_*0+-4/<!2^(IL)I1,+#\O8A;!?6]V
-M)LOPEHO5RZVLJ>DQATK_\:WLF(I@Y.:>ULXD,U&F"MF+9NAR`$(1O)=V_G"2
-M=AU?D5=I288&V49?Y<+7<Z!H"]X;]N:^-]ALXWAGSD5)3-KVB%@:8\^0N"O(
-M/+4SU9$)[0UCU.2IN=Q;*M1KAL?BMH9V;QF*T=3_22B"3$,F&\K(?EY^O>7:
-MR5E&%U4H(@41QDW`(G:O60;2:]@?)\"Y5M[WQGM+N:5*UV/ZVZZY^\-%\+L#
-M%UDS#%K`="U?S/1JP,S\*PIAEV;.G6S<?,?OE.3*F%&$$BF[[(^_?4'S;]]]
-M]S^?[_<CU[K-W'/L'&.,."+&C(C9"J:&4BA:Z"L&,Z1__^UOXU???Y]C[P?I
-MBD:3G>:>NS9Z-0L>]&]T=O[EU[^.__K^^U2)%:^]M<$GL)N-YMI89-JU2Y/6
-MA+>T7^>G^_W/K^?YLU'U+Y46EAL*:Z*5:B@VU$NMT@,7M>I)V_M;6ZMV0ZXM
-M6Y6#`642<QK>5XB[A+[.O=G@U>*>""^;E=M6*'.3=FJ,>(KX\NV<?YI?]OZR
-M]LY=HMM#8I<385LI1>*Z1NA1F87CW9`N9HALKYH57GMSVH^:SQ8G5U_<;:[7
-MWVUVVB=X=W-G.W9FZLPDO7<=.^0\U_(QYU,F\\O>?TC[%[?,I[/1)FSMXC"*
-M3#)"/VBXAR2L#+S9W-K'7&>M"'N9Y1YT:LH@\'F>^*LF?MW;^\I$IK)7-,MF
-M[>T[<-_;NQ=G`:]::_[I/'\ZS[U^GSN_,_3,1=..D2E'Q*YH$V01V*;(`N8N
-M=OZ:R9NM#;[O7>*PB=]U1X@(OZWUR(`O=ENO]W4'2U>G7#>QMTR?)>ZU,M>9
-M)O#Q1^GWG];Z,-_2GVS?4[(R-<:(LZGUQ32C-CK(B;.V8T<MA0SPY[TA[>5\
-M1/6QTXGPO88C+G99._2O5-C'=CHSL?1PYNJ%^]Y>H&5B.?>GS)<_KO7TY[6^
-MF?>]GVT[2\C'S-19Q"U6&@4$B3=8LA1*NRXJ37$^GJL.=JVXXIV>$*Y3T+[*
-MHM?EB?LF`!_W]N-TDZG3]K:Y.W&62+YGYC;QELFGW.?'O7YZVM_.5_M)=GCG
-M;8[0"8HT.T"DM1&2)2DEQ+84\L(/!_8BP:/@T9=H'[U0-B)=AB_5$B![Z@)\
-M7&LX,T-R]N]6H^#*318[T9O3IQEID\G3,IIO>X<EA8B5UAFP22FO$U%O">K$
-M5!/5&PF-VD'P>9>"F^`ZD0JBSWA]S%M<AL,N@J8K`Y\S-W:HZM^)91<BG<ZZ
-M1SAUMUE.W=,3G.G4O-L?L>--&@JT4D3Q'U\;!#V.VY*_6O4WB>:5)%+.7H)-
-MC+<>]ZYLP[,T0.R&WM4.W--*>G?JP@J`,\VVM;R]3&RC>]IW.Q;UN_EE[]/2
-M#`6;O-:'GO+%0+_:)L@2.HM<^<+6>RB*$3@N52BJ)W5?'Y=J,9=]OKL%\
-M.K6^NM2'[86UTBQ;Y00LITY;IZWE)&W/SSL_.S13C!OBB-#PUD-!78=N6_%0
-MQQ:NKQU<!H3E%=9T36396*6'KI/P5O5J"<PBB!14UFKQ`H):7$6?G;S;X&4H
-M!Y+3:-O,S\ZAS?-6CF20=OQ%V5P-Z0$Z:[ODNER6`:]I)B@V[$J,KF7JI8=3
-MV*GK$EDETZ5R1;GZRR$[$]A.K42;[#D`9QT".R-FOMF_#/C9+MJ0IQY?\%`[
-MX-&7=P5L5R]<E+>Y3$WNTE]!TX:>FC7!$Z72[CL71A>UNSN5Y8"*]-7UJJXV
-M2=HZ\SH"HM-06;#F@K\7C`6Q,^\K%)/P[.-&U-71DE"VZ(KZ&L!U)_YB1VT;
-M$ER"??4VXWTO<55'2ZRB'NYFC0?_J7]#Z<QNU&W8MD^*)';T==K,#;^\6$G:
-M+YEX*74TG1U??<V@Y:16BJE'!7#O+5HMKO;CF-W+@-[DU==5[$O4(_=[G,Y"
-G*5>#[WK<"V2N\ZO.:T+W8P/_#Z8YR6G";59[`````$E%3D2N0F""
-`
+ impuzzle is a picture puzzle game that let's you
+ use your own pictures as the game board.
\ No newline at end of file
mkdir -p builddir
builddir/Makefile: builddir
- cd builddir && /opt/qt4-maemo5/bin/qmake-qt4 PREFIX=/usr ../$(APPNAME).pro
+ cd builddir && qmake-qt4 PREFIX=/usr ../$(APPNAME).pro
build: build-stamp
#define RANDOM_IMAGE_TXT "Random image"
#define SELECT_IMAGE_TXT "Select image..."
+#define RESTORE_FILE "impuzzle.restore"
+#define HOME_DIRECTORY ".impuzzle"
+
#endif // DEFINES_H
#include "puzzleitem.h"
#include "defines.h"
#include "introitem.h"
+#include "imageimporter.h"
+#include "settings.h"
#include <QGraphicsScene>
#include <QDateTime>
#include <QParallelAnimationGroup>
#include <QFont>
#include <QMessageBox>
+#include <QFile>
+#include <QDir>
+#include <QTextStream>
+#include <QCloseEvent>
#include <QDebug>
introItem_ = new IntroItem;
introItem_->setText("Select new game from menu to play");
- scene_->addItem(introItem_);
verticalStep_ = 0;
horizontalStep_ = 0;
qsrand(QDateTime::currentDateTime().toTime_t());
+
+ if(QFile::exists(QString("%1/%2/%3")
+ .arg(QDir::homePath()).arg(HOME_DIRECTORY).arg(RESTORE_FILE))) {
+ if(!restoreGame()) {
+ setPieces(ImageImporter::instance()->newPieces(Settings::instance()->image(), Settings::instance()->pieceCount()));
+ }
+ }
+ else {
+ scene_->addItem(introItem_);
+ }
}
GameView *GameView::instance()
return pieces_;
}
-void GameView::setPieces(const QList<PuzzleItem *> pieces)
+void GameView::setPieces(const QList<PuzzleItem *> pieces, bool shuffle)
{
if(pieces.isEmpty()) {
qDebug() << "Empty list @ GameView::setPieces";
}
}
- // Wait
- QTimer::singleShot(750, this, SLOT(shufflePieces()));
+ // Wait and shuffle if desired
+ if(shuffle) {
+ QTimer::singleShot(750, this, SLOT(shufflePieces()));
+ }
}
void GameView::shufflePieces()
}
}
- // TODO Animate transitions to new locations
QParallelAnimationGroup *animationGroup = new QParallelAnimationGroup(this);
for(int i = 0; i < pieces_.count(); ++i) {
QPropertyAnimation *animation = new QPropertyAnimation(pieces_.at(i), "pos");
}
}
}
+
+bool GameView::restoreGame()
+{
+ // Read settings from file
+ QFile file(QString("%1/%2/%3")
+ .arg(QDir::homePath())
+ .arg(HOME_DIRECTORY)
+ .arg(RESTORE_FILE));
+
+ if(!file.open(QIODevice::ReadOnly)) {
+ qDebug() << "Failed to open restore file for reading";
+ return false;
+ }
+
+ QTextStream in(&file);
+
+ QStringList list;
+
+ list = in.readLine().split(";;");
+
+ qDebug() << "restore list count: " << list.count();
+
+ if(!list.isEmpty()) {
+ Settings::instance()->setPieceCount(list.at(0).toInt());
+
+ QString im = list.at(1);
+ if(im == "default" || im.isEmpty()) {
+ Settings::instance()->setImage(0);
+ Settings::instance()->setImagePath("default");
+ }
+ else {
+ Settings::instance()->setImagePath(im);
+ Settings::instance()->setImage(QPixmap(im));
+ }
+ PuzzleItem::setMoveCount(list.at(2).toInt());
+
+ setPieces(ImageImporter::instance()->newPieces(Settings::instance()->image(), Settings::instance()->pieceCount()), false);
+
+ qDebug() << "pieces_ count after restoring image: " << pieces_.count();
+
+ if(list.count() >= pieces_.count() + 3) {
+ 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)
+ QPointF point(points.at(0).toInt(), points.at(1).toInt());
+
+ qDebug() << "Setting piece " << pieces_.at(j)->pieceNumber();
+ qDebug() << "x: " << point.x() << " y: " << point.y();
+
+ pieces_.at(j)->setCurrentPlace(point);
+ }
+ }
+ }
+ else {
+ file.close();
+ file.remove();
+ return false;
+ }
+
+ QStringList hidden = list.last().split("#");
+
+ if(hidden.count() == 3) {
+ for(int m = 0; m < pieces_.count(); ++m) {
+ pieces_.at(m)->setPos(pieces_.at(m)->currentPlace());
+ if(pieces_.at(m)->pieceNumber() == hidden.at(2).toInt()) {
+ qDebug() << "Hiding piece number " << hidden;
+ hiddenIndex_ = m;
+ }
+ }
+
+ setEmptyPlace(QPointF(hidden.at(0).toInt(), hidden.at(1).toInt()));
+
+ pieces_.at(hiddenIndex_)->setVisible(false);
+
+ setMovingPieces();
+ }
+ else {
+ // TODO: revert
+ setPieces(ImageImporter::instance()->newPieces(Settings::instance()->image(), Settings::instance()->pieceCount()));
+ file.close();
+ file.remove();
+ return false;
+ }
+ }
+ else {
+ qDebug() << "Invalid restore file";
+ file.close();
+ file.remove();
+ return false;
+ }
+
+ file.close();
+ file.remove();
+
+ return true;
+}
+
+bool GameView::saveGame()
+{
+ if(pieces_.isEmpty() || pieces_.count() < EASY_PIECE_COUNT) {
+ return false;
+ }
+
+ QDir dir;
+ if(!dir.exists(QString("%1/%2")
+ .arg(QDir::homePath())
+ .arg(HOME_DIRECTORY))) {
+ dir.mkpath(QString("%1/%2")
+ .arg(QDir::homePath())
+ .arg(HOME_DIRECTORY));
+ }
+
+ QFile file(QString("%1/%2/%3")
+ .arg(QDir::homePath())
+ .arg(HOME_DIRECTORY)
+ .arg(RESTORE_FILE));
+
+ if(!file.open(QIODevice::WriteOnly)) {
+ qDebug() << "Failed to open restore file for writing";
+ return false;
+ }
+
+ QTextStream out(&file);
+
+ out << Settings::instance()->pieceCount();
+ out << ";;";
+ if(Settings::instance()->imagePath().isEmpty()) {
+ out << "default";
+ }
+ else {
+ out << Settings::instance()->imagePath();
+ }
+ out << ";;";
+ out << PuzzleItem::moveCount();
+ out << ";;";
+
+ // piece positions
+ int number = 0;
+ int hiddenNo = 0;
+
+ while(number != pieces_.count()) {
+ for(int i = 0; i < pieces_.count(); ++i) {
+ if(pieces_.at(i)->pieceNumber() == number + 1) {
+ out << pieces_.at(i)->currentPlace().x();
+ out << "#";
+ out << pieces_.at(i)->currentPlace().y();
+ out << ";;";
+ pieces_.at(i)->pieceNumber();
+ if(!pieces_.at(i)->isVisible()) {
+ hiddenNo = number + 1;
+ }
+ number++;
+ break;
+ }
+ }
+ }
+
+ out << QString("%1#%2#%3").arg(emptyPlace().x()).arg(emptyPlace().y()).arg(hiddenNo);
+
+ out << "\n";
+
+ file.close();
+
+ return true;
+}
+
+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();
+}
void setMovingPieces();
public slots:
- void setPieces(const QList<PuzzleItem *> pieces);
+ void setPieces(const QList<PuzzleItem *> pieces, bool shuffle = true);
void shufflePieces();
+ bool restoreGame();
+ bool saveGame();
+
+protected:
+ void closeEvent(QCloseEvent *event);
private:
GameView(QWidget *parent = 0);
{
menu_ = menuBar()->addMenu("");
menu_->addAction(newGameAction_);
+ menu_->addAction(saveAction_);
menu_->addAction(importAction_);
}
settingsAction_ = new QAction(tr("Settings"), this);
connect(settingsAction_, SIGNAL(triggered()), this, SLOT(settingsClicked()));
+
+ saveAction_ = new QAction(tr("Save game"), this);
+ connect(saveAction_, SIGNAL(triggered()), GameView::instance(), SLOT(saveGame()));
}
void MainWindow::importClicked()
QAction *newGameAction_;
QAction *importAction_;
QAction *settingsAction_;
+ QAction *saveAction_;
QMenu *menu_;
{
return drawNumber_;
}
+
+void PuzzleItem::setMoveCount(int count)
+{
+ moveCount_ = count;
+}
void setMovable(bool canMove);
void moveMeTo(const QPointF &location);
static int moveCount();
+ static void setMoveCount(const int count);
static void resetMoveCount();
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void setPieceNumber(const int pieceNumber);
{
pieceCount_ = EASY_PIECE_COUNT;
image_ = 0;
+ imagePath_ = "";
}
Settings *Settings::instance()
{
image_ = image;
}
+
+QString Settings::imagePath() const
+{
+ return imagePath_;
+}
+
+void Settings::setImagePath(const QString &path)
+{
+ imagePath_ = path;
+}
QPixmap image() const;
void setImage(const QPixmap &image);
+ QString imagePath() const;
+ void setImagePath(const QString &path);
+
private:
Settings(QObject *parent = 0);
int pieceCount_;
QPixmap image_;
+ QString imagePath_;
};
#endif
qDebug() << QString("pics list contains %1 entries").arg(pics.count());
- Settings::instance()->setImage(QPixmap(QDir::homePath() + QLatin1String("/MyDocs/.images/") + pics.at(qrand() % pics.count())));
+ QString path = QDir::homePath() + QLatin1String("/MyDocs/.images/") + pics.at(qrand() % pics.count());
+ Settings::instance()->setImage(QPixmap(path));
+ Settings::instance()->setImagePath(path);
if(selectedImageLabel_->isVisible()) {
selectedImageLabel_->setVisible(false);
tr("Images (*.png *.xpm *.jpg)"));
Settings::instance()->setImage(QPixmap(fileName));
+ Settings::instance()->setImagePath(fileName);
selectedImageLabel_->setText(fileName);
qDebug() << "Default image selected";
Settings::instance()->setImage(0);
+ Settings::instance()->setImagePath("default");
if(selectedImageLabel_->isVisible()) {
selectedImageLabel_->setVisible(false);