author | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
---|---|---|
committer | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
commit | 15318cad33835e4e2dc620d033e43cd930676cdd (patch) (side-by-side diff) | |
tree | c2fa0399a2c47fda8e2cd0092c73a809d17f68eb /noncore/games/minesweep | |
download | opie-15318cad33835e4e2dc620d033e43cd930676cdd.zip opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2 |
Initial revision
-rw-r--r-- | noncore/games/minesweep/.cvsignore | 2 | ||||
-rw-r--r-- | noncore/games/minesweep/Makefile.in | 134 | ||||
-rw-r--r-- | noncore/games/minesweep/main.cpp | 34 | ||||
-rw-r--r-- | noncore/games/minesweep/minefield.cpp | 623 | ||||
-rw-r--r-- | noncore/games/minesweep/minefield.h | 87 | ||||
-rw-r--r-- | noncore/games/minesweep/minesweep.cpp | 390 | ||||
-rw-r--r-- | noncore/games/minesweep/minesweep.h | 67 | ||||
-rw-r--r-- | noncore/games/minesweep/minesweep.pro | 14 | ||||
-rw-r--r-- | noncore/games/minesweep/qpe-minesweep.control | 9 |
9 files changed, 1360 insertions, 0 deletions
diff --git a/noncore/games/minesweep/.cvsignore b/noncore/games/minesweep/.cvsignore new file mode 100644 index 0000000..6fe2396 --- a/dev/null +++ b/noncore/games/minesweep/.cvsignore @@ -0,0 +1,2 @@ +moc_* +Makefile diff --git a/noncore/games/minesweep/Makefile.in b/noncore/games/minesweep/Makefile.in new file mode 100644 index 0000000..9ed6234 --- a/dev/null +++ b/noncore/games/minesweep/Makefile.in @@ -0,0 +1,134 @@ +############################################################################# + +####### Compiler, tools and options + +CXX = $(SYSCONF_CXX) $(QT_CXX_MT) +CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) +CC = $(SYSCONF_CC) $(QT_C_MT) +CFLAGS = $(SYSCONF_CFLAGS) +INCPATH = -I$(QPEDIR)/include +LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT) +LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP) +MOC = $(SYSCONF_MOC) +UIC = $(SYSCONF_UIC) + +####### Target + +DESTDIR = $(QPEDIR)/bin/ +VER_MAJ = 1 +VER_MIN = 0 +VER_PATCH = 0 +TARGET = minesweep +TARGET1 = lib$(TARGET).so.$(VER_MAJ) + +####### Files + +HEADERS = minefield.h \ + minesweep.h +SOURCES = main.cpp \ + minefield.cpp \ + minesweep.cpp +OBJECTS = main.o \ + minefield.o \ + minesweep.o +INTERFACES = +UICDECLS = +UICIMPLS = +SRCMOC = moc_minefield.cpp \ + moc_minesweep.cpp +OBJMOC = moc_minefield.o \ + moc_minesweep.o + + +####### Implicit rules + +.SUFFIXES: .cpp .cxx .cc .C .c + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + + +all: $(DESTDIR)$(TARGET) + +$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) + $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) + +moc: $(SRCMOC) + +tmake: + tmake minesweep.pro + +clean: + -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) + -rm -f *~ core + -rm -f allmoc.cpp + +####### Extension Modules + +listpromodules: + @echo + +listallmodules: + @echo + +listaddonpromodules: + @echo + +listaddonentmodules: + @echo + + +REQUIRES= + +####### Sub-libraries + + +###### Combined headers + + + +####### Compile + +main.o: main.cpp \ + minesweep.h \ + $(QPEDIR)/include/qpe/qpeapplication.h + +minefield.o: minefield.cpp \ + minefield.h \ + $(QPEDIR)/include/qpe/config.h + +minesweep.o: minesweep.cpp \ + minesweep.h \ + minefield.h \ + $(QPEDIR)/include/qpe/resource.h \ + $(QPEDIR)/include/qpe/config.h \ + $(QPEDIR)/include/qpe/qpetoolbar.h \ + $(QPEDIR)/include/qpe/qpemenubar.h + +moc_minefield.o: moc_minefield.cpp \ + minefield.h + +moc_minesweep.o: moc_minesweep.cpp \ + minesweep.h + +moc_minefield.cpp: minefield.h + $(MOC) minefield.h -o moc_minefield.cpp + +moc_minesweep.cpp: minesweep.h + $(MOC) minesweep.h -o moc_minesweep.cpp + + diff --git a/noncore/games/minesweep/main.cpp b/noncore/games/minesweep/main.cpp new file mode 100644 index 0000000..83de9a3 --- a/dev/null +++ b/noncore/games/minesweep/main.cpp @@ -0,0 +1,34 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of 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 <qpe/qpeapplication.h> + +int main( int argc, char** argv ) +{ + QPEApplication a( argc, argv ); + + MineSweep ms; + QPEApplication::setInputMethodHint( &ms, QPEApplication::AlwaysOff ); + a.showMainWidget( &ms ); + + return a.exec(); +} diff --git a/noncore/games/minesweep/minefield.cpp b/noncore/games/minesweep/minefield.cpp new file mode 100644 index 0000000..be2f9a3 --- a/dev/null +++ b/noncore/games/minesweep/minefield.cpp @@ -0,0 +1,623 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of 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 <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#####..", +"#############", +"..#########..", +"..#########..", +"...#######...", +"..#.#####.#..", +"......#......", +"......#......"}; + +class Mine : public QTableItem +{ +public: + enum MineState { + Hidden = 0, + Empty, + Mined, + Flagged, +#ifdef MARK_UNSURE + Unsure, +#endif + Exploded, + Wrong + }; + + Mine( QTable* ); + void paint( QPainter * p, const QColorGroup & cg, const QRect & cr, bool selected ); + EditType editType() const { return Never; } + QSize sizeHint() const { return QSize( 12, 12 ); } + + 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; + + 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( QTable *t ) +: QTableItem( t, Never, QString::null ) +{ + mined = FALSE; + st = Hidden; + hint = 0; +} + +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, bool ) +{ + if ( !knownField ) { + knownField = new QPixmap( cr.width(), cr.height() ); + QPainter pp( knownField ); + QBrush br( cg.button().dark(115) ); + qDrawWinButton( &pp, QRect(0,0,cr.width(), cr.height())/*cr*/, cg, TRUE, &br ); + } + + const int pmmarg=cr.width()/5; + + if ( !unknownField ) { + unknownField = new QPixmap( cr.width(), cr.height() ); + QPainter pp( unknownField ); + QBrush br( cg.button() ); + qDrawWinButton( &pp, QRect(0,0,cr.width(), cr.height())/*cr*/, cg, FALSE, &br ); + } + + if ( !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 ) { + 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( 0, 0, *unknownField ); + break; + case Empty: + p->drawPixmap( 0, 0, *knownField ); + if ( hint > 0 ) { + switch( hint ) { + case 1: + p->setPen( blue ); + break; + case 2: + p->setPen( green ); + case 3: + p->setPen( red ); + break; + default: + p->setPen( darkMagenta ); + break; + } + p->drawText( QRect( 0, 0, cr.width(), cr.height() ), AlignHCenter | AlignVCenter, QString().setNum( hint ) ); + } + break; + case Mined: + p->drawPixmap( 0, 0, *knownField ); + p->drawPixmap( pmmarg, pmmarg, *mine_pix ); + break; + case Exploded: + p->drawPixmap( 0, 0, *knownField ); + p->drawPixmap( pmmarg, pmmarg, *mine_pix ); + p->setPen( red ); + p->drawText( QRect( 0, 0, cr.width(), cr.height() ), AlignHCenter | AlignVCenter, "X" ); + break; + case Flagged: + p->drawPixmap( 0, 0, *unknownField ); + p->drawPixmap( pmmarg, pmmarg, *flag_pix ); + break; +#ifdef MARK_UNSURE + case Unsure: + p->drawPixmap( 0, 0, *unknownField ); + p->drawText( QRect( 0, 0, cr.width(), cr.height() ), AlignHCenter | AlignVCenter, "?" ); + break; +#endif + case Wrong: + p->drawPixmap( 0, 0, *unknownField ); + p->drawPixmap( pmmarg, pmmarg, *flag_pix ); + p->setPen( red ); + p->drawText( QRect( 0, 0, cr.width(), cr.height() ), AlignHCenter | AlignVCenter, "X" ); + break; + } + + p->restore(); +} + +/* + MineField implementation +*/ + +MineField::MineField( QWidget* parent, const char* name ) +: QTable( parent, name ) +{ + setState( GameOver ); + setShowGrid( FALSE ); + horizontalHeader()->hide(); + verticalHeader()->hide(); + setTopMargin( 0 ); + setLeftMargin( 0 ); + + setSizePolicy( QSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum ) ); + + setSelectionMode( QTable::NoSelection ); + setFocusPolicy( QWidget::NoFocus ); + + setCurrentCell( -1, -1 ); + + connect( this, SIGNAL( pressed( int, int, int, const QPoint& ) ), this, SLOT( cellPressed( int, int ) ) ); + connect( this, SIGNAL( clicked( int, int, int, const QPoint& ) ), this, SLOT( cellClicked( int, int ) ) ); + + holdTimer = new QTimer( this ); + connect( holdTimer, SIGNAL( timeout() ), this, SLOT( held() ) ); + + flagAction = NoAction; + ignoreClick = FALSE; + currRow = currCol = 0; + minecount=0; + mineguess=0; + nonminecount=0; +} + +MineField::~MineField() +{ +} + +void MineField::setState( State st ) +{ + stat = st; +} + + +void MineField::setup( int level ) +{ + lev = level; + setState( Waiting ); + viewport()->setUpdatesEnabled( FALSE ); + + int cellsize; + + int x; + int y; + for ( x = 0; x < numCols(); x++ ) + for ( y = 0; y < numRows(); y++ ) + clearCell( y, x ); + + switch( lev ) { + case 1: + setNumRows( 9 ); + setNumCols( 9 ); + minecount = 12; + cellsize = 21; + break; + case 2: + setNumRows( 16 ); + setNumCols( 16 ); + minecount = 45; + cellsize = 14; + break; + case 3: + setNumRows( 18 ); + setNumCols( 18 ); + minecount = 66 ; + cellsize = 12; + break; + } + nonminecount = numRows()*numCols() - minecount; + mineguess = minecount; + emit mineCount( mineguess ); + Mine::paletteChange(); + + for ( y = 0; y < numRows(); y++ ) + setRowHeight( y, cellsize ); + for ( x = 0; x < numCols(); x++ ) + setColumnWidth( x, cellsize ); + for ( x = 0; x < numCols(); x++ ) + for ( y = 0; y < numRows(); y++ ) + setItem( y, x, new Mine( this ) ); + + updateGeometry(); + viewport()->setUpdatesEnabled( TRUE ); + viewport()->repaint( TRUE ); +} + + +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* mine = (Mine*)item( row, col ); + + if ( mine && !mine->isMined() && mine->state() == Mine::Hidden ) { + mine->setMined( TRUE ); + mines--; + } + } +} + +void MineField::paintFocus( QPainter*, const QRect& ) +{ +} + +void MineField::viewportMousePressEvent( QMouseEvent* e ) +{ + QTable::viewportMousePressEvent( e ); +} + +void MineField::viewportMouseReleaseEvent( QMouseEvent* e ) +{ + QTable::viewportMouseReleaseEvent( e ); + if ( flagAction == FlagNext ) { + flagAction = NoAction; + } +} + +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* mine = (Mine*)item( r, c ); + if ( mine && mine->isMined() ) + hint++; + } + + return hint; +} + +void MineField::setHint( Mine* mine ) +{ + if ( !mine ) + return; + + int row = mine->row(); + int col = mine->col(); + 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* mine = (Mine*)item( r, c ); + if ( mine && mine->state() == Mine::Hidden ) { + mine->activate( TRUE ); + nonminecount--; + setHint( mine ); + updateCell( r, c ); + } + } + } + + mine->setHint( hint ); + updateCell( row, col ); +} + +/* + 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; +} + +/* + 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* mine = (Mine*)item( row, col ); + if ( !mine ) + return; + mine->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* mine = (Mine*)item( row, col ); + if ( !mine ) + return; + + bool wasFlagged = mine->state() == Mine::Flagged; + bool wasEmpty = mine->state() == Mine::Empty; + + mine->activate( flagAction == NoAction ); + + if ( mine->state() == Mine::Exploded ) { + emit gameOver( FALSE ); + setState( GameOver ); + return; + } else if ( mine->state() == Mine::Empty ) { + setHint( mine ); + if ( !wasEmpty ) + nonminecount--; + } + + if ( flagAction != NoAction ) { + if ( mine->state() == Mine::Flagged ) { + --mineguess; + emit mineCount( mineguess ); + if ( mine->isMined() ) + --minecount; + } else if ( wasFlagged ) { + ++mineguess; + emit mineCount( mineguess ); + if ( mine->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* mine = (Mine*)item( r, c ); + if ( !mine ) + continue; + if ( mine->isMined() && mine->state() == Mine::Hidden ) + mine->setState( Mine::Mined ); + if ( !mine->isMined() && mine->state() == Mine::Flagged ) + mine->setState( Mine::Wrong ); + + updateCell( r, c ); + } +} + +void MineField::paletteChange( const QPalette &o ) +{ + Mine::paletteChange(); + QTable::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 + Mine* mine = (Mine*)item( y, x ); + int st = (int)mine->state(); if ( mine->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"); + if ( !grid.isEmpty() ) { + int i=0; + minecount=0; + mineguess=0; + 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 + int st = (char)(QChar)grid[i++]-code; + Mine* mine = (Mine*)item( y, x ); + if ( st >= 5 ) { + st-=5; + mine->setMined(TRUE); + minecount++; + mineguess++; + } + mine->setState((Mine::MineState)st); + switch ( mine->state() ) { + case Mine::Flagged: + if (mine->isMined()) + minecount--; + mineguess--; + break; + case Mine::Empty: + --nonminecount; + } + } + } + for ( int x = 0; x < numCols(); x++ ) { + for ( int y = 0; y < numRows(); y++ ) { + Mine* mine = (Mine*)item( y, x ); + if ( mine->state() == Mine::Empty ) + mine->setHint(getHint(y,x)); + } + } + } + setState( Playing ); + emit mineCount( mineguess ); +} + diff --git a/noncore/games/minesweep/minefield.h b/noncore/games/minesweep/minefield.h new file mode 100644 index 0000000..4ede435 --- a/dev/null +++ b/noncore/games/minesweep/minefield.h @@ -0,0 +1,87 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of 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 <qtable.h> + +class Mine; +class Config; + +class MineField : public QTable +{ + 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; } + +public slots: + void setup( int level ); + + void showMines(); + +signals: + void gameOver( bool won ); + void gameStarted(); + void mineCount( int ); + +protected: + void paintFocus( QPainter*, const QRect& ); + void viewportMousePressEvent( QMouseEvent* ); + void viewportMouseReleaseEvent( QMouseEvent* ); + void keyPressEvent( QKeyEvent* ); + void keyReleaseEvent( QKeyEvent* ); + + int getHint( int row, int col ); + void setHint( Mine* ); + void updateMine( int row, int col ); + void paletteChange( const QPalette & ); + +protected slots: + void cellPressed( int row, int col ); + void cellClicked( int row, int col ); + void held(); + +private: + State stat; + void MineField::setState( State st ); + void MineField::placeMines(); + enum FlagAction { NoAction, FlagOn, FlagNext }; + FlagAction flagAction; + bool ignoreClick; + int currRow; + int currCol; + int minecount; + int mineguess; + int nonminecount; + int lev; + QTimer *holdTimer; +}; + +#endif // MINEFIELD_H diff --git a/noncore/games/minesweep/minesweep.cpp b/noncore/games/minesweep/minesweep.cpp new file mode 100644 index 0000000..6492462 --- a/dev/null +++ b/noncore/games/minesweep/minesweep.cpp @@ -0,0 +1,390 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of 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/resource.h> +#include <qpe/config.h> + +#include <qpe/qpetoolbar.h> +#include <qpe/qpemenubar.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; + 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; + } +} + + +MineSweep::MineSweep( QWidget* parent, const char* name, WFlags f ) +: QMainWindow( parent, name, f ) +{ + srand(::time(0)); + setCaption( tr("Mine Hunt") ); + setIcon( Resource::loadPixmap( "minesweep_icon" ) ); + + QPEToolBar *menuToolBar = new QPEToolBar( this ); + QPEMenuBar *menuBar = new QPEMenuBar( menuToolBar ); + + 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() ) ); + + menuBar->insertItem( tr("Game"), gameMenu ); + + QPEToolBar *toolBar = new QPEToolBar( this ); + toolBar->setHorizontalStretchable( TRUE ); + + 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( menuToolBar ); + addToolBar( toolBar ); + + QFrame *mainframe = new QFrame( this ); + mainframe->setFrameShape( QFrame::Box ); + mainframe->setFrameShadow( QFrame::Raised ); + mainframe->setMargin(5); + mainframe->setLineWidth(2); + QBoxLayout *box = new QVBoxLayout( mainframe ); + field = new MineField( mainframe ); + box->addWidget( field, 0, AlignCenter ); + 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(); + } +} diff --git a/noncore/games/minesweep/minesweep.h b/noncore/games/minesweep/minesweep.h new file mode 100644 index 0000000..e860573 --- a/dev/null +++ b/noncore/games/minesweep/minesweep.h @@ -0,0 +1,67 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of 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 MINESWEEP_H +#define MINESWEEP_H + +#include <qmainwindow.h> +#include <qdatetime.h> + +class MineField; +class QLCDNumber; +class QPushButton; + +class MineSweep : public QMainWindow +{ + Q_OBJECT +public: + MineSweep( QWidget* parent = 0, const char* name = 0, WFlags f = 0 ); + ~MineSweep(); + +public slots: + void gameOver( bool won ); + void newGame(); + +protected slots: + void setCounter( int ); + void updateTime(); + + void beginner(); + void advanced(); + void expert(); + +private slots: + void startPlaying(); + +private: + void readConfig(); + void writeConfig() const; + + void newGame(int); + MineField* field; + QLCDNumber* guessLCD; + QLCDNumber* timeLCD; + QPushButton* newGameButton; + + QDateTime starttime; + QTimer* timer; +}; + +#endif // MINESWEEP_H + diff --git a/noncore/games/minesweep/minesweep.pro b/noncore/games/minesweep/minesweep.pro new file mode 100644 index 0000000..87484bc --- a/dev/null +++ b/noncore/games/minesweep/minesweep.pro @@ -0,0 +1,14 @@ +TEMPLATE = app +CONFIG = qt warn_on release +DESTDIR = $(QPEDIR)/bin +HEADERS = minefield.h \ + minesweep.h +SOURCES = main.cpp \ + minefield.cpp \ + minesweep.cpp +INCLUDEPATH += $(QPEDIR)/include +DEPENDPATH += $(QPEDIR)/include +LIBS += -lqpe +INTERFACES = + +TRANSLATIONS = ../i18n/de/minesweep.ts diff --git a/noncore/games/minesweep/qpe-minesweep.control b/noncore/games/minesweep/qpe-minesweep.control new file mode 100644 index 0000000..36bc221 --- a/dev/null +++ b/noncore/games/minesweep/qpe-minesweep.control @@ -0,0 +1,9 @@ +Files: bin/minesweep apps/Games/minesweep.desktop +Priority: optional +Section: qpe/games +Maintainer: Warwick Allison <warwick@trolltech.com> +Architecture: arm +Version: $QPE_VERSION-3 +Depends: qpe-base ($QPE_VERSION) +Description: Game: find the mines + A game for the Qtopia environment. |