summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/games/minesweep/minefield.cpp104
-rw-r--r--noncore/games/minesweep/minefield.h7
-rw-r--r--noncore/games/minesweep/minesweep.cpp28
3 files changed, 87 insertions, 52 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++ )
- {
+ 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;
- }
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];
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 )
{
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;
+ 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 );
- int b = 5;
+ if ( availableRect.height() < h2 &&
+ availableRect.width() - w > style().scrollBarExtent().width() ) {
+ w += style().scrollBarExtent().width();
+ }
- setGeometry( availableRect.x() + (w-w2)/2, availableRect.y() + (h-h2)/2,
- w2+b, h2+b );
-// QMIN(w,w2+b), QMIN(h,h2+b) );
+ 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 ) {
+ 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() ) );
+
+ 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( 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();
}
}