-rw-r--r-- | noncore/games/fifteen/fifteen.cpp | 153 | ||||
-rw-r--r-- | noncore/games/fifteen/fifteen.h | 2 | ||||
-rw-r--r-- | noncore/games/fifteen/fifteenconfigdialog.cpp | 4 |
3 files changed, 108 insertions, 51 deletions
diff --git a/noncore/games/fifteen/fifteen.cpp b/noncore/games/fifteen/fifteen.cpp index f425e06..bb57ee1 100644 --- a/noncore/games/fifteen/fifteen.cpp +++ b/noncore/games/fifteen/fifteen.cpp | |||
@@ -106,7 +106,6 @@ PiecesTable::PiecesTable(QWidget* parent, const char* name ) | |||
106 | setNumCols(4); | 106 | setNumCols(4); |
107 | 107 | ||
108 | // init arrays | 108 | // init arrays |
109 | initMap(); | ||
110 | readConfig(); | 109 | readConfig(); |
111 | initColors(); | 110 | initColors(); |
112 | 111 | ||
@@ -124,11 +123,17 @@ void PiecesTable::writeConfig() | |||
124 | Config cfg("Fifteen"); | 123 | Config cfg("Fifteen"); |
125 | cfg.setGroup("Game"); | 124 | cfg.setGroup("Game"); |
126 | QStringList map; | 125 | QStringList map; |
127 | for (int i = 0; i < 16; i++) | 126 | |
127 | int items = numRows()*numCols(); | ||
128 | |||
129 | for (int i = 0; i < items; i++) | ||
128 | map.append( QString::number( _map[i] ) ); | 130 | map.append( QString::number( _map[i] ) ); |
131 | |||
129 | cfg.writeEntry("Map", map, '-'); | 132 | cfg.writeEntry("Map", map, '-'); |
130 | cfg.writeEntry("Randomized", _randomized ); | 133 | cfg.writeEntry("Randomized", _randomized ); |
131 | cfg.writeEntry("Image", _image ); | 134 | cfg.writeEntry("Image", _image ); |
135 | cfg.writeEntry("Rows", numRows() ); | ||
136 | cfg.writeEntry("Cols", numCols() ); | ||
132 | } | 137 | } |
133 | 138 | ||
134 | void PiecesTable::readConfig() | 139 | void PiecesTable::readConfig() |
@@ -138,11 +143,25 @@ void PiecesTable::readConfig() | |||
138 | QStringList map = cfg.readListEntry("Map", '-'); | 143 | QStringList map = cfg.readListEntry("Map", '-'); |
139 | _randomized = cfg.readBoolEntry( "Randomized", FALSE ); | 144 | _randomized = cfg.readBoolEntry( "Randomized", FALSE ); |
140 | _image = cfg.readEntry( "Image", QString::null ); | 145 | _image = cfg.readEntry( "Image", QString::null ); |
141 | int i = 0; | 146 | |
147 | int rows = cfg.readNumEntry( "Rows", 4 ); | ||
148 | int cols = cfg.readNumEntry( "Cols", 4 ); | ||
149 | uint items= rows*cols; | ||
150 | setNumRows( rows ); | ||
151 | setNumCols( cols ); | ||
152 | |||
153 | initMap(); | ||
154 | |||
155 | /* if we've more items than 'stones' don't restore the state */ | ||
156 | if ( items > map.count() ) | ||
157 | return; | ||
158 | |||
159 | |||
160 | uint i = 0; | ||
142 | for ( QStringList::Iterator it = map.begin(); it != map.end(); ++it ) { | 161 | for ( QStringList::Iterator it = map.begin(); it != map.end(); ++it ) { |
143 | _map[i] = (*it).toInt(); | 162 | _map[i] = (*it).toInt(); |
144 | i++; | 163 | i++; |
145 | if ( i > 15 ) break; | 164 | if ( i > items ) break; |
146 | } | 165 | } |
147 | 166 | ||
148 | } | 167 | } |
@@ -152,7 +171,7 @@ void PiecesTable::clear() { | |||
152 | /* clean up and resize */ | 171 | /* clean up and resize */ |
153 | for (uint i = 0; i < _pixmap.count(); ++i ) | 172 | for (uint i = 0; i < _pixmap.count(); ++i ) |
154 | delete _pixmap[i]; | 173 | delete _pixmap[i]; |
155 | _pixmap.resize( 16 ); | 174 | _pixmap.resize( numRows()*numCols() ); |
156 | } | 175 | } |
157 | 176 | ||
158 | /* | 177 | /* |
@@ -160,22 +179,24 @@ void PiecesTable::clear() { | |||
160 | * background or we use the drawRect to fill the background and | 179 | * background or we use the drawRect to fill the background and |
161 | * last we put the number on it | 180 | * last we put the number on it |
162 | */ | 181 | */ |
163 | void PiecesTable::slotCustomImage( const QString& _str , bool upd ) { | 182 | void PiecesTable::slotCustomImage( const QString& _str ) { |
164 | QString str = _str; | 183 | QString str = _str; |
165 | 184 | ||
166 | 185 | ||
167 | /* couldn't load image fall back to plain tiles*/ | 186 | /* couldn't load image fall back to plain tiles*/ |
168 | QImage img = QImage(str); | 187 | QImage img = QImage(str); |
188 | QPixmap pix; | ||
169 | if(img.isNull()) | 189 | if(img.isNull()) |
170 | str = QString::null; | 190 | str = QString::null; |
171 | else | 191 | else{ |
172 | img = img.smoothScale( width(),height() ); | 192 | img = img.smoothScale( width(),height() ); |
193 | pix.convertFromImage( img ); | ||
194 | } | ||
173 | 195 | ||
174 | QPixmap pix; | 196 | /* initialize base point */ |
175 | pix.convertFromImage( img ); | ||
176 | |||
177 | uint image=0; | 197 | uint image=0; |
178 | 198 | ||
199 | /* clear the old tiles */ | ||
179 | clear(); | 200 | clear(); |
180 | 201 | ||
181 | /* used variables */ | 202 | /* used variables */ |
@@ -190,14 +211,16 @@ void PiecesTable::slotCustomImage( const QString& _str , bool upd ) { | |||
190 | int x_offset = cellW - int(cellW * bw);// 10% should be enough | 211 | int x_offset = cellW - int(cellW * bw);// 10% should be enough |
191 | inty_offset = cellH - int(cellH * bw); | 212 | inty_offset = cellH - int(cellH * bw); |
192 | 213 | ||
193 | /* border polygon */ | 214 | /* border polygon calculation*/ |
194 | initPolygon(cellW, cellH, x_offset, y_offset ); | 215 | initPolygon(cellW, cellH, x_offset, y_offset ); |
195 | 216 | ||
217 | /* avoid crashes with isNull() pixmap later */ | ||
196 | if ( cellW == 0 || cellH == 0 ) { | 218 | if ( cellW == 0 || cellH == 0 ) { |
197 | _pixmap.resize( 0 ); | 219 | _pixmap.resize( 0 ); |
198 | return; | 220 | return; |
199 | } | 221 | } |
200 | 222 | ||
223 | /* make it bold and bigger */ | ||
201 | QFont f = font(); | 224 | QFont f = font(); |
202 | f.setPixelSize(18); | 225 | f.setPixelSize(18); |
203 | f.setBold( TRUE ); | 226 | f.setBold( TRUE ); |
@@ -235,9 +258,6 @@ void PiecesTable::slotCustomImage( const QString& _str , bool upd ) { | |||
235 | } | 258 | } |
236 | } | 259 | } |
237 | _image = str; | 260 | _image = str; |
238 | |||
239 | if ( upd ) | ||
240 | update(); | ||
241 | } | 261 | } |
242 | 262 | ||
243 | /* | 263 | /* |
@@ -266,16 +286,25 @@ void PiecesTable::paintCell(QPainter *p, int row, int col) | |||
266 | int w = cellWidth(); | 286 | int w = cellWidth(); |
267 | int h = cellHeight(); | 287 | int h = cellHeight(); |
268 | 288 | ||
289 | uint pos = col+row*numCols(); | ||
290 | |||
291 | /* sanity check. setNumRows()/setNumCols() calls repaint() directly */ | ||
292 | if ( pos >= _map.count() ) { | ||
293 | p->drawRect(0, 0, w, h); | ||
294 | return; | ||
295 | } | ||
296 | |||
269 | int number = _map[col + row * numCols()] + 1; | 297 | int number = _map[col + row * numCols()] + 1; |
270 | 298 | ||
271 | // draw cell background | 299 | // draw cell background |
272 | if(number == 16) { | 300 | if(number == numCols()*numRows() ) { |
273 | p->setBrush(colorGroup().background()); | 301 | p->setBrush(colorGroup().background()); |
274 | p->setPen(NoPen); | 302 | p->setPen(NoPen); |
275 | p->drawRect(0, 0, w, h); | 303 | p->drawRect(0, 0, w, h); |
276 | return; | 304 | return; |
277 | } | 305 | } |
278 | 306 | ||
307 | /* no tiles then contentRect() is not visible or too small anyway */ | ||
279 | if( _pixmap.count() == 0 ) | 308 | if( _pixmap.count() == 0 ) |
280 | return; | 309 | return; |
281 | 310 | ||
@@ -284,10 +313,15 @@ void PiecesTable::paintCell(QPainter *p, int row, int col) | |||
284 | 313 | ||
285 | void PiecesTable::resizeEvent(QResizeEvent *e) | 314 | void PiecesTable::resizeEvent(QResizeEvent *e) |
286 | { | 315 | { |
287 | QTableView::resizeEvent(e); | 316 | /* |
317 | * null if we faked it after the config dialog ran to | ||
318 | * regenerate everything | ||
319 | */ | ||
320 | if ( e ) | ||
321 | QTableView::resizeEvent(e); | ||
288 | 322 | ||
289 | setCellWidth(contentsRect().width()/ numRows()); | 323 | setCellWidth(contentsRect().width()/ numCols()); |
290 | setCellHeight(contentsRect().height() / numCols()); | 324 | setCellHeight(contentsRect().height() / numRows()); |
291 | 325 | ||
292 | 326 | ||
293 | /* update the image and calculate border*/ | 327 | /* update the image and calculate border*/ |
@@ -300,13 +334,14 @@ void PiecesTable::initColors() | |||
300 | _colors.resize(numRows() * numCols()); | 334 | _colors.resize(numRows() * numCols()); |
301 | for (int r = 0; r < numRows(); r++) | 335 | for (int r = 0; r < numRows(); r++) |
302 | for (int c = 0; c < numCols(); c++) | 336 | for (int c = 0; c < numCols(); c++) |
303 | _colors[c + r *numCols()] = QColor(255 - 70 * c,255 - 70 * r, 150); | 337 | _colors[c + r *numCols()] = QColor( 255 - (70 * c)%255 ,255 - (70 * r)%255, 150); |
304 | } | 338 | } |
305 | 339 | ||
306 | void PiecesTable::initMap() | 340 | void PiecesTable::initMap() |
307 | { | 341 | { |
308 | _map.resize(16); | 342 | int items = numCols()*numRows(); |
309 | for ( int i = 0; i < 16; i++) | 343 | _map.resize( items ); |
344 | for ( int i = 0; i < items; i++) | ||
310 | _map[i] = i; | 345 | _map[i] = i; |
311 | 346 | ||
312 | _randomized = false; | 347 | _randomized = false; |
@@ -317,21 +352,23 @@ void PiecesTable::randomizeMap() | |||
317 | initMap(); | 352 | initMap(); |
318 | _randomized = true; | 353 | _randomized = true; |
319 | // find the free position | 354 | // find the free position |
320 | int pos = _map.find(15); | 355 | int cols = numCols(); |
356 | int rows = numRows(); | ||
357 | int pos = _map.find( cols*rows -1 ); | ||
321 | 358 | ||
322 | int move = 0; | 359 | int move = 0; |
323 | while ( move < 333 ) { | 360 | while ( move < 333 ) { |
324 | 361 | ||
325 | int frow = pos / numCols(); | 362 | int frow = pos / cols; |
326 | int fcol = pos - frow * numCols(); | 363 | int fcol = pos - frow * cols; |
327 | 364 | ||
328 | // find click position | 365 | // find click position |
329 | int row = rand()%4; | 366 | int row = rand()%rows; |
330 | int col = rand()%4; | 367 | int col = rand()%cols; |
331 | 368 | ||
332 | // sanity check | 369 | // sanity check |
333 | if ( row < 0 || row >= numRows() ) continue; | 370 | if ( row < 0 || row >= rows ) continue; |
334 | if ( col < 0 || col >= numCols() ) continue; | 371 | if ( col < 0 || col >= cols ) continue; |
335 | if ( row != frow && col != fcol ) continue; | 372 | if ( row != frow && col != fcol ) continue; |
336 | 373 | ||
337 | move++; | 374 | move++; |
@@ -341,12 +378,12 @@ void PiecesTable::randomizeMap() | |||
341 | 378 | ||
342 | if (col < fcol) { | 379 | if (col < fcol) { |
343 | for(int c = fcol; c > col; c--) { | 380 | for(int c = fcol; c > col; c--) { |
344 | _map[c + row * numCols()] = _map[ c-1 + row *numCols()]; | 381 | _map[c + row * cols] = _map[ c-1 + row *cols]; |
345 | } | 382 | } |
346 | } | 383 | } |
347 | else if (col > fcol) { | 384 | else if (col > fcol) { |
348 | for(int c = fcol; c < col; c++) { | 385 | for(int c = fcol; c < col; c++) { |
349 | _map[c + row * numCols()] = _map[ c+1 + row *numCols()]; | 386 | _map[c + row * cols] = _map[ c+1 + row *cols]; |
350 | } | 387 | } |
351 | } | 388 | } |
352 | } | 389 | } |
@@ -355,17 +392,17 @@ void PiecesTable::randomizeMap() | |||
355 | 392 | ||
356 | if (row < frow) { | 393 | if (row < frow) { |
357 | for(int r = frow; r > row; r--) { | 394 | for(int r = frow; r > row; r--) { |
358 | _map[col + r * numCols()] = _map[ col + (r-1) *numCols()]; | 395 | _map[col + r * cols] = _map[ col + (r-1) *cols]; |
359 | } | 396 | } |
360 | } | 397 | } |
361 | else if (row > frow) { | 398 | else if (row > frow) { |
362 | for(int r = frow; r < row; r++) { | 399 | for(int r = frow; r < row; r++) { |
363 | _map[col + r * numCols()] = _map[ col + (r+1) *numCols()]; | 400 | _map[col + r * cols] = _map[ col + (r+1) *cols]; |
364 | } | 401 | } |
365 | } | 402 | } |
366 | } | 403 | } |
367 | // move free cell to click position | 404 | // move free cell to click position |
368 | _map[pos=(col + row * numCols())] = 15; | 405 | _map[pos=(col + row * cols)] = rows*cols-1; |
369 | } | 406 | } |
370 | repaint(); | 407 | repaint(); |
371 | } | 408 | } |
@@ -374,12 +411,13 @@ void PiecesTable::checkwin() | |||
374 | { | 411 | { |
375 | if(!_randomized) return; | 412 | if(!_randomized) return; |
376 | 413 | ||
414 | int items=numCols()*numRows(); | ||
377 | int i; | 415 | int i; |
378 | for (i = 0; i < 16; i++) | 416 | for (i = 0; i < items; i++) |
379 | if(i != _map[i]) | 417 | if(i != _map[i]) |
380 | break; | 418 | break; |
381 | 419 | ||
382 | if (i == 16) { | 420 | if (i == items) { |
383 | QMessageBox::information(this, tr("Fifteen Pieces"), | 421 | QMessageBox::information(this, tr("Fifteen Pieces"), |
384 | tr("Congratulations!\nYou win the game!")); | 422 | tr("Congratulations!\nYou win the game!")); |
385 | _randomized = FALSE; | 423 | _randomized = FALSE; |
@@ -427,21 +465,24 @@ void PiecesTable::mousePressEvent(QMouseEvent* e) | |||
427 | } | 465 | } |
428 | else { | 466 | else { |
429 | // GAME LOGIC | 467 | // GAME LOGIC |
468 | int cols = numCols(); | ||
469 | int rows = numRows(); | ||
470 | int item = cols*rows -1; | ||
430 | 471 | ||
431 | // find the free position | 472 | // find the free position |
432 | int pos = _map.find(15); | 473 | int pos = _map.find(item); |
433 | if(pos < 0) return; | 474 | if(pos < 0) return; |
434 | 475 | ||
435 | int frow = pos / numCols(); | 476 | int frow = pos / cols; |
436 | int fcol = pos - frow * numCols(); | 477 | int fcol = pos - frow * cols; |
437 | 478 | ||
438 | // find click position | 479 | // find click position |
439 | int row = findRow(e->y()); | 480 | int row = findRow(e->y()); |
440 | int col = findCol(e->x()); | 481 | int col = findCol(e->x()); |
441 | 482 | ||
442 | // sanity check | 483 | // sanity check |
443 | if (row < 0 || row >= numRows()) return; | 484 | if (row < 0 || row >= rows) return; |
444 | if (col < 0 || col >= numCols()) return; | 485 | if (col < 0 || col >= cols) return; |
445 | if ( row != frow && col != fcol ) return; | 486 | if ( row != frow && col != fcol ) return; |
446 | 487 | ||
447 | // valid move? | 488 | // valid move? |
@@ -452,13 +493,13 @@ void PiecesTable::mousePressEvent(QMouseEvent* e) | |||
452 | 493 | ||
453 | if (col < fcol) { | 494 | if (col < fcol) { |
454 | for(int c = fcol; c > col; c--) { | 495 | for(int c = fcol; c > col; c--) { |
455 | _map[c + row * numCols()] = _map[ c-1 + row *numCols()]; | 496 | _map[c + row * cols] = _map[ c-1 + row *cols]; |
456 | updateCell(row, c, false); | 497 | updateCell(row, c, false); |
457 | } | 498 | } |
458 | } | 499 | } |
459 | else if (col > fcol) { | 500 | else if (col > fcol) { |
460 | for(int c = fcol; c < col; c++) { | 501 | for(int c = fcol; c < col; c++) { |
461 | _map[c + row * numCols()] = _map[ c+1 + row *numCols()]; | 502 | _map[c + row * cols] = _map[ c+1 + row *cols]; |
462 | updateCell(row, c, false); | 503 | updateCell(row, c, false); |
463 | } | 504 | } |
464 | } | 505 | } |
@@ -468,19 +509,19 @@ void PiecesTable::mousePressEvent(QMouseEvent* e) | |||
468 | 509 | ||
469 | if (row < frow) { | 510 | if (row < frow) { |
470 | for(int r = frow; r > row; r--) { | 511 | for(int r = frow; r > row; r--) { |
471 | _map[col + r * numCols()] = _map[ col + (r-1) *numCols()]; | 512 | _map[col + r * cols] = _map[ col + (r-1) *cols]; |
472 | updateCell(r, col, false); | 513 | updateCell(r, col, false); |
473 | } | 514 | } |
474 | } | 515 | } |
475 | else if (row > frow) { | 516 | else if (row > frow) { |
476 | for(int r = frow; r < row; r++) { | 517 | for(int r = frow; r < row; r++) { |
477 | _map[col + r * numCols()] = _map[ col + (r+1) *numCols()]; | 518 | _map[col + r * cols] = _map[ col + (r+1) *cols]; |
478 | updateCell(r, col, false); | 519 | updateCell(r, col, false); |
479 | } | 520 | } |
480 | } | 521 | } |
481 | } | 522 | } |
482 | // move free cell to click position | 523 | // move free cell to click position |
483 | _map[col + row * numCols()] = 15; | 524 | _map[col + row * cols] = item; |
484 | updateCell(row, col, false); | 525 | updateCell(row, col, false); |
485 | 526 | ||
486 | // check if the player wins with this move | 527 | // check if the player wins with this move |
@@ -494,6 +535,24 @@ void PiecesTable::slotConfigure() { | |||
494 | 535 | ||
495 | 536 | ||
496 | _dialog->setImageSrc( _image ); | 537 | _dialog->setImageSrc( _image ); |
497 | if ( QPEApplication::execDialog(_dialog) == QDialog::Accepted ) | 538 | _dialog->setGameboard( numRows(), numCols() ); |
498 | slotCustomImage( _dialog->imageSrc(), true ); | 539 | |
540 | if ( QPEApplication::execDialog(_dialog) == QDialog::Accepted ) { | ||
541 | /* | ||
542 | * update the board grid and reinit the game if changed | ||
543 | * First set new columns so the update will regenerate the | ||
544 | * tiles with slotCustomImage | ||
545 | */ | ||
546 | _image = _dialog->imageSrc(); | ||
547 | if (numRows() != _dialog->rows() || | ||
548 | numCols() != _dialog->columns() ) { | ||
549 | setNumCols(_dialog->columns()); | ||
550 | setNumRows(_dialog->rows()); | ||
551 | slotReset(); | ||
552 | } | ||
553 | resizeEvent( 0l ); | ||
554 | |||
555 | |||
556 | update(); | ||
557 | } | ||
499 | } | 558 | } |
diff --git a/noncore/games/fifteen/fifteen.h b/noncore/games/fifteen/fifteen.h index 4b8702d..c70afc8 100644 --- a/noncore/games/fifteen/fifteen.h +++ b/noncore/games/fifteen/fifteen.h | |||
@@ -41,7 +41,7 @@ class PiecesTable : public QTableView | |||
41 | 41 | ||
42 | protected slots: | 42 | protected slots: |
43 | void slotConfigure(); | 43 | void slotConfigure(); |
44 | void slotCustomImage(const QString &str, bool upd = false); | 44 | void slotCustomImage(const QString &str); |
45 | void slotRandomize(); | 45 | void slotRandomize(); |
46 | void slotReset(); | 46 | void slotReset(); |
47 | 47 | ||
diff --git a/noncore/games/fifteen/fifteenconfigdialog.cpp b/noncore/games/fifteen/fifteenconfigdialog.cpp index 3f974f8..8539e0e 100644 --- a/noncore/games/fifteen/fifteenconfigdialog.cpp +++ b/noncore/games/fifteen/fifteenconfigdialog.cpp | |||
@@ -45,9 +45,7 @@ using Opie::Ui::OFileDialog; | |||
45 | 45 | ||
46 | FifteenConfigDialog::FifteenConfigDialog( QWidget* parent, const char* name, bool modal ) | 46 | FifteenConfigDialog::FifteenConfigDialog( QWidget* parent, const char* name, bool modal ) |
47 | : FifteenConfigDialogBase( parent, name, modal ) | 47 | : FifteenConfigDialogBase( parent, name, modal ) |
48 | { | 48 | {} |
49 | grpGameGrid->hide(); | ||
50 | } | ||
51 | 49 | ||
52 | FifteenConfigDialog::~FifteenConfigDialog() | 50 | FifteenConfigDialog::~FifteenConfigDialog() |
53 | {} | 51 | {} |