-rw-r--r-- | noncore/games/minesweep/minefield.cpp | 144 | ||||
-rw-r--r-- | noncore/games/minesweep/minefield.h | 7 | ||||
-rw-r--r-- | noncore/games/minesweep/minesweep.cpp | 34 |
3 files changed, 110 insertions, 75 deletions
diff --git a/noncore/games/minesweep/minefield.cpp b/noncore/games/minesweep/minefield.cpp index 04cfb97..1790110 100644 --- a/noncore/games/minesweep/minefield.cpp +++ b/noncore/games/minesweep/minefield.cpp @@ -1,725 +1,751 @@ /********************************************************************** -** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** -** This file is part of Qtopia Environment. +** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "minefield.h" -#include <qpe/config.h> +#include <qtopia/config.h> +#include <qtopia/qpeapplication.h> #include <qpainter.h> #include <qdrawutil.h> #include <qpixmap.h> #include <qimage.h> #include <qtimer.h> #include <stdlib.h> static const char *pix_flag[]={ "13 13 3 1", "# c #000000", "x c #ff0000", ". c None", ".............", ".............", ".....#xxxxxx.", ".....#xxxxxx.", ".....#xxxxxx.", ".....#xxxxxx.", ".....#.......", ".....#.......", ".....#.......", ".....#.......", "...#####.....", "..#######....", "............."}; static const char *pix_mine[]={ "13 13 3 1", "# c #000000", ". c None", "a c #ffffff", "......#......", "......#......", "..#.#####.#..", "...#######...", "..##aa#####..", "..##aa#####..", "#############", "..#########..", "..#########..", "...#######...", "..#.#####.#..", "......#......", "......#......"}; static const int maxGrid = 28; -static const int minGrid = 9; +static const int minGrid = 12; class Mine : public Qt { public: enum MineState { Hidden = 0, Empty, Mined, Flagged, #ifdef MARK_UNSURE Unsure, #endif Exploded, Wrong }; Mine( MineField* ); void paint( QPainter * p, const QColorGroup & cg, const QRect & cr ); QSize sizeHint() const { return QSize( maxGrid, maxGrid ); } void activate( bool sure = TRUE ); void setHint( int ); void setState( MineState ); MineState state() const { return st; } bool isMined() const { return mined; } void setMined( bool m ) { mined = m; } static void paletteChange(); private: bool mined; int hint; MineState st; MineField *field; static QPixmap* knownField; static QPixmap* unknownField; static QPixmap* flag_pix; static QPixmap* mine_pix; }; QPixmap* Mine::knownField = 0; QPixmap* Mine::unknownField = 0; QPixmap* Mine::flag_pix = 0; QPixmap* Mine::mine_pix = 0; Mine::Mine( MineField *f ) { mined = FALSE; st = Hidden; hint = 0; field = f; } void Mine::activate( bool sure ) { if ( !sure ) { switch ( st ) { case Hidden: setState( Flagged ); break; case Flagged: #ifdef MARK_UNSURE setState( Unsure ); break; case Unsure: #endif setState( Hidden ); default: break; } } else if ( st == Flagged ) { return; } else { if ( mined ) { setState( Exploded ); } else { setState( Empty ); } } } void Mine::setState( MineState s ) { st = s; } void Mine::setHint( int h ) { hint = h; } void Mine::paletteChange() { delete knownField; knownField = 0; delete unknownField; unknownField = 0; delete mine_pix; mine_pix = 0; delete flag_pix; flag_pix = 0; } void Mine::paint( QPainter* p, const QColorGroup &cg, const QRect& cr ) { int x = cr.x(); int y = cr.y(); - if ( !knownField ) { + if ( !knownField || knownField->width() != cr.width() || + knownField->height() != cr.height() ) { + delete knownField; knownField = new QPixmap( cr.width(), cr.height() ); QPainter pp( knownField ); QBrush br( cg.button().dark(115) ); - qDrawWinButton( &pp, cr, cg, TRUE, &br ); + qDrawWinButton( &pp, QRect( 0, 0, cr.width(), cr.height() ), cg, TRUE, &br ); } const int pmmarg=cr.width()/5; - if ( !unknownField ) { + if ( !unknownField || unknownField->width() != cr.width() || + unknownField->height() != cr.height() ) { + delete unknownField; unknownField = new QPixmap( cr.width(), cr.height() ); QPainter pp( unknownField ); QBrush br( cg.button() ); - qDrawWinButton( &pp, cr, cg, FALSE, &br ); + qDrawWinButton( &pp, QRect( 0, 0, cr.width(), cr.height() ), cg, FALSE, &br ); } - if ( !flag_pix ) { + if ( !flag_pix || flag_pix->width() != cr.width()-pmmarg*2 || + flag_pix->height() != cr.height()-pmmarg*2 ) { + delete flag_pix; flag_pix = new QPixmap( cr.width()-pmmarg*2, cr.height()-pmmarg*2 ); flag_pix->convertFromImage( QImage(pix_flag).smoothScale(cr.width()-pmmarg*2, cr.height()-pmmarg*2) ); } - if ( !mine_pix ) { + if ( !mine_pix || mine_pix->width() != cr.width()-pmmarg*2 || + mine_pix->height() != cr.height()-pmmarg*2 ) { + delete mine_pix; mine_pix = new QPixmap( cr.width()-pmmarg*2, cr.height()-pmmarg*2 ); mine_pix->convertFromImage( QImage(pix_mine).smoothScale(cr.width()-pmmarg*2, cr.height()-pmmarg*2) ); } p->save(); switch(st) { case Hidden: p->drawPixmap( x, y, *unknownField ); break; case Empty: p->drawPixmap( x, y, *knownField ); if ( hint > 0 ) { switch( hint ) { case 1: p->setPen( blue ); break; case 2: p->setPen( green.dark() ); break; case 3: p->setPen( red ); break; case 4: p->setPen( darkYellow.dark() ); break; case 5: p->setPen( darkMagenta ); break; case 6: p->setPen( darkRed ); break; default: p->setPen( black ); break; } p->drawText( cr, AlignHCenter | AlignVCenter, QString::number( hint ) ); } break; case Mined: p->drawPixmap( x, y, *knownField ); p->drawPixmap( x+pmmarg, y+pmmarg, *mine_pix ); break; case Exploded: p->drawPixmap( x, y, *knownField ); p->drawPixmap( x+pmmarg, y+pmmarg, *mine_pix ); p->setPen( red ); p->drawText( cr, AlignHCenter | AlignVCenter, "X" ); break; case Flagged: p->drawPixmap( x, y, *unknownField ); p->drawPixmap( x+pmmarg, y+pmmarg, *flag_pix ); break; #ifdef MARK_UNSURE case Unsure: p->drawPixmap( x, y, *unknownField ); p->drawText( cr, AlignHCenter | AlignVCenter, "?" ); break; #endif case Wrong: p->drawPixmap( x, y, *unknownField ); p->drawPixmap( x+pmmarg, y+pmmarg, *flag_pix ); p->setPen( red ); p->drawText( cr, AlignHCenter | AlignVCenter, "X" ); break; } p->restore(); } /* MineField implementation */ MineField::MineField( QWidget* parent, const char* name ) : QScrollView( parent, name ) { + viewport()->setBackgroundMode( NoBackground ); setState( GameOver ); setSizePolicy( QSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ) ); - + setFocusPolicy( QWidget::NoFocus ); holdTimer = new QTimer( this ); connect( holdTimer, SIGNAL( timeout() ), this, SLOT( held() ) ); flagAction = NoAction; ignoreClick = FALSE; currRow = currCol = -1; minecount=0; mineguess=0; nonminecount=0; cellSize = -1; - mines = 0; + + numRows = numCols = 0; + mines = NULL; } MineField::~MineField() { - int i; - if ( mines ) - { - for ( i = 0; i < numCols*numRows; i++ ) - { - delete mines[i]; - } - delete[] mines; - } + for ( int i = 0; i < numCols*numRows; i++ ) + delete mines[i]; + delete[] mines; } void MineField::setState( State st ) { stat = st; } void MineField::setup( int level ) { lev = level; setState( Waiting ); //viewport()->setUpdatesEnabled( FALSE ); int i; - if ( mines ) - { - for ( i = 0; i < numCols*numRows; i++ ) - { - delete mines[i]; - } - delete[] mines; - } + for ( i = 0; i < numCols*numRows; i++ ) + delete mines[i]; + delete[] mines; switch( lev ) { case 1: numRows = 9 ; numCols = 9 ; minecount = 12; break; case 2: - numRows = 16; - numCols = 16; - minecount = 45; + numRows = 13; + numCols = 13; + minecount = 33; break; case 3: numCols = 18; numRows = 18; minecount = 66 ; break; } - mines = new Mine*[numRows*numCols]; + mines = new Mine* [numRows*numCols]; for ( i = 0; i < numCols*numRows; i++ ) mines[i] = new Mine( this ); - + nonminecount = numRows*numCols - minecount; mineguess = minecount; emit mineCount( mineguess ); Mine::paletteChange(); if ( availableRect.isValid() ) setCellSize(findCellSize()); // viewport()->setUpdatesEnabled( TRUE ); //viewport()->repaint( TRUE ); updateContents( 0, 0, numCols*cellSize, numRows*cellSize ); updateGeometry(); } -void MineField::drawContents( QPainter * p, int clipx, int clipy, int clipw, int cliph ) +void MineField::drawContents( QPainter * p, int clipx, int clipy, int clipw, int cliph ) { int c1 = clipx / cellSize; int c2 = ( clipx + clipw - 1 ) / cellSize; int r1 = clipy / cellSize; int r2 = ( clipy + cliph - 1 ) / cellSize; - + for ( int c = c1; c <= c2 ; c++ ) { for ( int r = r1; r <= r2 ; r++ ) { int x = c * cellSize; int y = r * cellSize; Mine *m = mine( r, c ); if ( m ) m->paint( p, colorGroup(), QRect(x, y, cellSize, cellSize ) ); } } } // Chicken and egg problem: We need to know how big the parent is // before we can decide how big to make the table. void MineField::setAvailableRect( const QRect &r ) { availableRect = r; int newCellSize = findCellSize(); - if ( newCellSize != cellSize ) { + + + if ( newCellSize == cellSize ) { + setCellSize( cellSize ); + } else { viewport()->setUpdatesEnabled( FALSE ); setCellSize( newCellSize ); viewport()->setUpdatesEnabled( TRUE ); viewport()->repaint( TRUE ); } } int MineField::findCellSize() { - int w = availableRect.width() - 1; - int h = availableRect.height() - 1; + int w = availableRect.width() - 2; + int h = availableRect.height() - 2; int cellsize; - + cellsize = QMIN( w/numCols, h/numRows ); cellsize = QMIN( QMAX( cellsize, minGrid ), maxGrid ); return cellsize; } void MineField::setCellSize( int cellsize ) { - cellSize = cellsize; - - int w = availableRect.width(); - int h = availableRect.height(); - + int b = 2; + int w2 = cellsize*numCols; int h2 = cellsize*numRows; - - resizeContents( w2, h2 ); - - int b = 5; - - setGeometry( availableRect.x() + (w-w2)/2, availableRect.y() + (h-h2)/2, - w2+b, h2+b ); -// QMIN(w,w2+b), QMIN(h,h2+b) ); + + int w = QMIN( availableRect.width(), w2+b ); + int h = QMIN( availableRect.height(), h2+b ); + + // + // Don't rely on the change in cellsize to force a resize, + // as it's possible to have the same size cells when going + // from a large play area to a small one. + // + resizeContents(w2, h2); + + if ( availableRect.height() < h2 && + availableRect.width() - w > style().scrollBarExtent().width() ) { + w += style().scrollBarExtent().width(); + } + + setGeometry( availableRect.x() + (availableRect.width()-w)/2, + availableRect.y() + (availableRect.height()-h)/2, w, h ); + cellSize = cellsize; } void MineField::placeMines() { int mines = minecount; while ( mines ) { int col = int((double(rand()) / double(RAND_MAX)) * numCols); int row = int((double(rand()) / double(RAND_MAX)) * numRows); Mine* m = mine( row, col ); if ( m && !m->isMined() && m->state() == Mine::Hidden ) { m->setMined( TRUE ); mines--; } } } void MineField::updateCell( int r, int c ) { updateContents( c*cellSize, r*cellSize, cellSize, cellSize ); } void MineField::contentsMousePressEvent( QMouseEvent* e ) { int c = e->pos().x() / cellSize; int r = e->pos().y() / cellSize; if ( onBoard( r, c ) ) cellPressed( r, c ); else currCol = currRow = -1; } void MineField::contentsMouseReleaseEvent( QMouseEvent* e ) { int c = e->pos().x() / cellSize; int r = e->pos().y() / cellSize; if ( onBoard( r, c ) && c == currCol && r == currRow ) cellClicked( r, c ); if ( flagAction == FlagNext ) { flagAction = NoAction; } } /* state == Waiting means no "hold" */ void MineField::cellPressed( int row, int col ) { if ( state() == GameOver ) return; currRow = row; currCol = col; if ( state() == Playing ) holdTimer->start( 150, TRUE ); } void MineField::held() { flagAction = FlagNext; updateMine( currRow, currCol ); ignoreClick = TRUE; } void MineField::keyPressEvent( QKeyEvent* e ) { #if defined(Q_WS_QWS) || defined(_WS_QWS_) flagAction = ( e->key() == Key_Up ) ? FlagOn : NoAction; #else flagAction = ( ( e->state() & ShiftButton ) == ShiftButton ) ? FlagOn : NoAction; #endif } void MineField::keyReleaseEvent( QKeyEvent* ) { flagAction = NoAction; } int MineField::getHint( int row, int col ) { int hint = 0; for ( int c = col-1; c <= col+1; c++ ) for ( int r = row-1; r <= row+1; r++ ) { Mine* m = mine( r, c ); if ( m && m->isMined() ) hint++; } return hint; } void MineField::setHint( int row, int col ) { Mine *m = mine( row, col ); if ( !m ) return; int hint = getHint( row, col ); if ( !hint ) { for ( int c = col-1; c <= col+1; c++ ) for ( int r = row-1; r <= row+1; r++ ) { Mine* m = mine( r, c ); if ( m && m->state() == Mine::Hidden ) { m->activate( TRUE ); nonminecount--; setHint( r, c ); updateCell( r, c ); } } } m->setHint( hint ); updateCell( row, col ); } /* Only place mines after first click, since it is pointless to kill the player before the game has started. */ void MineField::cellClicked( int row, int col ) { if ( state() == GameOver ) return; if ( state() == Waiting ) { Mine* m = mine( row, col ); if ( !m ) return; m->setState( Mine::Empty ); nonminecount--; placeMines(); setState( Playing ); emit gameStarted(); updateMine( row, col ); } else { // state() == Playing holdTimer->stop(); if ( ignoreClick ) ignoreClick = FALSE; else updateMine( row, col ); } } void MineField::updateMine( int row, int col ) { Mine* m = mine( row, col ); if ( !m ) return; bool wasFlagged = m->state() == Mine::Flagged; bool wasEmpty = m->state() == Mine::Empty; m->activate( flagAction == NoAction ); if ( m->state() == Mine::Exploded ) { emit gameOver( FALSE ); setState( GameOver ); return; } else if ( m->state() == Mine::Empty ) { setHint( row, col ); if ( !wasEmpty ) nonminecount--; } if ( flagAction != NoAction ) { if ( m->state() == Mine::Flagged ) { - --mineguess; - emit mineCount( mineguess ); - if ( m->isMined() ) - --minecount; + if (mineguess > 0) { + --mineguess; + emit mineCount( mineguess ); + if ( m->isMined() ) + --minecount; + } else { + m->setState(Mine::Hidden); + } } else if ( wasFlagged ) { ++mineguess; emit mineCount( mineguess ); if ( m->isMined() ) ++minecount; } } updateCell( row, col ); if ( !minecount && !mineguess || !nonminecount ) { emit gameOver( TRUE ); setState( GameOver ); } } void MineField::showMines() { for ( int c = 0; c < numCols; c++ ) for ( int r = 0; r < numRows; r++ ) { Mine* m = mine( r, c ); if ( !m ) continue; if ( m->isMined() && m->state() == Mine::Hidden ) m->setState( Mine::Mined ); if ( !m->isMined() && m->state() == Mine::Flagged ) m->setState( Mine::Wrong ); updateCell( r, c ); } } void MineField::paletteChange( const QPalette &o ) { Mine::paletteChange(); QScrollView::paletteChange( o ); } void MineField::writeConfig(Config& cfg) const { cfg.setGroup("Field"); cfg.writeEntry("Level",lev); QString grid=""; if ( stat == Playing ) { for ( int x = 0; x < numCols; x++ ) for ( int y = 0; y < numRows; y++ ) { char code='A'+(x*17+y*101)%21; // Reduce the urge to cheat const Mine* m = mine( y, x ); int st = (int)m->state(); if ( m->isMined() ) st+=5; grid += code + st; } } cfg.writeEntry("Grid",grid); } void MineField::readConfig(Config& cfg) { cfg.setGroup("Field"); lev = cfg.readNumEntry("Level",1); setup(lev); flagAction = NoAction; ignoreClick = FALSE; currRow = currCol = 0; QString grid = cfg.readEntry("Grid"); + int x; if ( !grid.isEmpty() ) { int i=0; minecount=0; mineguess=0; - for ( int x = 0; x < numCols; x++ ) { + for ( x = 0; x < numCols; x++ ) { for ( int y = 0; y < numRows; y++ ) { char code='A'+(x*17+y*101)%21; // Reduce the urge to cheat int st = (char)(QChar)grid[i++]-code; Mine* m = mine( y, x ); if ( st >= 5 ) { st-=5; m->setMined(TRUE); minecount++; mineguess++; } m->setState((Mine::MineState)st); switch ( m->state() ) { case Mine::Flagged: if (m->isMined()) minecount--; mineguess--; break; case Mine::Empty: --nonminecount; break; default: break; } } } - for ( int x = 0; x < numCols; x++ ) { + for ( x = 0; x < numCols; x++ ) { for ( int y = 0; y < numRows; y++ ) { Mine* m = mine( y, x ); if ( m->state() == Mine::Empty ) m->setHint(getHint(y,x)); } } } setState( Playing ); emit mineCount( mineguess ); } +QSize MineField::sizeHint() const +{ + if ( qApp->desktop()->width() >= 240 ) + return QSize(200,200); + else + return QSize(160, 160); +} + diff --git a/noncore/games/minesweep/minefield.h b/noncore/games/minesweep/minefield.h index 1349c35..e243d77 100644 --- a/noncore/games/minesweep/minefield.h +++ b/noncore/games/minesweep/minefield.h @@ -1,101 +1,104 @@ /********************************************************************** -** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** -** This file is part of Qtopia Environment. +** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #ifndef MINEFIELD_H #define MINEFIELD_H #include <qscrollview.h> class Mine; class Config; class MineField : public QScrollView { Q_OBJECT public: MineField( QWidget* parent = 0, const char* name = 0 ); ~MineField(); enum State { Waiting, Playing, GameOver }; State state() const { return stat; } void readConfig(Config&); void writeConfig(Config&) const; int level() const { return lev; } void setAvailableRect( const QRect & ); + + QSize sizeHint() const; + public slots: void setup( int level ); void showMines(); signals: void gameOver( bool won ); void gameStarted(); void mineCount( int ); protected: void contentsMousePressEvent( QMouseEvent* ); void contentsMouseReleaseEvent( QMouseEvent* ); void keyPressEvent( QKeyEvent* ); void keyReleaseEvent( QKeyEvent* ); void drawContents( QPainter * p, int clipx, int clipy, int clipw, int cliph ); int getHint( int row, int col ); void setHint( int r, int c ); void updateMine( int row, int col ); void paletteChange( const QPalette & ); void updateCell( int r, int c ); bool onBoard( int r, int c ) const { return r >= 0 && r < numRows && c >= 0 && c < numCols; } Mine *mine( int row, int col ) { return onBoard(row, col ) ? mines[row+numCols*col] : 0; } const Mine *mine( int row, int col ) const { return onBoard(row, col ) ? mines[row+numCols*col] : 0; } protected slots: void cellPressed( int row, int col ); void cellClicked( int row, int col ); void held(); private: int findCellSize(); void setCellSize( int ); State stat; void MineField::setState( State st ); void MineField::placeMines(); enum FlagAction { NoAction, FlagOn, FlagNext }; FlagAction flagAction; bool ignoreClick; int currRow; int currCol; int numRows, numCols; int minecount; int mineguess; int nonminecount; int lev; QRect availableRect; int cellSize; QTimer *holdTimer; Mine **mines; }; #endif // MINEFIELD_H diff --git a/noncore/games/minesweep/minesweep.cpp b/noncore/games/minesweep/minesweep.cpp index 7214a73..d707dab 100644 --- a/noncore/games/minesweep/minesweep.cpp +++ b/noncore/games/minesweep/minesweep.cpp @@ -1,407 +1,413 @@ /********************************************************************** -** Copyright (C) 2000 Trolltech AS. All rights reserved. +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** -** This file is part of Qtopia Environment. +** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "minesweep.h" #include "minefield.h" -#include <qpe/qpeapplication.h> -#include <qpe/resource.h> -#include <qpe/config.h> +#include <qtopia/qpeapplication.h> +#include <qtopia/resource.h> +#include <qtopia/config.h> -#include <qpe/qpetoolbar.h> +#include <qtoolbar.h> #include <qmenubar.h> #include <qpopupmenu.h> #include <qpushbutton.h> #include <qlcdnumber.h> #include <qmessagebox.h> #include <qtimer.h> #include <qpalette.h> #include <qapplication.h> #include <qlayout.h> #include <qlabel.h> #include <stdlib.h> #include <time.h> static const char *pix_new[]={ "20 20 3 1", " c None", "# c #00FF00", ". c #000000", " ", " ...... ", " ..######.. ", " .##########. ", " .############. ", " .##############. ", " .##############. ", " .################. ", " .################. ", " .################. ", " .################. ", " .################. ", " .################. ", " .##############. ", " .##############. ", " .############. ", " .##########. ", " ..######.. ", " ...... ", " "}; /* XPM */ static const char * happy_xpm[] = { "20 20 3 1", " c None", ". c #ffff3f ", "# c #000000", " ", " ###### ", " ##......## ", " #..........# ", " #............# ", " #..............# ", " #..............# ", " #....##....##....# ", " #....##....##....# ", " #................# ", " #................# ", " #................# ", " #...#........#...# ", " #.##........##.# ", " #...########...# ", " #...######...# ", " #..........# ", " ##......## ", " ###### ", " "}; /* XPM */ static const char * worried_xpm[] = { "20 20 3 1", " c None", ". c #ffff3f", "# c #000000", " ", " ###### ", " ##......## ", " #..........# ", " #............# ", " #..............# ", " #..............# ", " #....##....##....# ", " #....##....##....# ", " #................# ", " #................# ", " #................# ", " #................# ", " #....######....# ", " #..............# ", " #............# ", " #..........# ", " ##......## ", " ###### ", " "}; /* XPM */ static const char * dead_xpm[] = { "20 20 3 1", " c None", ". c #ffff3f", "# c #000000", " ", " ###### ", " ##......## ", " #..........# ", " #............# ", " #..............# ", " #..#.#...#.#...# ", " #....#.....#.....# ", " #...#.#...#.#....# ", " #................# ", " #................# ", " #................# ", " #......####......# ", " #....# #....# ", " #...#......#...# ", " #............# ", " #..........# ", " ##......## ", " ###### ", " "}; class ResultIndicator : private QLabel { public: static void showResult( QWidget *ref, bool won ); private: ResultIndicator( QWidget *parent, const char *name, WFlags f) :QLabel( parent, name, f ) {} void timerEvent( QTimerEvent *); void center(); bool twoStage; int timerId; }; void ResultIndicator::showResult( QWidget *ref, bool won ) { ResultIndicator *r = new ResultIndicator( ref, 0, WStyle_Customize | WStyle_Tool | WType_TopLevel ); r->setAlignment( AlignCenter ); r->setFrameStyle( Sunken|StyledPanel ); if ( won ) { r->setText( MineSweep::tr("You won!") ); r->center(); r->show(); r->twoStage = FALSE; r->timerId = r->startTimer(1500); } else { QPalette p( red ); r->setPalette( p ); r->setText( MineSweep::tr("You exploded!") ); r->resize( ref->size() ); r->move( ref->mapToGlobal(QPoint(0,0)) ); r->show(); r->twoStage = TRUE; r->timerId =r->startTimer(200); } } void ResultIndicator::center() { QWidget *w = parentWidget(); QPoint pp = w->mapToGlobal( QPoint(0,0) ); QSize s = sizeHint()*3; + s.setWidth( QMIN(s.width(), w->width()) ); pp = QPoint( pp.x() + w->width()/2 - s.width()/2, pp.y() + w->height()/ 2 - s.height()/2 ); setGeometry( QRect(pp, s) ); } void ResultIndicator::timerEvent( QTimerEvent *te ) { if ( te->timerId() != timerId ) return; killTimer( timerId ); if ( twoStage ) { center(); twoStage = FALSE; timerId = startTimer( 1000 ); } else { delete this; } } class MineFrame : public QFrame { public: MineFrame( QWidget *parent, const char *name = 0 ) - :QFrame( parent, name ) {} - void setField( MineField *f ) { field = f; } + :QFrame( parent, name ), field(0) {} + void setField( MineField *f ) { + field = f; + setMinimumSize( field->sizeHint() ); + } protected: void resizeEvent( QResizeEvent *e ) { field->setAvailableRect( contentsRect()); QFrame::resizeEvent(e); } private: MineField *field; }; MineSweep::MineSweep( QWidget* parent, const char* name, WFlags f ) : QMainWindow( parent, name, f ) { - QPEApplication::setInputMethodHint(this, QPEApplication::AlwaysOff ); srand(::time(0)); setCaption( tr("Mine Hunt") ); - setIcon( Resource::loadPixmap( "minesweep_icon" ) ); + QPEApplication::setInputMethodHint(this, QPEApplication::AlwaysOff ); + setIcon( Resource::loadPixmap( "minesweep/MineHunt" ) ); QToolBar *toolBar = new QToolBar( this ); toolBar->setHorizontalStretchable( TRUE ); QMenuBar *menuBar = new QMenuBar( toolBar ); QPopupMenu *gameMenu = new QPopupMenu( this ); gameMenu->insertItem( tr("Beginner"), this, SLOT( beginner() ) ); gameMenu->insertItem( tr("Advanced"), this, SLOT( advanced() ) ); - gameMenu->insertItem( tr("Expert"), this, SLOT( expert() ) ); + + if (qApp->desktop()->width() >= 240) { + gameMenu->insertItem( tr("Expert"), this, SLOT( expert() ) ); + } menuBar->insertItem( tr("Game"), gameMenu ); guessLCD = new QLCDNumber( toolBar ); toolBar->setStretchableWidget( guessLCD ); QPalette lcdPal( red ); lcdPal.setColor( QColorGroup::Background, QApplication::palette().active().background() ); lcdPal.setColor( QColorGroup::Button, QApplication::palette().active().button() ); // guessLCD->setPalette( lcdPal ); guessLCD->setSegmentStyle( QLCDNumber::Flat ); guessLCD->setFrameStyle( QFrame::NoFrame ); guessLCD->setNumDigits( 2 ); guessLCD->setBackgroundMode( PaletteButton ); newGameButton = new QPushButton( toolBar ); newGameButton->setPixmap( QPixmap( pix_new ) ); newGameButton->setFocusPolicy(QWidget::NoFocus); connect( newGameButton, SIGNAL(clicked()), this, SLOT(newGame()) ); timeLCD = new QLCDNumber( toolBar ); // timeLCD->setPalette( lcdPal ); timeLCD->setSegmentStyle( QLCDNumber::Flat ); timeLCD->setFrameStyle( QFrame::NoFrame ); timeLCD->setNumDigits( 5 ); // "mm:ss" timeLCD->setBackgroundMode( PaletteButton ); setToolBarsMovable ( FALSE ); addToolBar( toolBar ); MineFrame *mainframe = new MineFrame( this ); mainframe->setFrameShape( QFrame::Box ); mainframe->setFrameShadow( QFrame::Raised ); mainframe->setLineWidth(2); field = new MineField( mainframe ); mainframe->setField( field ); QFont fnt = field->font(); fnt.setBold( TRUE ); field->setFont( QFont( fnt ) ); field->setFocus(); setCentralWidget( mainframe ); - connect( field, SIGNAL( gameOver( bool ) ), this, SLOT( gameOver( bool ) ) ); - connect( field, SIGNAL( mineCount( int ) ), this, SLOT( setCounter( int ) ) ); + connect( field, SIGNAL( gameOver(bool) ), this, SLOT( gameOver(bool) ) ); + connect( field, SIGNAL( mineCount(int) ), this, SLOT( setCounter(int) ) ); connect( field, SIGNAL( gameStarted()), this, SLOT( startPlaying() ) ); timer = new QTimer( this ); - connect( timer, SIGNAL( timeout() ), this, SLOT( updateTime() ) ); readConfig(); } MineSweep::~MineSweep() { writeConfig(); } void MineSweep::gameOver( bool won ) { field->showMines(); if ( won ) { newGameButton->setPixmap( QPixmap( happy_xpm ) ); } else { newGameButton->setPixmap( QPixmap( dead_xpm ) ); } ResultIndicator::showResult( this, won ); timer->stop(); } void MineSweep::newGame() { newGame(field->level()); } void MineSweep::newGame(int level) { timeLCD->display( "0:00" ); field->setup( level ); newGameButton->setPixmap( QPixmap( pix_new ) ); timer->stop(); } void MineSweep::startPlaying() { newGameButton->setPixmap( QPixmap( worried_xpm ) ); starttime = QDateTime::currentDateTime(); timer->start( 1000 ); } void MineSweep::beginner() { newGame(1); } void MineSweep::advanced() { newGame(2); } void MineSweep::expert() { newGame(3); } void MineSweep::setCounter( int c ) { if ( !guessLCD ) return; guessLCD->display( c ); } void MineSweep::updateTime() { if ( !timeLCD ) return; int s = starttime.secsTo(QDateTime::currentDateTime()); if ( s/60 > 99 ) timeLCD->display( "-----" ); else timeLCD->display( QString().sprintf("%2d:%02d",s/60,s%60) ); } void MineSweep::writeConfig() const { Config cfg("MineSweep"); cfg.setGroup("Panel"); cfg.writeEntry("Time", timer->isActive() ? starttime.secsTo(QDateTime::currentDateTime()) : -1); field->writeConfig(cfg); } void MineSweep::readConfig() { Config cfg("MineSweep"); field->readConfig(cfg); cfg.setGroup("Panel"); int s = cfg.readNumEntry("Time",-1); if ( s<0 ) { newGame(); } else { startPlaying(); starttime = QDateTime::currentDateTime().addSecs(-s); updateTime(); } } |