Diffstat (limited to 'noncore/games/fifteen/fifteen.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/games/fifteen/fifteen.cpp | 211 |
1 files changed, 162 insertions, 49 deletions
diff --git a/noncore/games/fifteen/fifteen.cpp b/noncore/games/fifteen/fifteen.cpp index 506e87a..f425e06 100644 --- a/noncore/games/fifteen/fifteen.cpp +++ b/noncore/games/fifteen/fifteen.cpp | |||
@@ -1,288 +1,391 @@ | |||
1 | /********************************************************************** | 1 | /********************************************************************** |
2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. | 2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. |
3 | ** | 3 | ** |
4 | ** This file is part of the Qtopia Environment. | 4 | ** This file is part of the Qtopia Environment. |
5 | ** | 5 | ** |
6 | ** This file may be distributed and/or modified under the terms of the | 6 | ** This file may be distributed and/or modified under the terms of the |
7 | ** GNU General Public License version 2 as published by the Free Software | 7 | ** GNU General Public License version 2 as published by the Free Software |
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | 8 | ** Foundation and appearing in the file LICENSE.GPL included in the |
9 | ** packaging of this file. | 9 | ** packaging of this file. |
10 | ** | 10 | ** |
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | 11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
13 | ** | 13 | ** |
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
15 | ** | 15 | ** |
16 | ** Contact info@trolltech.com if any conditions of this licensing are | 16 | ** Contact info@trolltech.com if any conditions of this licensing are |
17 | ** not clear to you. | 17 | ** not clear to you. |
18 | ** | 18 | ** |
19 | **********************************************************************/ | 19 | **********************************************************************/ |
20 | 20 | ||
21 | #include "fifteen.h" | 21 | #include "fifteen.h" |
22 | 22 | ||
23 | #include "fifteenconfigdialog.h" | ||
24 | |||
25 | #include <opie2/ofileselector.h> | ||
26 | |||
23 | #include <qtopia/resource.h> | 27 | #include <qtopia/resource.h> |
24 | #include <qtopia/config.h> | 28 | #include <qtopia/config.h> |
29 | #include <qtopia/qpeapplication.h> | ||
25 | 30 | ||
26 | #include <qvbox.h> | 31 | #include <qvbox.h> |
27 | #include <qaction.h> | 32 | #include <qaction.h> |
28 | #include <qpainter.h> | 33 | #include <qpainter.h> |
29 | #include <qmessagebox.h> | 34 | #include <qmessagebox.h> |
30 | #include <qtoolbar.h> | 35 | #include <qtoolbar.h> |
31 | #include <qmenubar.h> | 36 | #include <qmenubar.h> |
37 | #include <qimage.h> | ||
32 | 38 | ||
33 | #include <stdlib.h> | 39 | #include <stdlib.h> |
34 | #include <time.h> | 40 | #include <time.h> |
35 | 41 | ||
36 | FifteenMainWindow::FifteenMainWindow(QWidget *parent, const char* name, WFlags fl) | 42 | FifteenMainWindow::FifteenMainWindow(QWidget *parent, const char* name, WFlags fl) |
37 | : QMainWindow( parent, name, fl ) | 43 | : QMainWindow( parent, name, fl ) |
38 | { | 44 | { |
45 | |||
39 | // random seed | 46 | // random seed |
40 | srand(time(0)); | 47 | srand(time(0)); |
41 | setCaption( tr("Fifteen Pieces") ); | 48 | setCaption( tr("Fifteen Pieces") ); |
42 | 49 | ||
43 | QToolBar *toolbar = new QToolBar(this); | 50 | QToolBar *toolbar = new QToolBar(this); |
44 | toolbar->setHorizontalStretchable( FALSE ); | 51 | toolbar->setHorizontalStretchable( FALSE ); |
45 | QMenuBar *menubar = new QMenuBar( toolbar ); | 52 | QMenuBar *menubar = new QMenuBar( toolbar ); |
46 | menubar->setMargin(0); | 53 | menubar->setMargin(0); |
47 | QPopupMenu *game = new QPopupMenu( this ); | 54 | QPopupMenu *game = new QPopupMenu( this ); |
48 | 55 | ||
49 | QWidget *spacer = new QWidget( toolbar ); | 56 | QWidget *spacer = new QWidget( toolbar ); |
50 | spacer->setBackgroundMode( PaletteButton ); | 57 | spacer->setBackgroundMode( PaletteButton ); |
51 | toolbar->setStretchableWidget( spacer ); | 58 | toolbar->setStretchableWidget( spacer ); |
52 | 59 | ||
53 | 60 | ||
54 | setToolBarsMovable( FALSE ); | 61 | setToolBarsMovable( FALSE ); |
55 | QVBox *vbox = new QVBox( this ); | 62 | QVBox *vbox = new QVBox( this ); |
56 | PiecesTable *table = new PiecesTable( vbox ); | 63 | PiecesTable *table = new PiecesTable( vbox ); |
57 | setCentralWidget(vbox); | 64 | setCentralWidget(vbox); |
58 | 65 | ||
59 | 66 | ||
60 | 67 | ||
61 | QAction *a = new QAction( tr( "Randomize" ), Resource::loadPixmap( "new" ), | 68 | QAction *a = new QAction( tr( "Randomize" ), Resource::loadPixmap( "new" ), |
62 | QString::null, 0, this, 0 ); | 69 | QString::null, 0, this, 0 ); |
63 | connect( a, SIGNAL( activated() ), table, SLOT( slotRandomize() ) ); | 70 | connect( a, SIGNAL( activated() ), table, SLOT( slotRandomize() ) ); |
64 | a->addTo( game ); | 71 | a->addTo( game ); |
65 | a->addTo( toolbar ); | 72 | a->addTo( toolbar ); |
66 | 73 | ||
74 | |||
75 | a = new QAction( tr("Configure"), Resource::loadPixmap( "SettingsIcon" ), | ||
76 | QString::null, 0, this, 0 ); | ||
77 | connect( a, SIGNAL( activated()), table, SLOT( slotConfigure()) ); | ||
78 | a->addTo( game ); | ||
79 | |||
67 | /* This is pointless and confusing. | 80 | /* This is pointless and confusing. |
68 | a = new QAction( tr( "Solve" ), Resource::loadIconSet( "repeat" ), | 81 | a = new QAction( tr( "Solve" ), Resource::loadIconSet( "repeat" ), |
69 | QString::null, 0, this, 0 ); | 82 | QString::null, 0, this, 0 ); |
70 | connect( a, SIGNAL( activated() ), table, SLOT( slotReset() ) ); | 83 | connect( a, SIGNAL( activated() ), table, SLOT( slotReset() ) ); |
71 | a->addTo( game ); | 84 | a->addTo( game ); |
72 | a->addTo( toolbar ); | 85 | a->addTo( toolbar ); |
73 | */ | 86 | */ |
74 | menubar->insertItem( tr( "Game" ), game ); | 87 | menubar->insertItem( tr( "Game" ), game ); |
75 | } | 88 | } |
76 | 89 | ||
90 | |||
91 | |||
92 | |||
93 | /////////////// | ||
94 | /////// Pieces table Implementation | ||
95 | /////// | ||
77 | PiecesTable::PiecesTable(QWidget* parent, const char* name ) | 96 | PiecesTable::PiecesTable(QWidget* parent, const char* name ) |
78 | : QTableView(parent, name), _menu(0), _randomized(false) | 97 | : QTableView(parent, name), _menu(0), _randomized(false), |
98 | _dialog( 0l ) | ||
79 | { | 99 | { |
80 | // setup table view | 100 | // setup table view |
81 | setFrameStyle(StyledPanel | Sunken); | 101 | setFrameStyle(StyledPanel | Sunken); |
82 | setBackgroundMode(NoBackground); | 102 | setBackgroundMode(NoBackground); |
83 | setMouseTracking(true); | 103 | setMouseTracking(true); |
84 | 104 | ||
85 | setNumRows(4); | 105 | setNumRows(4); |
86 | setNumCols(4); | 106 | setNumCols(4); |
87 | 107 | ||
88 | // init arrays | 108 | // init arrays |
89 | initMap(); | 109 | initMap(); |
90 | readConfig(); | 110 | readConfig(); |
91 | initColors(); | 111 | initColors(); |
92 | 112 | ||
93 | // set font | ||
94 | QFont f = font(); | ||
95 | f.setPixelSize(18); | ||
96 | f.setBold( TRUE ); | ||
97 | setFont(f); | ||
98 | } | 113 | } |
99 | 114 | ||
115 | |||
100 | PiecesTable::~PiecesTable() | 116 | PiecesTable::~PiecesTable() |
101 | { | 117 | { |
102 | writeConfig(); | 118 | writeConfig(); |
119 | clear(); | ||
103 | } | 120 | } |
104 | 121 | ||
105 | void PiecesTable::writeConfig() | 122 | void PiecesTable::writeConfig() |
106 | { | 123 | { |
107 | Config cfg("Fifteen"); | 124 | Config cfg("Fifteen"); |
108 | cfg.setGroup("Game"); | 125 | cfg.setGroup("Game"); |
109 | QStringList map; | 126 | QStringList map; |
110 | for (int i = 0; i < 16; i++) | 127 | for (int i = 0; i < 16; i++) |
111 | map.append( QString::number( _map[i] ) ); | 128 | map.append( QString::number( _map[i] ) ); |
112 | cfg.writeEntry("Map", map, '-'); | 129 | cfg.writeEntry("Map", map, '-'); |
113 | cfg.writeEntry("Randomized", _randomized ); | 130 | cfg.writeEntry("Randomized", _randomized ); |
131 | cfg.writeEntry("Image", _image ); | ||
114 | } | 132 | } |
115 | 133 | ||
116 | void PiecesTable::readConfig() | 134 | void PiecesTable::readConfig() |
117 | { | 135 | { |
118 | Config cfg("Fifteen"); | 136 | Config cfg("Fifteen"); |
119 | cfg.setGroup("Game"); | 137 | cfg.setGroup("Game"); |
120 | QStringList map = cfg.readListEntry("Map", '-'); | 138 | QStringList map = cfg.readListEntry("Map", '-'); |
121 | _randomized = cfg.readBoolEntry( "Randomized", FALSE ); | 139 | _randomized = cfg.readBoolEntry( "Randomized", FALSE ); |
140 | _image = cfg.readEntry( "Image", QString::null ); | ||
122 | int i = 0; | 141 | int i = 0; |
123 | for ( QStringList::Iterator it = map.begin(); it != map.end(); ++it ) { | 142 | for ( QStringList::Iterator it = map.begin(); it != map.end(); ++it ) { |
124 | _map[i] = (*it).toInt(); | 143 | _map[i] = (*it).toInt(); |
125 | i++; | 144 | i++; |
126 | if ( i > 15 ) break; | 145 | if ( i > 15 ) break; |
127 | } | 146 | } |
147 | |||
148 | } | ||
149 | |||
150 | |||
151 | void PiecesTable::clear() { | ||
152 | /* clean up and resize */ | ||
153 | for (uint i = 0; i < _pixmap.count(); ++i ) | ||
154 | delete _pixmap[i]; | ||
155 | _pixmap.resize( 16 ); | ||
156 | } | ||
157 | |||
158 | /* | ||
159 | * Let us pre-render the tiles. Either we've a Custom Image as | ||
160 | * background or we use the drawRect to fill the background and | ||
161 | * last we put the number on it | ||
162 | */ | ||
163 | void PiecesTable::slotCustomImage( const QString& _str , bool upd ) { | ||
164 | QString str = _str; | ||
165 | |||
166 | |||
167 | /* couldn't load image fall back to plain tiles*/ | ||
168 | QImage img = QImage(str); | ||
169 | if(img.isNull()) | ||
170 | str = QString::null; | ||
171 | else | ||
172 | img = img.smoothScale( width(),height() ); | ||
173 | |||
174 | QPixmap pix; | ||
175 | pix.convertFromImage( img ); | ||
176 | |||
177 | uint image=0; | ||
178 | |||
179 | clear(); | ||
180 | |||
181 | /* used variables */ | ||
182 | int cols = numCols(); | ||
183 | int rows = numRows(); | ||
184 | int cellW = cellWidth(); | ||
185 | int cellH = cellHeight(); | ||
186 | int x2 = cellW-1; | ||
187 | int y2 = cellH-1; | ||
188 | bool empty = str.isEmpty(); | ||
189 | double bw = empty ? 0.9 : 0.98; | ||
190 | int x_offset = cellW - int(cellW * bw);// 10% should be enough | ||
191 | inty_offset = cellH - int(cellH * bw); | ||
192 | |||
193 | /* border polygon */ | ||
194 | initPolygon(cellW, cellH, x_offset, y_offset ); | ||
195 | |||
196 | if ( cellW == 0 || cellH == 0 ) { | ||
197 | _pixmap.resize( 0 ); | ||
198 | return; | ||
199 | } | ||
200 | |||
201 | QFont f = font(); | ||
202 | f.setPixelSize(18); | ||
203 | f.setBold( TRUE ); | ||
204 | |||
205 | /* for every tile */ | ||
206 | for(int row = 0; row < rows; ++row ) { | ||
207 | for(int col= 0; col < cols; ++col) { | ||
208 | QPixmap *pip = new QPixmap(cellW, cellH ); | ||
209 | QPainter *p = new QPainter(pip ); | ||
210 | p->setFont( f ); | ||
211 | |||
212 | /* draw the tradional tile or a part of the pixmap*/ | ||
213 | if(empty) { | ||
214 | p->setBrush(_colors[image]); | ||
215 | p->setPen(NoPen); | ||
216 | p->drawRect(0,0,cellW,cellH); | ||
217 | }else | ||
218 | p->drawPixmap(0, 0, pix,col*cellW, row*cellH, cellW, cellH ); | ||
219 | |||
220 | // draw borders | ||
221 | if (height() > 40) { | ||
222 | p->setBrush(_colors[image].light(130)); | ||
223 | p->drawPolygon(light_border); | ||
224 | |||
225 | p->setBrush(_colors[image].dark(130)); | ||
226 | p->drawPolygon(dark_border); | ||
227 | } | ||
228 | |||
229 | // draw number | ||
230 | p->setPen(black); | ||
231 | p->drawText(0, 0, x2, y2, AlignHCenter | AlignVCenter, QString::number(image+1)); | ||
232 | |||
233 | delete p; | ||
234 | _pixmap[image++] = pip; | ||
235 | } | ||
236 | } | ||
237 | _image = str; | ||
238 | |||
239 | if ( upd ) | ||
240 | update(); | ||
241 | } | ||
242 | |||
243 | /* | ||
244 | * Calculate 3d-effect borders | ||
245 | */ | ||
246 | void PiecesTable::initPolygon(int cell_w, int cell_h, int x_offset, int y_offset ) { | ||
247 | light_border.setPoints(6, | ||
248 | 0, 0, | ||
249 | cell_w, 0, | ||
250 | cell_w - x_offset, y_offset, | ||
251 | x_offset, y_offset, | ||
252 | x_offset, cell_h - y_offset, | ||
253 | 0, cell_h); | ||
254 | |||
255 | dark_border.setPoints(6, | ||
256 | cell_w, 0, | ||
257 | cell_w, cell_h, | ||
258 | 0, cell_h, | ||
259 | x_offset, cell_h - y_offset, | ||
260 | cell_w - x_offset, cell_h - y_offset, | ||
261 | cell_w - x_offset, y_offset); | ||
128 | } | 262 | } |
129 | 263 | ||
130 | void PiecesTable::paintCell(QPainter *p, int row, int col) | 264 | void PiecesTable::paintCell(QPainter *p, int row, int col) |
131 | { | 265 | { |
132 | int w = cellWidth(); | 266 | int w = cellWidth(); |
133 | int h = cellHeight(); | 267 | int h = cellHeight(); |
134 | int x2 = w - 1; | ||
135 | int y2 = h - 1; | ||
136 | 268 | ||
137 | int number = _map[col + row * numCols()] + 1; | 269 | int number = _map[col + row * numCols()] + 1; |
138 | 270 | ||
139 | // draw cell background | 271 | // draw cell background |
140 | if(number == 16) | 272 | if(number == 16) { |
141 | p->setBrush(colorGroup().background()); | 273 | p->setBrush(colorGroup().background()); |
142 | else | 274 | p->setPen(NoPen); |
143 | p->setBrush(_colors[number-1]); | 275 | p->drawRect(0, 0, w, h); |
144 | p->setPen(NoPen); | 276 | return; |
145 | p->drawRect(0, 0, w, h); | ||
146 | |||
147 | if (number == 16) return; | ||
148 | |||
149 | // draw borders | ||
150 | if (height() > 40) { | ||
151 | p->setBrush(_colors[number-1].light(130)); | ||
152 | p->drawPolygon(light_border); | ||
153 | |||
154 | p->setBrush(_colors[number-1].dark(130)); | ||
155 | p->drawPolygon(dark_border); | ||
156 | } | 277 | } |
157 | 278 | ||
158 | // draw number | 279 | if( _pixmap.count() == 0 ) |
159 | p->setPen(black); | 280 | return; |
160 | p->drawText(0, 0, x2, y2, AlignHCenter | AlignVCenter, QString::number(number)); | 281 | |
282 | p->drawPixmap(0, 0, *(_pixmap[(number-1 )]) ); | ||
161 | } | 283 | } |
162 | 284 | ||
163 | void PiecesTable::resizeEvent(QResizeEvent *e) | 285 | void PiecesTable::resizeEvent(QResizeEvent *e) |
164 | { | 286 | { |
165 | QTableView::resizeEvent(e); | 287 | QTableView::resizeEvent(e); |
166 | 288 | ||
167 | setCellWidth(contentsRect().width()/ numRows()); | 289 | setCellWidth(contentsRect().width()/ numRows()); |
168 | setCellHeight(contentsRect().height() / numCols()); | 290 | setCellHeight(contentsRect().height() / numCols()); |
169 | 291 | ||
170 | // | 292 | |
171 | // Calculate 3d-effect borders | 293 | /* update the image and calculate border*/ |
172 | // | 294 | slotCustomImage( _image ); |
173 | intcell_w = cellWidth(); | 295 | |
174 | intcell_h = cellHeight(); | ||
175 | int x_offset = cell_w - int(cell_w * 0.9);// 10% should be enough | ||
176 | inty_offset = cell_h - int(cell_h * 0.9); | ||
177 | |||
178 | light_border.setPoints(6, | ||
179 | 0, 0, | ||
180 | cell_w, 0, | ||
181 | cell_w - x_offset, y_offset, | ||
182 | x_offset, y_offset, | ||
183 | x_offset, cell_h - y_offset, | ||
184 | 0, cell_h); | ||
185 | |||
186 | dark_border.setPoints(6, | ||
187 | cell_w, 0, | ||
188 | cell_w, cell_h, | ||
189 | 0, cell_h, | ||
190 | x_offset, cell_h - y_offset, | ||
191 | cell_w - x_offset, cell_h - y_offset, | ||
192 | cell_w - x_offset, y_offset); | ||
193 | } | 296 | } |
194 | 297 | ||
195 | void PiecesTable::initColors() | 298 | void PiecesTable::initColors() |
196 | { | 299 | { |
197 | _colors.resize(numRows() * numCols()); | 300 | _colors.resize(numRows() * numCols()); |
198 | for (int r = 0; r < numRows(); r++) | 301 | for (int r = 0; r < numRows(); r++) |
199 | for (int c = 0; c < numCols(); c++) | 302 | for (int c = 0; c < numCols(); c++) |
200 | _colors[c + r *numCols()] = QColor(255 - 70 * c,255 - 70 * r, 150); | 303 | _colors[c + r *numCols()] = QColor(255 - 70 * c,255 - 70 * r, 150); |
201 | } | 304 | } |
202 | 305 | ||
203 | void PiecesTable::initMap() | 306 | void PiecesTable::initMap() |
204 | { | 307 | { |
205 | _map.resize(16); | 308 | _map.resize(16); |
206 | for ( int i = 0; i < 16; i++) | 309 | for ( int i = 0; i < 16; i++) |
207 | _map[i] = i; | 310 | _map[i] = i; |
208 | 311 | ||
209 | _randomized = false; | 312 | _randomized = false; |
210 | } | 313 | } |
211 | 314 | ||
212 | void PiecesTable::randomizeMap() | 315 | void PiecesTable::randomizeMap() |
213 | { | 316 | { |
214 | initMap(); | 317 | initMap(); |
215 | _randomized = true; | 318 | _randomized = true; |
216 | // find the free position | 319 | // find the free position |
217 | int pos = _map.find(15); | 320 | int pos = _map.find(15); |
218 | 321 | ||
219 | int move = 0; | 322 | int move = 0; |
220 | while ( move < 333 ) { | 323 | while ( move < 333 ) { |
221 | 324 | ||
222 | int frow = pos / numCols(); | 325 | int frow = pos / numCols(); |
223 | int fcol = pos - frow * numCols(); | 326 | int fcol = pos - frow * numCols(); |
224 | 327 | ||
225 | // find click position | 328 | // find click position |
226 | int row = rand()%4; | 329 | int row = rand()%4; |
227 | int col = rand()%4; | 330 | int col = rand()%4; |
228 | 331 | ||
229 | // sanity check | 332 | // sanity check |
230 | if ( row < 0 || row >= numRows() ) continue; | 333 | if ( row < 0 || row >= numRows() ) continue; |
231 | if ( col < 0 || col >= numCols() ) continue; | 334 | if ( col < 0 || col >= numCols() ) continue; |
232 | if ( row != frow && col != fcol ) continue; | 335 | if ( row != frow && col != fcol ) continue; |
233 | 336 | ||
234 | move++; | 337 | move++; |
235 | 338 | ||
236 | // rows match -> shift pieces | 339 | // rows match -> shift pieces |
237 | if(row == frow) { | 340 | if(row == frow) { |
238 | 341 | ||
239 | if (col < fcol) { | 342 | if (col < fcol) { |
240 | for(int c = fcol; c > col; c--) { | 343 | for(int c = fcol; c > col; c--) { |
241 | _map[c + row * numCols()] = _map[ c-1 + row *numCols()]; | 344 | _map[c + row * numCols()] = _map[ c-1 + row *numCols()]; |
242 | } | 345 | } |
243 | } | 346 | } |
244 | else if (col > fcol) { | 347 | else if (col > fcol) { |
245 | for(int c = fcol; c < col; c++) { | 348 | for(int c = fcol; c < col; c++) { |
246 | _map[c + row * numCols()] = _map[ c+1 + row *numCols()]; | 349 | _map[c + row * numCols()] = _map[ c+1 + row *numCols()]; |
247 | } | 350 | } |
248 | } | 351 | } |
249 | } | 352 | } |
250 | // cols match -> shift pieces | 353 | // cols match -> shift pieces |
251 | else if (col == fcol) { | 354 | else if (col == fcol) { |
252 | 355 | ||
253 | if (row < frow) { | 356 | if (row < frow) { |
254 | for(int r = frow; r > row; r--) { | 357 | for(int r = frow; r > row; r--) { |
255 | _map[col + r * numCols()] = _map[ col + (r-1) *numCols()]; | 358 | _map[col + r * numCols()] = _map[ col + (r-1) *numCols()]; |
256 | } | 359 | } |
257 | } | 360 | } |
258 | else if (row > frow) { | 361 | else if (row > frow) { |
259 | for(int r = frow; r < row; r++) { | 362 | for(int r = frow; r < row; r++) { |
260 | _map[col + r * numCols()] = _map[ col + (r+1) *numCols()]; | 363 | _map[col + r * numCols()] = _map[ col + (r+1) *numCols()]; |
261 | } | 364 | } |
262 | } | 365 | } |
263 | } | 366 | } |
264 | // move free cell to click position | 367 | // move free cell to click position |
265 | _map[pos=(col + row * numCols())] = 15; | 368 | _map[pos=(col + row * numCols())] = 15; |
266 | } | 369 | } |
267 | repaint(); | 370 | repaint(); |
268 | } | 371 | } |
269 | 372 | ||
270 | void PiecesTable::checkwin() | 373 | void PiecesTable::checkwin() |
271 | { | 374 | { |
272 | if(!_randomized) return; | 375 | if(!_randomized) return; |
273 | 376 | ||
274 | int i; | 377 | int i; |
275 | for (i = 0; i < 16; i++) | 378 | for (i = 0; i < 16; i++) |
276 | if(i != _map[i]) | 379 | if(i != _map[i]) |
277 | break; | 380 | break; |
278 | 381 | ||
279 | if (i == 16) { | 382 | if (i == 16) { |
280 | QMessageBox::information(this, tr("Fifteen Pieces"), | 383 | QMessageBox::information(this, tr("Fifteen Pieces"), |
281 | tr("Congratulations!\nYou win the game!")); | 384 | tr("Congratulations!\nYou win the game!")); |
282 | _randomized = FALSE; | 385 | _randomized = FALSE; |
283 | } | 386 | } |
284 | 387 | ||
285 | } | 388 | } |
286 | 389 | ||
287 | void PiecesTable::slotRandomize() | 390 | void PiecesTable::slotRandomize() |
288 | { | 391 | { |
@@ -291,96 +394,106 @@ void PiecesTable::slotRandomize() | |||
291 | 394 | ||
292 | void PiecesTable::slotReset() | 395 | void PiecesTable::slotReset() |
293 | { | 396 | { |
294 | initMap(); | 397 | initMap(); |
295 | repaint(); | 398 | repaint(); |
296 | } | 399 | } |
297 | 400 | ||
298 | void PiecesTable::mousePressEvent(QMouseEvent* e) | 401 | void PiecesTable::mousePressEvent(QMouseEvent* e) |
299 | { | 402 | { |
300 | QTableView::mousePressEvent(e); | 403 | QTableView::mousePressEvent(e); |
301 | 404 | ||
302 | if (e->button() == RightButton) { | 405 | if (e->button() == RightButton) { |
303 | 406 | ||
304 | // setup RMB pupup menu | 407 | // setup RMB pupup menu |
305 | if(!_menu) { | 408 | if(!_menu) { |
306 | _menu = new QPopupMenu(this); | 409 | _menu = new QPopupMenu(this); |
307 | _menu->insertItem(tr("R&andomize Pieces"), mRandomize); | 410 | _menu->insertItem(tr("R&andomize Pieces"), mRandomize); |
308 | _menu->insertItem(tr("&Reset Pieces"), mReset); | 411 | _menu->insertItem(tr("&Reset Pieces"), mReset); |
309 | _menu->adjustSize(); | 412 | _menu->adjustSize(); |
310 | } | 413 | } |
311 | 414 | ||
312 | // execute RMB popup and check result | 415 | // execute RMB popup and check result |
313 | switch(_menu->exec(mapToGlobal(e->pos()))) { | 416 | switch(_menu->exec(mapToGlobal(e->pos()))) { |
314 | case mRandomize: | 417 | case mRandomize: |
315 | randomizeMap(); | 418 | randomizeMap(); |
316 | break; | 419 | break; |
317 | case mReset: | 420 | case mReset: |
318 | initMap(); | 421 | initMap(); |
319 | repaint(); | 422 | repaint(); |
320 | break; | 423 | break; |
321 | default: | 424 | default: |
322 | break; | 425 | break; |
323 | } | 426 | } |
324 | } | 427 | } |
325 | else { | 428 | else { |
326 | // GAME LOGIC | 429 | // GAME LOGIC |
327 | 430 | ||
328 | // find the free position | 431 | // find the free position |
329 | int pos = _map.find(15); | 432 | int pos = _map.find(15); |
330 | if(pos < 0) return; | 433 | if(pos < 0) return; |
331 | 434 | ||
332 | int frow = pos / numCols(); | 435 | int frow = pos / numCols(); |
333 | int fcol = pos - frow * numCols(); | 436 | int fcol = pos - frow * numCols(); |
334 | 437 | ||
335 | // find click position | 438 | // find click position |
336 | int row = findRow(e->y()); | 439 | int row = findRow(e->y()); |
337 | int col = findCol(e->x()); | 440 | int col = findCol(e->x()); |
338 | 441 | ||
339 | // sanity check | 442 | // sanity check |
340 | if (row < 0 || row >= numRows()) return; | 443 | if (row < 0 || row >= numRows()) return; |
341 | if (col < 0 || col >= numCols()) return; | 444 | if (col < 0 || col >= numCols()) return; |
342 | if ( row != frow && col != fcol ) return; | 445 | if ( row != frow && col != fcol ) return; |
343 | 446 | ||
344 | // valid move? | 447 | // valid move? |
345 | if(row != frow && col != fcol) return; | 448 | if(row != frow && col != fcol) return; |
346 | 449 | ||
347 | // rows match -> shift pieces | 450 | // rows match -> shift pieces |
348 | if(row == frow) { | 451 | if(row == frow) { |
349 | 452 | ||
350 | if (col < fcol) { | 453 | if (col < fcol) { |
351 | for(int c = fcol; c > col; c--) { | 454 | for(int c = fcol; c > col; c--) { |
352 | _map[c + row * numCols()] = _map[ c-1 + row *numCols()]; | 455 | _map[c + row * numCols()] = _map[ c-1 + row *numCols()]; |
353 | updateCell(row, c, false); | 456 | updateCell(row, c, false); |
354 | } | 457 | } |
355 | } | 458 | } |
356 | else if (col > fcol) { | 459 | else if (col > fcol) { |
357 | for(int c = fcol; c < col; c++) { | 460 | for(int c = fcol; c < col; c++) { |
358 | _map[c + row * numCols()] = _map[ c+1 + row *numCols()]; | 461 | _map[c + row * numCols()] = _map[ c+1 + row *numCols()]; |
359 | updateCell(row, c, false); | 462 | updateCell(row, c, false); |
360 | } | 463 | } |
361 | } | 464 | } |
362 | } | 465 | } |
363 | // cols match -> shift pieces | 466 | // cols match -> shift pieces |
364 | else if (col == fcol) { | 467 | else if (col == fcol) { |
365 | 468 | ||
366 | if (row < frow) { | 469 | if (row < frow) { |
367 | for(int r = frow; r > row; r--) { | 470 | for(int r = frow; r > row; r--) { |
368 | _map[col + r * numCols()] = _map[ col + (r-1) *numCols()]; | 471 | _map[col + r * numCols()] = _map[ col + (r-1) *numCols()]; |
369 | updateCell(r, col, false); | 472 | updateCell(r, col, false); |
370 | } | 473 | } |
371 | } | 474 | } |
372 | else if (row > frow) { | 475 | else if (row > frow) { |
373 | for(int r = frow; r < row; r++) { | 476 | for(int r = frow; r < row; r++) { |
374 | _map[col + r * numCols()] = _map[ col + (r+1) *numCols()]; | 477 | _map[col + r * numCols()] = _map[ col + (r+1) *numCols()]; |
375 | updateCell(r, col, false); | 478 | updateCell(r, col, false); |
376 | } | 479 | } |
377 | } | 480 | } |
378 | } | 481 | } |
379 | // move free cell to click position | 482 | // move free cell to click position |
380 | _map[col + row * numCols()] = 15; | 483 | _map[col + row * numCols()] = 15; |
381 | updateCell(row, col, false); | 484 | updateCell(row, col, false); |
382 | 485 | ||
383 | // check if the player wins with this move | 486 | // check if the player wins with this move |
384 | checkwin(); | 487 | checkwin(); |
385 | } | 488 | } |
386 | } | 489 | } |
490 | |||
491 | void PiecesTable::slotConfigure() { | ||
492 | if ( !_dialog ) | ||
493 | _dialog = new FifteenConfigDialog(this, "Fifteen Configure Dialog", true ); | ||
494 | |||
495 | |||
496 | _dialog->setImageSrc( _image ); | ||
497 | if ( QPEApplication::execDialog(_dialog) == QDialog::Accepted ) | ||
498 | slotCustomImage( _dialog->imageSrc(), true ); | ||
499 | } | ||