Initial import from the monolithic Qt.
[profile/ivi/qtdeclarative.git] / demos / declarative / minehunt / minehunt.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the demonstration applications of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <stdlib.h>
43 #include <QTime>
44 #include <QTimer>
45
46 #include "minehunt.h"
47
48 void tilesPropAppend(QDeclarativeListProperty<TileData>* prop, TileData* value)
49 {
50     Q_UNUSED(prop);
51     Q_UNUSED(value);
52     return; //Append not supported
53 }
54
55 int tilesPropCount(QDeclarativeListProperty<TileData>* prop)
56 {
57     return static_cast<QList<TileData*>*>(prop->data)->count();
58 }
59
60 TileData* tilesPropAt(QDeclarativeListProperty<TileData>* prop, int index)
61 {
62     return static_cast<QList<TileData*>*>(prop->data)->at(index);
63 }
64
65 QDeclarativeListProperty<TileData> MinehuntGame::tiles(){
66     return QDeclarativeListProperty<TileData>(this, &_tiles, &tilesPropAppend,
67             &tilesPropCount, &tilesPropAt, 0);
68 }
69
70 MinehuntGame::MinehuntGame()
71 : numCols(9), numRows(9), playing(true), won(false)
72 {
73     setObjectName("mainObject");
74     srand(QTime(0,0,0).secsTo(QTime::currentTime()));
75
76     //initialize array
77     for(int ii = 0; ii < numRows * numCols; ++ii) {
78         _tiles << new TileData;
79     }
80     reset();
81
82 }
83
84 void MinehuntGame::setBoard()
85 {
86     foreach(TileData* t, _tiles){
87         t->setHasMine(false);
88         t->setHint(-1);
89     }
90     //place mines
91     int mines = nMines;
92     remaining = numRows*numCols-mines;
93     while ( mines ) {
94         int col = int((double(rand()) / double(RAND_MAX)) * numCols);
95         int row = int((double(rand()) / double(RAND_MAX)) * numRows);
96
97         TileData* t = tile( row, col );
98
99         if (t && !t->hasMine()) {
100             t->setHasMine( true );
101             mines--;
102         }
103     }
104
105     //set hints
106     for (int r = 0; r < numRows; r++)
107         for (int c = 0; c < numCols; c++) {
108             TileData* t = tile(r, c);
109             if (t && !t->hasMine()) {
110                 int hint = getHint(r,c);
111                 t->setHint(hint);
112             }
113         }
114
115     setPlaying(true);
116 }
117
118 void MinehuntGame::reset()
119 {
120     foreach(TileData* t, _tiles){
121         t->unflip();
122         t->setHasFlag(false);
123     }
124     nMines = 12;
125     nFlags = 0;
126     emit numMinesChanged();
127     emit numFlagsChanged();
128     setPlaying(false);
129     QTimer::singleShot(600,this, SLOT(setBoard()));
130 }
131
132 int MinehuntGame::getHint(int row, int col)
133 {
134     int hint = 0;
135     for (int c = col-1; c <= col+1; c++)
136         for (int r = row-1; r <= row+1; r++) {
137             TileData* t = tile(r, c);
138             if (t && t->hasMine())
139                 hint++;
140         }
141     return hint;
142 }
143
144 bool MinehuntGame::flip(int row, int col)
145 {
146     if(!playing)
147         return false;
148
149     TileData *t = tile(row, col);
150     if (!t || t->hasFlag())
151         return false;
152
153     if(t->flipped()){
154         int flags = 0;
155         for (int c = col-1; c <= col+1; c++)
156             for (int r = row-1; r <= row+1; r++) {
157                 TileData *nearT = tile(r, c);
158                 if(!nearT || nearT == t)
159                     continue;
160                 if(nearT->hasFlag())
161                     flags++;
162             }
163         if(!t->hint() || t->hint() != flags)
164             return false;
165         for (int c = col-1; c <= col+1; c++)
166             for (int r = row-1; r <= row+1; r++) {
167                 TileData *nearT = tile(r, c);
168                 if (nearT && !nearT->flipped() && !nearT->hasFlag()) {
169                     flip( r, c );
170                 }
171             }
172         return true;
173     }
174
175     t->flip();
176
177     if (t->hint() == 0) {
178         for (int c = col-1; c <= col+1; c++)
179             for (int r = row-1; r <= row+1; r++) {
180                 TileData* t = tile(r, c);
181                 if (t && !t->flipped()) {
182                     flip( r, c );
183                 }
184             }
185     }
186
187     if(t->hasMine()){
188         for (int r = 0; r < numRows; r++)//Flip all other mines
189             for (int c = 0; c < numCols; c++) {
190                 TileData* t = tile(r, c);
191                 if (t && t->hasMine()) {
192                     flip(r, c);
193                 }
194             }
195         won = false;
196         hasWonChanged();
197         setPlaying(false);
198         return true;
199     }
200
201     remaining--;
202     if(!remaining){
203         won = true;
204         hasWonChanged();
205         setPlaying(false);
206         return true;
207     }
208     return true;
209 }
210
211 bool MinehuntGame::flag(int row, int col)
212 {
213     TileData *t = tile(row, col);
214     if(!t || !playing || t->flipped())
215         return false;
216
217     t->setHasFlag(!t->hasFlag());
218     nFlags += (t->hasFlag()?1:-1);
219     emit numFlagsChanged();
220     return true;
221 }