📄 minefield.cpp
字号:
/************************************************************************ Copyright (C) 2000-2005 Trolltech AS. All rights reserved.**** This file is part of the Qtopia Environment.** ** This program is free software; you can redistribute it and/or modify it** under the terms of the GNU General Public License as published by the** Free Software Foundation; either version 2 of the License, or (at your** option) any later version.** ** A copy of the GNU GPL license version 2 is included in this package as ** LICENSE.GPL.**** This program is distributed in the hope that it will be useful, but** WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** See the GNU General Public License for more details.**** In addition, as a special exception Trolltech gives permission to link** the code of this program with Qtopia applications copyrighted, developed** and distributed by Trolltech under the terms of the Qtopia Personal Use** License Agreement. You must comply with the GNU General Public License** in all respects for all of the code used other than the applications** licensed under the Qtopia Personal Use License Agreement. If you modify** this file, you may extend this exception to your version of the file,** but you are not obligated to do so. If you do not wish to do so, delete** this exception statement from your version.** ** 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 <qtopia/config.h>#include <qtopia/global.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 = 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; }#ifdef QTOPIA_PHONE bool selected() const { return mSelected; } void setSelected( bool f ) { mSelected = f; }#endif static void paletteChange();private:#ifdef QTOPIA_PHONE bool mSelected;#endif 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 ){#ifdef QTOPIA_PHONE mSelected = FALSE;#endif 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(); QColorGroup scg; scg = cg;#ifdef QTOPIA_PHONE if( selected() && !Global::mousePreferred()) { scg.setBrush( QColorGroup::Base, cg.brush( QColorGroup::Highlight ) ); scg.setBrush( QColorGroup::Button, cg.brush( QColorGroup::Highlight ) ); }#endif const int pmmarg=cr.width()/5;#ifndef QTOPIA_PHONE if ( !unknownField || unknownField->width() != cr.width() || unknownField->height() != cr.height() ) { delete unknownField; unknownField = new QPixmap( cr.width(), cr.height() ); QPainter pp( unknownField ); QBrush br( scg.button() ); qDrawWinButton( &pp, QRect( 0, 0, cr.width(), cr.height() ), scg, FALSE, &br ); pp.flush(); }#else QPainter pixp; if( unknownField ) delete unknownField; unknownField = new QPixmap( cr.width(), cr.height() ); pixp.begin( unknownField ); const QBrush ubr( scg.button() ); qDrawWinButton( &pixp, QRect(0, 0, cr.width(), cr.height()), scg, FALSE, &ubr ); pixp.flush(); pixp.end();#endif#ifndef QTOPIA_PHONE if ( !knownField || knownField->width() != cr.width() || knownField->height() != cr.height() ) { delete knownField; knownField = new QPixmap( cr.width(), cr.height() ); QPainter pp( knownField ); QBrush br( scg.button().dark(115) ); qDrawWinButton( &pp, QRect( 0, 0, cr.width(), cr.height() ), scg, TRUE, &br ); pp.flush(); }#else if( knownField ) delete knownField; knownField = new QPixmap( cr.width(), cr.height() ); pixp.begin( knownField ); const QBrush kbr( scg.button().dark(115) ); qDrawWinButton( &pixp, QRect(0, 0, cr.width(), cr.height()), scg, TRUE, &kbr ); pixp.flush(); pixp.end();#endif if ( !flag_pix || flag_pix->width() != cr.width()-pmmarg*2 || flag_pix->height() != cr.height()-pmmarg*2 ) { if( flag_pix ) 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 || mine_pix->width() != cr.width()-pmmarg*2 || mine_pix->height() != cr.height()-pmmarg*2 ) { if( mine_pix ) 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 ); setFrameStyle(NoFrame); 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; pressed = FALSE; minecount=0; mineguess=0; nonminecount=0; cellSize = -1;#ifdef QTOPIA_PHONE mAlreadyHeld = FALSE;#endif numRows = numCols = 0; mines = NULL;}MineField::~MineField(){ 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 ){#ifdef QTOPIA_PHONE currRow = 0; currCol = 0;#endif lev = level; setState( Waiting ); //viewport()->setUpdatesEnabled( FALSE ); int i; 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 = 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 );#ifdef QTOPIA_PHONE if( mines[0] ) mines[0]->setSelected( TRUE );#endif 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 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -