Qt Reference Documentation

# minehunt.cpp Example File

demos/declarative/minehunt/minehunt.cpp

     /****************************************************************************
     **
     ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
     ** All rights reserved.
     ** Contact: Nokia Corporation (qt-info@nokia.com)
     **
     ** This file is part of the demonstration applications of the Qt Toolkit.
     **
     ** $QT_BEGIN_LICENSE:LGPL$
     ** GNU Lesser General Public License Usage
     ** This file may be used under the terms of the GNU Lesser General Public
     ** License version 2.1 as published by the Free Software Foundation and
     ** appearing in the file LICENSE.LGPL included in the packaging of this
     ** file. Please review the following information to ensure the GNU Lesser
     ** General Public License version 2.1 requirements will be met:
     ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
     **
     ** In addition, as a special exception, Nokia gives you certain additional
     ** rights. These rights are described in the Nokia Qt LGPL Exception
     ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
     **
     ** GNU General Public License Usage
     ** Alternatively, this file may be used under the terms of the GNU General
     ** Public License version 3.0 as published by the Free Software Foundation
     ** and appearing in the file LICENSE.GPL included in the packaging of this
     ** file. Please review the following information to ensure the GNU General
     ** Public License version 3.0 requirements will be met:
     ** http://www.gnu.org/copyleft/gpl.html.
     **
     ** Other Usage
     ** Alternatively, this file may be used in accordance with the terms and
     ** conditions contained in a signed written agreement between you and Nokia.
     **
     **
     **
     **
     **
     ** $QT_END_LICENSE$
     **
     ****************************************************************************/

     #include <stdlib.h>
     #include <QTime>
     #include <QTimer>

     #include "minehunt.h"

     void tilesPropAppend(QDeclarativeListProperty<TileData>* prop, TileData* value)
     {
         Q_UNUSED(prop);
         Q_UNUSED(value);
         return; //Append not supported
     }

     int tilesPropCount(QDeclarativeListProperty<TileData>* prop)
     {
         return static_cast<QList<TileData*>*>(prop->data)->count();
     }

     TileData* tilesPropAt(QDeclarativeListProperty<TileData>* prop, int index)
     {
         return static_cast<QList<TileData*>*>(prop->data)->at(index);
     }

     QDeclarativeListProperty<TileData> MinehuntGame::tiles(){
         return QDeclarativeListProperty<TileData>(this, &_tiles, &tilesPropAppend,
                 &tilesPropCount, &tilesPropAt, 0);
     }

     MinehuntGame::MinehuntGame()
     : numCols(9), numRows(9), playing(true), won(false)
     {
         setObjectName("mainObject");
         srand(QTime(0,0,0).secsTo(QTime::currentTime()));

         //initialize array
         for(int ii = 0; ii < numRows * numCols; ++ii) {
             _tiles << new TileData;
         }
         reset();

     }

     void MinehuntGame::setBoard()
     {
         foreach(TileData* t, _tiles){
             t->setHasMine(false);
             t->setHint(-1);
         }
         //place mines
         int mines = nMines;
         remaining = numRows*numCols-mines;
         while ( mines ) {
             int col = int((double(rand()) / double(RAND_MAX)) * numCols);
             int row = int((double(rand()) / double(RAND_MAX)) * numRows);

             TileData* t = tile( row, col );

             if (t && !t->hasMine()) {
                 t->setHasMine( true );
                 mines--;
             }
         }

         //set hints
         for (int r = 0; r < numRows; r++)
             for (int c = 0; c < numCols; c++) {
                 TileData* t = tile(r, c);
                 if (t && !t->hasMine()) {
                     int hint = getHint(r,c);
                     t->setHint(hint);
                 }
             }

         setPlaying(true);
     }

     void MinehuntGame::reset()
     {
         foreach(TileData* t, _tiles){
             t->unflip();
             t->setHasFlag(false);
         }
         nMines = 12;
         nFlags = 0;
         emit numMinesChanged();
         emit numFlagsChanged();
         setPlaying(false);
         QTimer::singleShot(600,this, SLOT(setBoard()));
     }

     int MinehuntGame::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++) {
                 TileData* t = tile(r, c);
                 if (t && t->hasMine())
                     hint++;
             }
         return hint;
     }

     bool MinehuntGame::flip(int row, int col)
     {
         if(!playing)
             return false;

         TileData *t = tile(row, col);
         if (!t || t->hasFlag())
             return false;

         if(t->flipped()){
             int flags = 0;
             for (int c = col-1; c <= col+1; c++)
                 for (int r = row-1; r <= row+1; r++) {
                     TileData *nearT = tile(r, c);
                     if(!nearT || nearT == t)
                         continue;
                     if(nearT->hasFlag())
                         flags++;
                 }
             if(!t->hint() || t->hint() != flags)
                 return false;
             for (int c = col-1; c <= col+1; c++)
                 for (int r = row-1; r <= row+1; r++) {
                     TileData *nearT = tile(r, c);
                     if (nearT && !nearT->flipped() && !nearT->hasFlag()) {
                         flip( r, c );
                     }
                 }
             return true;
         }

         t->flip();

         if (t->hint() == 0) {
             for (int c = col-1; c <= col+1; c++)
                 for (int r = row-1; r <= row+1; r++) {
                     TileData* t = tile(r, c);
                     if (t && !t->flipped()) {
                         flip( r, c );
                     }
                 }
         }

         if(t->hasMine()){
             for (int r = 0; r < numRows; r++)//Flip all other mines
                 for (int c = 0; c < numCols; c++) {
                     TileData* t = tile(r, c);
                     if (t && t->hasMine()) {
                         flip(r, c);
                     }
                 }
             won = false;
             hasWonChanged();
             setPlaying(false);
             return true;
         }

         remaining--;
         if(!remaining){
             won = true;
             hasWonChanged();
             setPlaying(false);
             return true;
         }
         return true;
     }

     bool MinehuntGame::flag(int row, int col)
     {
         TileData *t = tile(row, col);
         if(!t || !playing || t->flipped())
             return false;

         t->setHasFlag(!t->hasFlag());
         nFlags += (t->hasFlag()?1:-1);
         emit numFlagsChanged();
         return true;
     }