00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "minesweep.h"
00022 #include "minefield.h"
00023
00024 #include <opie2/oresource.h>
00025
00026 #include <qtopia/qpeapplication.h>
00027 #include <qtopia/config.h>
00028
00029 #include <qtoolbar.h>
00030 #include <qmenubar.h>
00031 #include <qpushbutton.h>
00032 #include <qlcdnumber.h>
00033 #include <qtimer.h>
00034 #include <qlabel.h>
00035
00036 #include <stdlib.h>
00037 #include <time.h>
00038
00039
00040
00041
00042 static const char *pix_new[]={
00043 "20 20 3 1",
00044 " c None",
00045 "# c #00FF00",
00046 ". c #000000",
00047 " ",
00048 " ...... ",
00049 " ..######.. ",
00050 " .##########. ",
00051 " .############. ",
00052 " .##############. ",
00053 " .##############. ",
00054 " .################. ",
00055 " .################. ",
00056 " .################. ",
00057 " .################. ",
00058 " .################. ",
00059 " .################. ",
00060 " .##############. ",
00061 " .##############. ",
00062 " .############. ",
00063 " .##########. ",
00064 " ..######.. ",
00065 " ...... ",
00066 " "};
00067
00068
00069
00070 static const char * happy_xpm[] = {
00071 "20 20 3 1",
00072 " c None",
00073 ". c #ffff3f ",
00074 "# c #000000",
00075 " ",
00076 " ###### ",
00077 " ##......## ",
00078 " #..........# ",
00079 " #............# ",
00080 " #..............# ",
00081 " #..............# ",
00082 " #....##....##....# ",
00083 " #....##....##....# ",
00084 " #................# ",
00085 " #................# ",
00086 " #................# ",
00087 " #...#........#...# ",
00088 " #.##........##.# ",
00089 " #...########...# ",
00090 " #...######...# ",
00091 " #..........# ",
00092 " ##......## ",
00093 " ###### ",
00094 " "};
00095
00096
00097
00098 static const char * worried_xpm[] = {
00099 "20 20 3 1",
00100 " c None",
00101 ". c #ffff3f",
00102 "# c #000000",
00103 " ",
00104 " ###### ",
00105 " ##......## ",
00106 " #..........# ",
00107 " #............# ",
00108 " #..............# ",
00109 " #..............# ",
00110 " #....##....##....# ",
00111 " #....##....##....# ",
00112 " #................# ",
00113 " #................# ",
00114 " #................# ",
00115 " #................# ",
00116 " #....######....# ",
00117 " #..............# ",
00118 " #............# ",
00119 " #..........# ",
00120 " ##......## ",
00121 " ###### ",
00122 " "};
00123
00124
00125
00126 static const char * dead_xpm[] = {
00127 "20 20 3 1",
00128 " c None",
00129 ". c #ffff3f",
00130 "# c #000000",
00131 " ",
00132 " ###### ",
00133 " ##......## ",
00134 " #..........# ",
00135 " #............# ",
00136 " #..............# ",
00137 " #..#.#...#.#...# ",
00138 " #....#.....#.....# ",
00139 " #...#.#...#.#....# ",
00140 " #................# ",
00141 " #................# ",
00142 " #................# ",
00143 " #......####......# ",
00144 " #....# #....# ",
00145 " #...#......#...# ",
00146 " #............# ",
00147 " #..........# ",
00148 " ##......## ",
00149 " ###### ",
00150 " "};
00151
00152
00153 class ResultIndicator : private QLabel
00154 {
00155 public:
00156 static void showResult( QWidget *ref, bool won );
00157 private:
00158 ResultIndicator( QWidget *parent, const char *name, WFlags f)
00159 :QLabel( parent, name, f ) {}
00160
00161 void timerEvent( QTimerEvent *);
00162 void center();
00163 bool twoStage;
00164 int timerId;
00165 };
00166
00167 void ResultIndicator::showResult( QWidget *ref, bool won )
00168 {
00169 ResultIndicator *r = new ResultIndicator( ref, 0, WStyle_Customize | WStyle_Tool | WType_TopLevel );
00170
00171 r->setAlignment( AlignCenter );
00172 r->setFrameStyle( Sunken|StyledPanel );
00173 if ( won ) {
00174 r->setText( MineSweep::tr("You won!") );
00175 r->center();
00176 r->show();
00177 r->twoStage = FALSE;
00178 r->timerId = r->startTimer(1500);
00179 } else {
00180 QPalette p( red );
00181 r->setPalette( p );
00182 r->setText( MineSweep::tr("You exploded!") );
00183 r->resize( ref->size() );
00184 r->move( ref->mapToGlobal(QPoint(0,0)) );
00185 r->show();
00186 r->twoStage = TRUE;
00187 r->timerId =r->startTimer(200);
00188 }
00189 }
00190
00191 void ResultIndicator::center()
00192 {
00193 QWidget *w = parentWidget();
00194
00195 QPoint pp = w->mapToGlobal( QPoint(0,0) );
00196 QSize s = sizeHint()*3;
00197 s.setWidth( QMIN(s.width(), w->width()) );
00198 pp = QPoint( pp.x() + w->width()/2 - s.width()/2,
00199 pp.y() + w->height()/ 2 - s.height()/2 );
00200
00201 setGeometry( QRect(pp, s) );
00202
00203 }
00204
00205 void ResultIndicator::timerEvent( QTimerEvent *te )
00206 {
00207 if ( te->timerId() != timerId )
00208 return;
00209 killTimer( timerId );
00210 if ( twoStage ) {
00211 center();
00212 twoStage = FALSE;
00213 timerId = startTimer( 1000 );
00214 } else {
00215 delete this;
00216 }
00217 }
00218
00219
00220 class MineFrame : public QFrame
00221 {
00222 public:
00223 MineFrame( QWidget *parent, const char *name = 0 )
00224 :QFrame( parent, name ), field(0) {}
00225 void setField( MineField *f ) {
00226 field = f;
00227 setMinimumSize( field->sizeHint() );
00228 }
00229 protected:
00230 void resizeEvent( QResizeEvent *e ) {
00231 field->setAvailableRect( contentsRect());
00232 QFrame::resizeEvent(e);
00233 }
00234 private:
00235 MineField *field;
00236 };
00237
00238
00239
00240 MineSweep::MineSweep( QWidget* parent, const char* name, WFlags f )
00241 : QMainWindow( parent, name, f )
00242 {
00243 srand(::time(0));
00244 setCaption( tr("Mine Sweep") );
00245 QPEApplication::setInputMethodHint(this, QPEApplication::AlwaysOff );
00246 setIcon( Opie::Core::OResource::loadPixmap( "minesweep/MineSweep" ) );
00247
00248 QToolBar *toolBar = new QToolBar( this );
00249 toolBar->setHorizontalStretchable( TRUE );
00250
00251 QMenuBar *menuBar = new QMenuBar( toolBar );
00252
00253 QPopupMenu *gameMenu = new QPopupMenu( this );
00254 gameMenu->insertItem( tr("Beginner"), this, SLOT( beginner() ) );
00255 gameMenu->insertItem( tr("Advanced"), this, SLOT( advanced() ) );
00256
00257 if (qApp->desktop()->width() >= 240) {
00258 gameMenu->insertItem( tr("Expert"), this, SLOT( expert() ) );
00259 }
00260
00261 menuBar->insertItem( tr("Game"), gameMenu );
00262
00263 guessLCD = new QLCDNumber( toolBar );
00264 toolBar->setStretchableWidget( guessLCD );
00265
00266 QPalette lcdPal( red );
00267 lcdPal.setColor( QColorGroup::Background, QApplication::palette().active().background() );
00268 lcdPal.setColor( QColorGroup::Button, QApplication::palette().active().button() );
00269
00270
00271 guessLCD->setSegmentStyle( QLCDNumber::Flat );
00272 guessLCD->setFrameStyle( QFrame::NoFrame );
00273 guessLCD->setNumDigits( 2 );
00274 guessLCD->setBackgroundMode( PaletteButton );
00275 newGameButton = new QPushButton( toolBar );
00276 newGameButton->setPixmap( QPixmap( pix_new ) );
00277 newGameButton->setFocusPolicy(QWidget::NoFocus);
00278 connect( newGameButton, SIGNAL(clicked()), this, SLOT(newGame()) );
00279
00280 timeLCD = new QLCDNumber( toolBar );
00281
00282 timeLCD->setSegmentStyle( QLCDNumber::Flat );
00283 timeLCD->setFrameStyle( QFrame::NoFrame );
00284 timeLCD->setNumDigits( 5 );
00285 timeLCD->setBackgroundMode( PaletteButton );
00286
00287 setToolBarsMovable ( FALSE );
00288
00289 addToolBar( toolBar );
00290
00291 MineFrame *mainframe = new MineFrame( this );
00292 mainframe->setFrameShape( QFrame::Box );
00293 mainframe->setFrameShadow( QFrame::Raised );
00294
00295 mainframe->setLineWidth(2);
00296
00297 field = new MineField( mainframe );
00298 mainframe->setField( field );
00299 QFont fnt = field->font();
00300 fnt.setBold( TRUE );
00301 field->setFont( QFont( fnt ) );
00302 field->setFocus();
00303 setCentralWidget( mainframe );
00304
00305 connect( field, SIGNAL( gameOver(bool) ), this, SLOT( gameOver(bool) ) );
00306 connect( field, SIGNAL( mineCount(int) ), this, SLOT( setCounter(int) ) );
00307 connect( field, SIGNAL( gameStarted()), this, SLOT( startPlaying() ) );
00308
00309 timer = new QTimer( this );
00310 connect( timer, SIGNAL( timeout() ), this, SLOT( updateTime() ) );
00311
00312 readConfig();
00313 }
00314
00315 MineSweep::~MineSweep()
00316 {
00317 writeConfig();
00318 }
00319
00320 void MineSweep::gameOver( bool won )
00321 {
00322 field->showMines();
00323 if ( won ) {
00324 newGameButton->setPixmap( QPixmap( happy_xpm ) );
00325 } else {
00326 newGameButton->setPixmap( QPixmap( dead_xpm ) );
00327 }
00328 ResultIndicator::showResult( this, won );
00329 timer->stop();
00330 }
00331
00332 void MineSweep::newGame()
00333 {
00334 newGame(field->level());
00335 }
00336
00337 void MineSweep::newGame(int level)
00338 {
00339 timeLCD->display( "0:00" );
00340 field->setup( level );
00341 newGameButton->setPixmap( QPixmap( pix_new ) );
00342 timer->stop();
00343 }
00344
00345 void MineSweep::startPlaying()
00346 {
00347 newGameButton->setPixmap( QPixmap( worried_xpm ) );
00348 starttime = QDateTime::currentDateTime();
00349 timer->start( 1000 );
00350 }
00351
00352 void MineSweep::beginner()
00353 {
00354 newGame(1);
00355 }
00356
00357 void MineSweep::advanced()
00358 {
00359 newGame(2);
00360 }
00361
00362 void MineSweep::expert()
00363 {
00364 newGame(3);
00365 }
00366
00367 void MineSweep::setCounter( int c )
00368 {
00369 if ( !guessLCD )
00370 return;
00371
00372 guessLCD->display( c );
00373 }
00374
00375 void MineSweep::updateTime()
00376 {
00377 if ( !timeLCD )
00378 return;
00379
00380 int s = starttime.secsTo(QDateTime::currentDateTime());
00381 if ( s/60 > 99 )
00382 timeLCD->display( "-----" );
00383 else
00384 timeLCD->display( QString().sprintf("%2d:%02d",s/60,s%60) );
00385 }
00386
00387 void MineSweep::writeConfig() const
00388 {
00389 Config cfg("MineSweep");
00390 cfg.setGroup("Panel");
00391 cfg.writeEntry("Time",
00392 timer->isActive() ? starttime.secsTo(QDateTime::currentDateTime()) : -1);
00393 field->writeConfig(cfg);
00394 }
00395
00396 void MineSweep::readConfig()
00397 {
00398 Config cfg("MineSweep");
00399 field->readConfig(cfg);
00400 cfg.setGroup("Panel");
00401 int s = cfg.readNumEntry("Time",-1);
00402 if ( s<0 ) {
00403 newGame();
00404 } else {
00405 startPlaying();
00406 starttime = QDateTime::currentDateTime().addSecs(-s);
00407 updateTime();
00408 }
00409 }