Update copyright headers
[qt:qt.git] / demos / declarative / minehunt / minehunt.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the demonstration applications of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
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 }