⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 minefield.cpp

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.7平台上编译为嵌入式图形界面操作系统。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    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 ) {	setCellSize( cellSize );    } else {	viewport()->setUpdatesEnabled( FALSE );	setCellSize( newCellSize );	viewport()->setUpdatesEnabled( TRUE );	viewport()->repaint( TRUE );    }}int MineField::findCellSize(){    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 ){    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);    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 ) {	    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 ( 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 ( 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);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -