• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdegames API Reference
  • KDE Home
  • Contact Us
 

kmahjongg

  • sources
  • kde-4.14
  • kdegames
  • kmahjongg
boardwidget.cpp
Go to the documentation of this file.
1 /* Copyright (C) 1997 Mathias Mueller <in5y158@public.uni-hamburg.de>
2  * Copyright (C) 2006 Mauricio Piacentini <mauricio@tabuleiro.com>
3  *
4  * Kmahjongg is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17 
18 #include "boardwidget.h"
19 #include "prefs.h"
20 
21 #include <QTimer>
22 #include <qpainter.h>
23 #include <qapplication.h>
24 
25 #include <klocale.h>
26 #include <kstandarddirs.h>
27 #include <kmessagebox.h>
28 #include <krandom.h>
29 #include <kconfig.h>
30 #include <kglobal.h>
31 #include <KDebug>
32 
33 
34 BoardWidget::BoardWidget(QWidget *parent)
35  : KGameCanvasWidget(parent),
36  theTiles()
37 {
38  QPalette palette;
39  palette.setColor(backgroundRole(), Qt::black);
40  setPalette(palette);
41 
42  timer = new QTimer(this);
43  connect(timer, SIGNAL(timeout()), this, SLOT(helpMoveTimeout()));
44 
45  TimerState = Stop;
46  gamePaused = false;
47  iTimerStep = 0;
48  matchCount = 0;
49  showMatch = false;
50  showHelp = false;
51 
52  //memset( &Game->Mask, 0, sizeof( Game->Mask ) );
53  gameGenerationNum = 0;
54  m_angle = (TileViewAngle) Prefs::angle();
55 
56  // Load layout first
57  loadBoardLayout(Prefs::layout());
58 
59  //Initialize our Game structure
60  Game = new GameData(theBoardLayout.board());
61 
62  MouseClickPos1.e = Game->m_depth; // mark tile position as invalid
63  MouseClickPos2.e = Game->m_depth;
64 
65  //Animation timers
66  animateForwardTimer = new QTimer(this);
67  animateForwardTimer->setSingleShot(true);
68  animateForwardTimer->setInterval(100);
69  connect(animateForwardTimer, SIGNAL(timeout()), SLOT(animatingMoveListForward()));
70  animateForwardTimer->stop();
71 
72  animateBackwardsTimer = new QTimer(this);
73  animateBackwardsTimer->setSingleShot(true);
74  animateBackwardsTimer->setInterval(100);
75  connect(animateBackwardsTimer, SIGNAL(timeout()), SLOT(animatingMoveListBackwards()));
76  animateBackwardsTimer->stop();
77 
78  loadSettings();
79 }
80 
81 BoardWidget::~BoardWidget()
82 {
83  delete Game;
84 }
85 
86 void BoardWidget::loadSettings()
87 {
88  // Load tileset. First try to load the last use tileset
89 
90  if (!loadTileset(Prefs::tileSet())) {
91  kDebug() << "An error occurred when loading the tileset" << Prefs::tileSet() << "KMahjongg "
92  "will continue with the default tileset.";
93  }
94 
95  // Load background
96  if (!loadBackground(Prefs::background(), false)) {
97  kDebug() << "An error occurred when loading the background" << Prefs::background() << "KMah"
98  "jongg will continue with the default background.";
99  }
100 
101  setShowMatch(Prefs::showMatchingTiles());
102 
103  // If the random layout is activated, we won't load a boardlayout, as it will be created
104  // randomly in calculateNewGame().
105  if (!Prefs::randomLayout()) {
106  if (QString::compare(Prefs::layout(), theBoardLayout.path(), Qt::CaseSensitive) !=0 ) {
107  //TODO: WARN USER HERE ABOUT DESTRUCTIVE OPERATION!!!
108  loadBoardLayout(Prefs::layout());
109  calculateNewGame();
110  }
111  } else {
112  calculateNewGame();
113  }
114 
115  setDisplayedWidth();
116  drawBoard(true);
117 
118  //Store our updated settings, some values might have been changed to defaults
119  saveSettings();
120 }
121 
122 void BoardWidget::resizeEvent(QResizeEvent *event)
123 {
124  if (event->spontaneous()) {
125  return;
126  }
127 
128  resizeTileset(event->size());
129  theBackground.sizeChanged(requiredWidth(), requiredHeight());
130  drawBoard(true);
131 }
132 
133 void BoardWidget::resizeTileset(const QSize &wsize)
134 {
135  QSize newtiles = theTiles.preferredTileSize(wsize, requiredHorizontalCells(),
136  requiredVerticalCells());
137 
138  theTiles.reloadTileset(newtiles);
139  stopMatchAnimation();
140 }
141 
142 void BoardWidget::saveSettings()
143 {
144  Prefs::setTileSet(theTiles.path());
145  Prefs::setLayout(theBoardLayout.path());
146  Prefs::setBackground(theBackground.path());
147  Prefs::setAngle(m_angle);
148  Prefs::self()->writeConfig();
149 }
150 
151 void BoardWidget::setDisplayedWidth()
152 {
153  //TODO remove method and let the layout handle it
154  //for now we just force our resizeEvent() to be called
155  resize(width(), height());
156 }
157 
158 void BoardWidget::populateSpriteMap()
159 {
160  //Delete previous sprites (full update), synchronize state with GameData
161  while (!items()->isEmpty()) {
162  delete items()->first();
163  }
164 
165  //Clear our spritemap as well
166  spriteMap.clear();
167 
168  //Recreate our background
169  QPalette palette;
170  palette.setBrush(backgroundRole(), theBackground.getBackground());
171  setPalette(palette);
172  setAutoFillBackground(true);
173 
174  //create the sprites
175  for (int z = 0; z < Game->m_depth; z++) {
176  // we draw down the board so the tile below over rights our border
177  for (int y = 0; y < Game->m_height; y++) {
178  // drawing right to left to prevent border overwrite
179  for (int x = Game->m_width - 1; x >= 0; x--) {
180 
181  // skip if no tile to display
182  if (!Game->tilePresent(z, y, x)) {
183  continue;
184  }
185 
186  QPixmap s;
187  QPixmap us;
188  QPixmap f;
189  bool selected = false;
190  s = theTiles.selectedTile(m_angle);
191  us = theTiles.unselectedTile(m_angle);
192  f = theTiles.tileface(Game->BoardData(z, y, x) - TILE_OFFSET);
193 
194  if (Game->HighlightData(z, y, x)) {
195  selected = true;
196  }
197 
198  TileSprite *thissprite = new TileSprite(this, us, s, f, m_angle, selected);
199 
200  spriteMap.insert(TileCoord(x, y, z), thissprite);
201  }
202  }
203  }
204 
205  updateSpriteMap();
206 }
207 
208 void BoardWidget::updateSpriteMap()
209 {
210  // initial offset on the screen of tile 0,0
211  // think of it as what is left if you add all tilefaces (qwidth/heigh*2) plus one
212  // (wholetile - shadow(3dindent) - tileface), and divide by 2
213  int xOffset = (width() - (Game->m_width * (theTiles.qWidth())) - (theTiles.width()
214  - (theTiles.qWidth() * 2))) / 2;
215  int yOffset = (height() - (Game->m_height * (theTiles.qHeight())) - (theTiles.height()
216  - (theTiles.qHeight() * 2))) / 2;
217 
218  // we iterate over the depth stacking order. Each successive level is
219  // drawn one indent up and to the right. The indent is the width
220  // of the 3d relief on the tile left (tile shadow width)
221  switch (m_angle) {
222  case NW:
223  //remove shadow from margin calculation
224  xOffset += theTiles.levelOffsetX() / 2;
225  yOffset += theTiles.levelOffsetY() / 2;
226 
227  //Position
228  for (int z = 0; z < Game->m_depth; z++) {
229  // we draw down the board so the tile below over rights our border
230  for (int y = 0; y < Game->m_height; y++) {
231  // drawing right to left to prevent border overwrite
232  for (int x=Game->m_width - 1; x >= 0; x--) {
233  int sx = x * (theTiles.qWidth()) + xOffset;
234  int sy = y * (theTiles.qHeight()) + yOffset;
235 
236  // skip if no tile to display
237  if (!Game->tilePresent(z, y, x)) {
238  continue;
239  }
240 
241  TileSprite *thissprite = spriteMap.value(TileCoord(x, y, z));
242 
243  if (thissprite) {
244  thissprite->moveTo(sx, sy);
245  }
246 
247  if (thissprite) {
248  thissprite->show();
249  }
250  }
251  }
252 
253  xOffset += theTiles.levelOffsetX();
254  yOffset -= theTiles.levelOffsetY();
255  }
256 
257  //Layer
258  for (int z = 0; z < Game->m_depth; z++) {
259  // start drawing in diagonal for correct layering. For this we double the board,
260  //actually starting outside of it, in the bottom right corner, so our first diagonal ends
261  // at the actual top right corner of the board
262  for (int x = Game->m_width * 2; x >= 0; x--) {
263  // reset the offset
264  int offset = 0;
265 
266  for (int y = Game->m_height - 1; y >= 0; y--) {
267  if (Game->tilePresent(z, y, x - offset)) {
268  TileSprite *thissprite = spriteMap.value(TileCoord(x - offset, y, z));
269 
270  if (thissprite) {
271  thissprite->raise();
272  }
273  }
274 
275  //at each pass, move one place to the left
276  offset++;
277  }
278  }
279  }
280 
281  break;
282 
283  case NE:
284  xOffset -= theTiles.levelOffsetX() / 2;
285  yOffset += theTiles.levelOffsetY() / 2;
286 
287  //Position
288  for (int z = 0; z < Game->m_depth; z++) {
289  // we draw down the board so the tile below over rights our border
290  for (int y = 0; y < Game->m_height; y++) {
291  // drawing right to left to prevent border overwrite
292  for (int x = 0; x <= Game->m_width - 1; x++) {
293  int sx = x * (theTiles.qWidth()) + xOffset;
294  int sy = y * (theTiles.qHeight()) + yOffset;
295 
296  // skip if no tile to display
297  if (!Game->tilePresent(z, y, x)) {
298  continue;
299  }
300 
301  TileSprite *thissprite = spriteMap.value(TileCoord(x, y, z));
302 
303  if (thissprite) {
304  thissprite->moveTo(sx, sy);
305  }
306 
307  if (thissprite) {
308  thissprite->show();
309  }
310  }
311  }
312 
313  xOffset -= theTiles.levelOffsetX();
314  yOffset -= theTiles.levelOffsetY();
315  }
316 
317  //Layer
318  for (int z = 0; z < Game->m_depth; z++) {
319  // start drawing in diagonal for correct layering. For this we double the board,
320  //actually starting outside of it, in the bottom right corner, so our first diagonal ends
321  // at the actual top right corner of the board
322  for (int x =- (Game->m_width); x <= Game->m_width - 1; x++) {
323  // reset the offset
324  int offset = 0;
325 
326  for (int y = Game->m_height - 1; y >= 0; y--) {
327  if (Game->tilePresent(z, y, x + offset)) {
328  TileSprite *thissprite = spriteMap.value(TileCoord(x + offset, y, z));
329 
330  if (thissprite) {
331  thissprite->raise();
332  }
333  }
334 
335  //at each pass, move one place to the right
336  offset++;
337  }
338  }
339  }
340 
341  break;
342 
343  case SE:
344  xOffset -= theTiles.levelOffsetX() / 2;
345  yOffset -= theTiles.levelOffsetY() / 2;
346 
347  //Position
348  for (int z = 0; z < Game->m_depth; z++) {
349  for (int y = Game->m_height - 1; y >= 0; y--) {
350  for (int x = 0; x <= Game->m_width - 1; x++) {
351  int sx = x * (theTiles.qWidth()) + xOffset;
352  int sy = y * (theTiles.qHeight()) + yOffset;
353 
354  if (!Game->tilePresent(z, y, x)) {
355  continue;
356  }
357 
358  TileSprite *thissprite = spriteMap.value(TileCoord(x, y, z));
359 
360  if (thissprite) {
361  thissprite->moveTo(sx, sy);
362  }
363 
364  if (thissprite) {
365  thissprite->show();
366  }
367  }
368  }
369 
370  xOffset -= theTiles.levelOffsetX();
371  yOffset += theTiles.levelOffsetY();
372  }
373 
374  //Layer
375  for (int z = 0; z < Game->m_depth; z++) {
376  for (int x =- (Game->m_width); x <= Game->m_width - 1; x++) {
377  int offset = 0;
378 
379  for (int y = 0; y < Game->m_height; y++) {
380  if (Game->tilePresent(z, y, x + offset)) {
381  TileSprite *thissprite = spriteMap.value(TileCoord(x + offset, y, z));
382  if (thissprite) {
383  thissprite->raise();
384  }
385  }
386 
387  offset++;
388  }
389  }
390  }
391 
392  break;
393 
394  case SW:
395  xOffset += theTiles.levelOffsetX() / 2;
396  yOffset -= theTiles.levelOffsetY() / 2;
397 
398  //Position
399  for (int z = 0; z < Game->m_depth; z++) {
400  for (int y = Game->m_height - 1; y >= 0; y--) {
401  for (int x = Game->m_width - 1; x >= 0; x--) {
402  int sx = x * (theTiles.qWidth()) + xOffset;
403  int sy = y * (theTiles.qHeight()) + yOffset;
404 
405  if (!Game->tilePresent(z, y, x)) {
406  continue;
407  }
408 
409  TileSprite *thissprite = spriteMap.value(TileCoord(x, y, z));
410 
411  if (thissprite) {
412  thissprite->moveTo(sx, sy);
413  }
414 
415  if (thissprite) {
416  thissprite->show();
417  }
418  }
419  }
420 
421  xOffset += theTiles.levelOffsetX();
422  yOffset += theTiles.levelOffsetY();
423  }
424 
425  //Layer
426  for (int z = 0; z < Game->m_depth; z++) {
427  for (int x = Game->m_width * 2; x >= 0; x--) {
428  int offset = 0;
429 
430  for (int y = 0; y < Game->m_height; y++) {
431  if (Game->tilePresent(z, y, x - offset)) {
432  TileSprite *thissprite = spriteMap.value(TileCoord(x - offset, y, z));
433 
434  if (thissprite) {
435  thissprite->raise();
436  }
437  }
438 
439  offset++;
440  }
441  }
442  }
443 
444  break;
445  }
446 }
447 
448 void BoardWidget::pause()
449 {
450  gamePaused = !gamePaused;
451  drawBoard(!gamePaused);
452 }
453 
454 void BoardWidget::gameLoaded()
455 {
456  int i;
457  Game->initialiseRemovedTiles();
458  i = Game->TileNum;
459 
460  // use the history of moves to put in the removed tiles area the correct tiles
461  while (i < Game->MaxTileNum) {
462  Game->setRemovedTilePair(Game->MoveListData(i), Game->MoveListData(i + 1));
463  i += 2;
464  }
465 
466  populateSpriteMap();
467  drawBoard(true);
468 }
469 
470 int BoardWidget::undoMove()
471 {
472  cancelUserSelectedTiles();
473 
474  if (Game->TileNum < Game->MaxTileNum)
475  {
476  Game->clearRemovedTilePair(Game->MoveListData(Game->TileNum), Game->MoveListData(
477  Game->TileNum + 1));
478  putTileInBoard(Game->MoveListData(Game->TileNum), false);
479  Game->TileNum++;
480  putTileInBoard(Game->MoveListData(Game->TileNum));
481  Game->TileNum++;
482  drawTileNumber();
483  setStatusText(i18n("Undo operation done successfully."));
484 
485  return 1;
486  } else {
487  setStatusText(i18n("What do you want to undo? You have done nothing!"));
488 
489  return 0;
490  }
491 }
492 
493 void BoardWidget::helpMove()
494 {
495  cancelUserSelectedTiles();
496  if (showHelp) helpMoveStop();
497 
498  if (Game->findMove(TimerPos1, TimerPos2)) {
499  cheatsUsed++;
500  iTimerStep = 1;
501  showHelp = true;
502  helpMoveTimeout();
503  } else {
504  setStatusText(i18n("Sorry, you have lost the game."));
505  }
506 }
507 
508 void BoardWidget::helpMoveTimeout()
509 {
510  if (iTimerStep & 1) {
511  hilightTile(TimerPos1, true, false);
512  hilightTile(TimerPos2, true);
513  } else {
514  hilightTile(TimerPos1, false, false);
515  hilightTile(TimerPos2, false);
516  }
517 
518  // restart timer
519  if (iTimerStep++ < 8) {
520  timer->setSingleShot(true);
521  timer->start(ANIMSPEED);
522  } else {
523  showHelp = false;
524  }
525 }
526 
527 void BoardWidget::helpMoveStop()
528 {
529  timer->stop();
530  iTimerStep = 8;
531  hilightTile(TimerPos1, false, false);
532  hilightTile(TimerPos2, false);
533  showHelp = false;
534 }
535 
536 void BoardWidget::startDemoMode()
537 {
538  calculateNewGame();
539 
540  if (TimerState == Stop) {
541  TimerState = Demo;
542  iTimerStep = 0;
543  emit demoModeChanged(true);
544  setStatusText(i18n("Demo mode. Click mousebutton to stop."));
545  demoMoveTimeout();
546  }
547 }
548 
549 void BoardWidget::stopDemoMode()
550 {
551  TimerState = Stop; // stop demo
552  calculateNewGame();
553  setStatusText(i18n("Now it is you again."));
554 
555  emit demoModeChanged(false);
556  emit gameCalculated();
557 }
558 
559 void BoardWidget::demoMoveTimeout()
560 {
561  if (TimerState == Demo) {
562  switch (iTimerStep++ % 6) {
563  case 0:
564  if (!Game->findMove(TimerPos1, TimerPos2)) {
565  // if computer has won
566  if (Game->TileNum == 0) {
567  animateMoveList();
568  } else {
569  setStatusText(i18n("Your computer has lost the game."));
570 
571  while (Game->TileNum < Game->MaxTileNum) {
572  putTileInBoard(Game->MoveListData(Game->TileNum), false);
573  Game->TileNum++;
574  putTileInBoard(Game->MoveListData(Game->TileNum));
575  Game->TileNum++;
576  drawTileNumber();
577  }
578  }
579 
580  TimerState = Stop;
581  //startDemoMode();
582  //do not loop demo
583  stopDemoMode();
584 
585  return;
586  }
587 
588  break;
589 
590  case 1:
591  case 3:
592  hilightTile(TimerPos1, true, false);
593  hilightTile(TimerPos2, true);
594 
595  break;
596 
597  case 2:
598  case 4:
599  hilightTile(TimerPos1, false, false);
600  hilightTile(TimerPos2, false);
601 
602  break;
603 
604  case 5:
605  Game->setRemovedTilePair(TimerPos1, TimerPos2);
606  removeTile(TimerPos1, false);
607  removeTile(TimerPos2);
608  drawTileNumber();
609 
610  break;
611  }
612 
613  // restart timer
614  QTimer::singleShot(ANIMSPEED, this, SLOT(demoMoveTimeout()));
615  }
616 }
617 
618 void BoardWidget::setShowMatch(bool show)
619 {
620  if (showMatch) {
621  stopMatchAnimation();
622  }
623 
624  showMatch = show;
625 }
626 
627 void BoardWidget::matchAnimationTimeout()
628 {
629  if (matchCount == 0) {
630  return;
631  }
632 
633  if (iTimerStep++ & 1) {
634  for (short Pos = 0; Pos < matchCount; Pos++) {
635  hilightTile(Game->getFromPosTable(Pos), true);
636  }
637  } else {
638  for (short Pos = 0; Pos < matchCount; Pos++) {
639  hilightTile(Game->getFromPosTable(Pos), false);
640  }
641  }
642 
643  if (TimerState == Match) {
644  QTimer::singleShot(ANIMSPEED, this, SLOT(matchAnimationTimeout()));
645  }
646 }
647 
648 void BoardWidget::stopMatchAnimation()
649 {
650  for (short Pos = 0; Pos < matchCount; Pos++) {
651  hilightTile(Game->getFromPosTable(Pos), false);
652  }
653 
654  TimerState = Stop;
655  matchCount = 0;
656 }
657 
658 void BoardWidget::redoMove()
659 {
660  Game->setRemovedTilePair(Game->MoveListData(Game->TileNum - 1), Game->MoveListData(Game->TileNum
661  - 2));
662  removeTile(Game->MoveListData(Game->TileNum - 1), false);
663  removeTile(Game->MoveListData(Game->TileNum - 1));
664  drawTileNumber();
665 }
666 
667 void BoardWidget::animateMoveList()
668 {
669  setStatusText(i18n("Congratulations. You have won!"));
670  animatingMoveListForward();
671 }
672 
673 void BoardWidget::animatingMoveListForward()
674 {
675  if (Game->TileNum < Game->MaxTileNum) {
676  // put back all tiles
677  putTileInBoard(Game->MoveListData(Game->TileNum));
678  Game->TileNum++;
679  putTileInBoard(Game->MoveListData(Game->TileNum), false);
680  Game->TileNum++;
681  drawTileNumber();
682  animateForwardTimer->start(); //it is a single shot timer
683  } else {
684  //start removal
685  animateBackwardsTimer->start(); //it is a single shot timer
686  }
687 }
688 
689 void BoardWidget::animatingMoveListBackwards()
690 {
691  if (Game->TileNum > 0) {
692  // remove all tiles
693  removeTile(Game->MoveListData(Game->TileNum - 1), false);
694  removeTile(Game->MoveListData(Game->TileNum - 1));
695  drawTileNumber();
696  animateBackwardsTimer->start(); //it is a single shot timer
697  } else {
698  //end of animation
699  stopEndAnimation();
700  }
701 }
702 
703 void BoardWidget::stopEndAnimation()
704 {
705  animateForwardTimer->stop();
706  animateBackwardsTimer->stop();
707 }
708 
709 QString BoardWidget::getRandomLayoutName() const
710 {
711  QStringList tilesAvailable = KGlobal::dirs()->findAllResources("kmahjongglayout",
712  QString("*.desktop"), KStandardDirs::Recursive);
713 
714  return tilesAvailable.at(qrand() % tilesAvailable.size());
715 }
716 
717 void BoardWidget::calculateNewGame(int gNumber)
718 {
719  cancelUserSelectedTiles();
720  stopMatchAnimation();
721  stopEndAnimation();
722  Game->initialiseRemovedTiles();
723 
724  // If random layout is true, we will create a new random layout from the existing layouts.
725  if (Prefs::randomLayout()) {
726  QString layoutName = getRandomLayoutName();
727  loadBoardLayout(layoutName);
728  }
729 
730  setStatusText(i18n("Calculating new game..."));
731 
732  if (!loadBoard()) {
733  setStatusText(i18n("Error converting board information!"));
734 
735  return;
736  }
737 
738  if (gNumber == -1) {
739  gameGenerationNum = KRandom::random();
740  } else {
741  gameGenerationNum = gNumber;
742  }
743 
744  Game->random.setSeed(gameGenerationNum);
745 
746  // Translate Game->Map to an array of POSITION data. We only need to
747  // do this once for each new game.
748  Game->generateTilePositions();
749 
750  // Now use the tile position data to generate tile dependency data.
751  // We only need to do this once for each new game.
752  Game->generatePositionDepends();
753 
754  // Now try to position tiles on the board, 64 tries max.
755  for (short nr = 0; nr < 64; nr++) {
756  if (Game->generateStartPosition2()) {
757  drawBoard(true);
758  setStatusText(i18n("Ready. Now it is your turn."));
759  cheatsUsed = 0;
760  emit gameCalculated();
761 
762  return;
763  }
764  }
765 
766  drawBoard(false);
767  setStatusText(i18n("Error generating new game!"));
768 }
769 
770 void BoardWidget::hilightTile(POSITION& Pos, bool on, bool doRepaint)
771 {
772  TileSprite *atile = 0;
773  TileCoord coord = TileCoord(Pos.x, Pos.y, Pos.e);
774 
775  if (spriteMap.contains(coord)) {
776  atile = spriteMap.value(coord);
777  }
778 
779  if (on) {
780  Game->setHighlightData(Pos.e, Pos.y, Pos.x, 1);
781  if (atile) {
782  atile->setSelected(true);
783  }
784  } else {
785  Game->setHighlightData(Pos.e, Pos.y, Pos.x, 0);
786  if (atile) {
787  atile->setSelected(false);
788  }
789  }
790 }
791 
792 void BoardWidget::drawBoard(bool showTiles)
793 {
794  if (gamePaused) {
795  showTiles = false;
796  }
797 
798  if (showTiles) {
799  populateSpriteMap();
800  drawTileNumber();
801  } else {
802  //Delete previous sprites
803  while (!items()->isEmpty()) {
804  delete items()->first();
805  }
806 
807  //Clear our spritemap as well
808  spriteMap.clear();
809 
810  //Recreate our background
811  QPalette palette;
812  palette.setBrush(backgroundRole(), theBackground.getBackground());
813  setPalette(palette);
814  setAutoFillBackground(true);
815  }
816 }
817 
818 void BoardWidget::putTileInBoard(POSITION& Pos, bool doRepaint)
819 {
820  short E = Pos.e;
821  short Y = Pos.y;
822  short X = Pos.x;
823 
824  // we ensure that any tile we put on has highlighting off
825  Game->putTile(E, Y, X, Pos.f);
826  Game->setHighlightData(E, Y, X, 0);
827 
828  QPixmap s;
829  QPixmap us;
830  QPixmap f;
831  s = theTiles.selectedTile(m_angle);
832  us = theTiles.unselectedTile(m_angle);
833  f = theTiles.tileface(Game->BoardData(E, Y, X) - TILE_OFFSET);
834  TileSprite *thissprite = new TileSprite(this, us, s, f, m_angle, false);
835  thissprite->show();
836  spriteMap.insert(TileCoord(X, Y, E), thissprite);
837 
838  updateSpriteMap();
839 }
840 
841 void BoardWidget::removeTile(POSITION& Pos, bool doRepaint)
842 {
843  short E = Pos.e;
844  short Y = Pos.y;
845  short X = Pos.x;
846 
847  Game->TileNum--; // Eine Figur weniger
848  Game->setMoveListData(Game->TileNum,Pos); // Position ins Protokoll eintragen
849 
850  delete spriteMap.take(TileCoord(X,Y,E));
851 
852  // remove tile from game board
853  Game->putTile(E, Y, X, 0);
854 }
855 
856 void BoardWidget::mousePressEvent(QMouseEvent *event)
857 {
858  if (gamePaused) {
859  return;
860  }
861 
862  if (event->button() == Qt::LeftButton) {
863  if (TimerState == Demo) {
864  stopDemoMode();
865  } else if (showMatch) {
866  stopMatchAnimation();
867  }
868 
869  if (showHelp) { // stop hilighting tiles
870  helpMoveStop();
871  }
872 
873  if (MouseClickPos1.e == Game->m_depth) { // first tile
874  transformPointToPosition(event->pos(), MouseClickPos1);
875 
876  if (MouseClickPos1.e != Game->m_depth && showMatch) {
877  matchCount = Game->findAllMatchingTiles(MouseClickPos1);
878  TimerState = Match;
879  iTimerStep = 1;
880  matchAnimationTimeout();
881  cheatsUsed++;
882  }
883  } else { // second tile
884  transformPointToPosition(event->pos(), MouseClickPos2);
885  if (MouseClickPos2.e == Game->m_depth) {
886  cancelUserSelectedTiles();
887  } else {
888  if (Game->isMatchingTile(MouseClickPos1, MouseClickPos2)) {
889  // update the removed tiles (we do this before the remove below
890  // so that we only require 1 screen paint for both actions)
891  Game->setRemovedTilePair(MouseClickPos1, MouseClickPos2);
892 
893  // now we remove the tiles from the board*t,
894  removeTile(MouseClickPos1, false);
895  removeTile(MouseClickPos2);
896 
897  // removing a tile means redo is impossible without
898  // a further undo.
899  Game->allow_redo = false;
900  demoModeChanged(false);
901  drawTileNumber();
902 
903  // if no tiles are left, the player has `won`, so celebrate
904  if (Game->TileNum == 0) {
905  gameOver(Game->MaxTileNum,cheatsUsed);
906  } else {
907  // else if no more moves are possible, display the sour grapes dialog
908  validMovesAvailable();
909  }
910  } else {
911  // redraw tiles in normal state
912  hilightTile(MouseClickPos1, false, false);
913  hilightTile(MouseClickPos2, false);
914  }
915 
916  MouseClickPos1.e = Game->m_depth; // mark tile position as invalid
917  MouseClickPos2.e = Game->m_depth;
918  }
919  }
920  }
921 }
922 
923 KGameCanvasItem* BoardWidget::itemAt(const QPoint& point) const
924 {
925  // Get the shadows...
926  // theTiles.width() == The whole tile width including offset and shadow.
927  // theTiles.qWidth() == Half of the width of the tile face (without the offset and the shadow).
928  // theTiles.levelOffsetX() == The level of the tile (the perspective height of the tile)
929  int shadowWidth = theTiles.width() - (theTiles.qWidth() * 2 + theTiles.levelOffsetX());
930  int shadowHeight = theTiles.height() - (theTiles.qHeight() * 2 + theTiles.levelOffsetY());
931 
932  for (int i = m_items.size() - 1; i >= 0; i--) {
933  KGameCanvasItem *canvasItem = m_items[i];
934 
935  // Cause of the shadow, that is not really a part of a tile. Correct the rect positions
936  // related to the angle. Actually we just correct the rect of the canvas item cause of the
937  // shadow, that is not part of the clickable tile.
938  QRect oldRect = canvasItem->rect();
939  QRect rectCorrection = oldRect;
940 
941  // Correct the positions related to the angle we had set.
942  switch (m_angle) {
943  case NW:
944  rectCorrection.setRect(oldRect.x() + shadowWidth, oldRect.y(),
945  oldRect.width() - shadowWidth, oldRect.height() - shadowHeight);
946  break;
947  case NE:
948  rectCorrection.setRect(oldRect.x(), oldRect.y(), oldRect.width() - shadowWidth,
949  oldRect.height() - shadowHeight);
950  break;
951  case SW:
952  rectCorrection.setRect(oldRect.x() + shadowWidth, oldRect.y() + shadowHeight,
953  oldRect.width() - shadowWidth, oldRect.height() - shadowHeight);
954  break;
955  case SE:
956  rectCorrection.setRect(oldRect.x(), oldRect.y() + shadowHeight,
957  oldRect.width() - shadowWidth, oldRect.height() - shadowHeight);
958  break;
959  }
960 
961  // if the canvas is visible and we click inside the corrected rect of the canvas item, we
962  // can return the actual canvas item.
963  if (canvasItem->visible() && rectCorrection.contains(point)) {
964  return canvasItem;
965  }
966  }
967 
968  return NULL;
969 }
970 
971 void BoardWidget::transformPointToPosition(const QPoint &point, POSITION &MouseClickPos)
972 {
973  int E;
974  int X;
975  int Y;
976 
977  TileSprite *clickedItem = NULL;
978  clickedItem = (TileSprite *) itemAt(point);
979 
980  if (!clickedItem) {
981  //no item under mouse
982  qDebug() << "no tile registered";
983 
984  return;
985  }
986 
987  TileCoord coord = spriteMap.key(clickedItem);
988  E = coord.z();
989  X = coord.x();
990  Y = coord.y();
991 
992  //sanity checking
993  if (X < 0 || X >= Game->m_width || Y < 0 || Y >= Game->m_height) {
994  return;
995  }
996 
997  // if gameboard is empty, skip
998  //sanity checking
999  if (!Game->BoardData(E, Y, X)) {
1000  qDebug() << "Tile not in BoardData. Fading out?";
1001 
1002  return;
1003  }
1004 
1005  // tile must be 'free' (nothing left, right or above it)
1006  //Optimization, skip "over" test for the top layer
1007  if (E < Game->m_depth - 1) {
1008  if (Game->BoardData(E + 1, Y, X)
1009  || (Y < Game->m_height - 1 && Game->BoardData(E + 1, Y + 1, X))
1010  || (X < Game->m_width - 1 && Game->BoardData(E + 1, Y, X + 1))
1011  || (X < Game->m_width - 1 && Y < Game->m_height - 1
1012  && Game->BoardData(E + 1, Y + 1, X + 1))) {
1013  return;
1014  }
1015  }
1016 
1017  // No left test on left edge
1018  if (( X > 0) && (Game->BoardData(E, Y, X - 1) || Game->BoardData(E, Y + 1, X - 1))) {
1019  if ((X < Game->m_width - 2)
1020  && (Game->BoardData(E, Y, X + 2) || Game->BoardData(E, Y + 1, X + 2))) {
1021  return;
1022  }
1023  }
1024 
1025  // if we reach here, position is legal
1026  MouseClickPos.e = E;
1027  MouseClickPos.y = Y;
1028  MouseClickPos.x = X;
1029  MouseClickPos.f = Game->BoardData(E, Y, X);
1030 
1031  // give visible feedback
1032  hilightTile( MouseClickPos );
1033 }
1034 
1035 bool BoardWidget::loadBoard( )
1036 {
1037  delete Game;
1038  Game = new GameData(theBoardLayout.board());
1039 
1040  return true;
1041 }
1042 
1043 void BoardWidget::setStatusText(const QString &pszText)
1044 {
1045  emit statusTextChanged(pszText, gameGenerationNum);
1046 }
1047 
1048 bool BoardWidget::loadBackground(const QString &pszFileName, bool bShowError)
1049 {
1050  if (theBackground.load(pszFileName, requiredWidth(), requiredHeight())) {
1051  if (theBackground.loadGraphics()) {
1052  return true;
1053  }
1054  }
1055 
1056  //Try default
1057  if (theBackground.loadDefault()) {
1058  if (theBackground.loadGraphics()) {
1059  }
1060  }
1061 
1062  return false;
1063 }
1064 
1065 void BoardWidget::drawTileNumber()
1066 {
1067  emit tileNumberChanged(Game->MaxTileNum, Game->TileNum, Game->moveCount());
1068 }
1069 
1070 void BoardWidget::cancelUserSelectedTiles()
1071 {
1072  if (MouseClickPos1.e != Game->m_depth) {
1073  hilightTile(MouseClickPos1, false); // redraw tile
1074  MouseClickPos1.e = Game->m_depth; // mark tile invalid
1075  }
1076 }
1077 
1078 bool BoardWidget::loadTileset(const QString &path)
1079 {
1080  if (theTiles.loadTileset(path)) {
1081  if (theTiles.loadGraphics()) {
1082  resizeTileset(size());
1083 
1084  return true;
1085  }
1086  }
1087 
1088  //Tileset or graphics could not be loaded, try default
1089  if (theTiles.loadDefault()) {
1090  if (theTiles.loadGraphics()) {
1091  resizeTileset(size());
1092  }
1093  }
1094 
1095  return false;
1096 }
1097 
1098 bool BoardWidget::loadBoardLayout(const QString &file)
1099 {
1100  if (theBoardLayout.load(file)) {
1101  return true;
1102  } else {
1103  if (theBoardLayout.loadDefault()) {
1104  return false;
1105  } else {
1106  return false;
1107  }
1108  }
1109 }
1110 
1111 int BoardWidget::requiredHorizontalCells()
1112 {
1113  int res = (Game->m_width / 2);
1114  /*if (Prefs::showRemoved())
1115  res = res + 3; //space for removed tiles*/
1116 
1117  return res;
1118 }
1119 
1120 int BoardWidget::requiredVerticalCells()
1121 {
1122  int res = (Game->m_height / 2);
1123 
1124  return res;
1125 }
1126 
1127 int BoardWidget::requiredWidth()
1128 {
1129  //int res = ((BoardLayout::width+12)* theTiles.qWidth());
1130  int res = width();
1131 
1132  return res;
1133 }
1134 
1135 int BoardWidget::requiredHeight()
1136 {
1137  //int res = ((BoardLayout::height+3)* theTiles.qHeight());
1138  int res = height();
1139 
1140  return res;
1141 }
1142 
1143 void BoardWidget::angleSwitchCCW()
1144 {
1145  switch (m_angle) {
1146  case NW :
1147  m_angle = NE;
1148 
1149  break;
1150 
1151  case NE :
1152  m_angle = SE;
1153 
1154  break;
1155 
1156  case SE :
1157  m_angle = SW;
1158 
1159  break;
1160 
1161  case SW :
1162  m_angle = NW;
1163 
1164  break;
1165  }
1166 
1167  QHashIterator<TileCoord, TileSprite*> i(spriteMap);
1168  while (i.hasNext()) {
1169  i.next();
1170  QPixmap u = theTiles.unselectedTile(m_angle);
1171  QPixmap s = theTiles.selectedTile(m_angle);
1172  i.value()->setAngle(m_angle, u, s);
1173  }
1174 
1175  //re-position and re-layer
1176  updateSpriteMap();
1177 
1178  //save angle
1179  saveSettings();
1180 }
1181 
1182 void BoardWidget::angleSwitchCW()
1183 {
1184  switch (m_angle) {
1185  case NW :
1186  m_angle = SW;
1187 
1188  break;
1189 
1190  case NE :
1191  m_angle = NW;
1192 
1193  break;
1194 
1195  case SE :
1196  m_angle = NE;
1197 
1198  break;
1199 
1200  case SW :
1201  m_angle = SE;
1202 
1203  break;
1204  }
1205 
1206  QHashIterator<TileCoord, TileSprite *> i(spriteMap);
1207  while (i.hasNext()) {
1208  i.next();
1209  QPixmap u = theTiles.unselectedTile(m_angle);
1210  QPixmap s = theTiles.selectedTile(m_angle);
1211  i.value()->setAngle(m_angle, u, s);
1212  }
1213 
1214  //re-position and re-layer
1215  updateSpriteMap();
1216 
1217  //save settings
1218  saveSettings();
1219 }
1220 
1221 void BoardWidget::shuffle()
1222 {
1223  cancelUserSelectedTiles();
1224  Game->shuffle();
1225 
1226  // force a full redraw
1227  populateSpriteMap();
1228 
1229  // I consider this s very bad cheat so, I punish the user
1230  // 300 points per use
1231  cheatsUsed += 15;
1232  drawTileNumber();
1233 
1234  // Test if any moves are available
1235  validMovesAvailable();
1236 }
1237 
1238 bool BoardWidget::validMovesAvailable()
1239 {
1240  if (!Game->findMove(TimerPos1, TimerPos2)) {
1241  KMessageBox::information(this, i18n("Game over: You have no moves left."));
1242 
1243  return false;
1244  }
1245 
1246  return true;
1247 }
1248 
1249 QString BoardWidget::getLayoutName()
1250 {
1251  QString key("Name");
1252 
1253  return theBoardLayout.authorProperty(key);
1254 }
1255 
1256 void BoardWidget::wheelEvent(QWheelEvent *event)
1257 {
1258  if (event->orientation() == Qt::Vertical) {
1259  if (event->delta() > 0) {
1260  angleSwitchCCW();
1261  } else {
1262  angleSwitchCW();
1263  }
1264  }
1265 
1266  event->accept();
1267 }
1268 
1269 
1270 #include "boardwidget.moc"
QTimer::setInterval
void setInterval(int msec)
BoardWidget::Demo
Definition: boardwidget.h:368
QPalette::setBrush
void setBrush(ColorRole role, const QBrush &brush)
BoardWidget::getLayoutName
QString getLayoutName()
Method Description.
Definition: boardwidget.cpp:1249
Prefs::showMatchingTiles
static bool showMatchingTiles()
Get Whether matching tiles are shown.
Definition: prefs.h:144
Prefs::setBackground
static void setBackground(const QString &v)
Set The background to use.
Definition: prefs.h:39
QResizeEvent
QWidget
QHash::insert
iterator insert(const Key &key, const T &value)
KGameCanvasItem
BoardWidget::populateSpriteMap
void populateSpriteMap()
Slot Description.
Definition: boardwidget.cpp:158
GameData::putTile
void putTile(short e, short y, short x, UCHAR f)
Method Description.
Definition: GameData.cpp:51
GameData::generateTilePositions
void generateTilePositions()
Definition: GameData.cpp:143
QHash::key
const Key key(const T &value) const
KGameCanvasWidget
GameData::getFromPosTable
POSITION & getFromPosTable(int index)
Definition: GameData.h:184
GameData::m_height
short m_height
Definition: GameData.h:194
KMahjonggLayout::loadDefault
bool loadDefault()
Definition: kmahjongglayout.cpp:62
QPalette::setColor
void setColor(ColorGroup group, ColorRole role, const QColor &color)
BoardWidget::helpMoveTimeout
void helpMoveTimeout()
Slot Description.
Definition: boardwidget.cpp:508
BoardWidget::drawBoard
void drawBoard(bool showTiles=true)
Slot Description.
Definition: boardwidget.cpp:792
BoardWidget::requiredHeight
int requiredHeight()
Method Description.
Definition: boardwidget.cpp:1135
GameData::generatePositionDepends
void generatePositionDepends()
Definition: GameData.cpp:165
BoardWidget::gameLoaded
void gameLoaded()
Method Description.
Definition: boardwidget.cpp:454
ANIMSPEED
#define ANIMSPEED
Definition: boardwidget.h:43
GameData::initialiseRemovedTiles
void initialiseRemovedTiles()
Definition: GameData.cpp:871
BoardWidget::m_angle
TileViewAngle m_angle
Definition: boardwidget.h:127
QHashIterator::hasNext
bool hasNext() const
BoardWidget::transformPointToPosition
void transformPointToPosition(const QPoint &point, POSITION &MouseClickPos)
Transform window point to board position.
Definition: boardwidget.cpp:971
BoardWidget::animateBackwardsTimer
QTimer * animateBackwardsTimer
Definition: boardwidget.h:376
BoardWidget::validMovesAvailable
bool validMovesAvailable()
This method test if any valid moves are available.
Definition: boardwidget.cpp:1238
QList::at
const T & at(int i) const
pos::e
USHORT e
Member Description.
Definition: KmTypes.h:36
BoardWidget::setShowMatch
void setShowMatch(bool show)
Method Description.
Definition: boardwidget.cpp:618
KMahjonggLayout::load
bool load(const QString &file)
Definition: kmahjongglayout.cpp:76
QWheelEvent
BoardWidget::setStatusText
void setStatusText(const QString &)
Method Description.
Definition: boardwidget.cpp:1043
BoardWidget::setDisplayedWidth
void setDisplayedWidth()
Slot Description.
Definition: boardwidget.cpp:151
BoardWidget::calculateNewGame
void calculateNewGame(int num=-1)
Method Description.
Definition: boardwidget.cpp:717
BoardWidget::putTileInBoard
void putTileInBoard(POSITION &, bool refresh=true)
Method Description.
Definition: boardwidget.cpp:818
BoardWidget::gameGenerationNum
long gameGenerationNum
Definition: boardwidget.h:357
BoardWidget::timer
QTimer * timer
Definition: boardwidget.h:374
GameData::m_depth
short m_depth
Definition: GameData.h:195
BoardWidget::saveSettings
void saveSettings()
Slot Description.
Definition: boardwidget.cpp:142
QRect::height
int height() const
BoardWidget::shuffle
void shuffle()
Slot Description.
Definition: boardwidget.cpp:1221
QRect::x
int x() const
QRect::y
int y() const
QPoint
prefs.h
QMouseEvent
NE
North East.
Definition: KmTypes.h:59
BoardWidget::angleSwitchCW
void angleSwitchCW()
Slot Description.
Definition: boardwidget.cpp:1182
BoardWidget::theBackground
KMahjonggBackground theBackground
Definition: boardwidget.h:130
QList::size
int size() const
GameData::clearRemovedTilePair
void clearRemovedTilePair(POSITION &a, POSITION &b)
Definition: GameData.cpp:824
GameData::setMoveListData
void setMoveListData(short i, POSITION &value)
Method Description.
Definition: GameData.cpp:134
BoardWidget::matchCount
short matchCount
Definition: boardwidget.h:351
TileCoord
This class implements.
Definition: TileCoord.h:34
TileCoord::y
int y() const
Method description.
Definition: TileCoord.h:154
Prefs::self
static Prefs * self()
Definition: prefs.cpp:17
BoardWidget::loadBackground
bool loadBackground(const QString &, bool bShowError=true)
Slot Description.
Definition: boardwidget.cpp:1048
GameData::MoveListData
POSITION & MoveListData(short i)
Method Description.
Definition: GameData.cpp:124
TileViewAngle
TileViewAngle
Tile angles for face composition.
Definition: KmTypes.h:57
QRect
GameData::generateStartPosition2
bool generateStartPosition2()
Definition: GameData.cpp:549
pos::x
USHORT x
Member Description.
Definition: KmTypes.h:38
BoardWidget::Game
GameData * Game
Definition: boardwidget.h:128
BoardWidget::spriteMap
QHash< TileCoord, TileSprite * > spriteMap
Definition: boardwidget.h:133
BoardWidget::cheatsUsed
unsigned short cheatsUsed
Definition: boardwidget.h:356
BoardWidget::helpMove
void helpMove()
Slot Description.
Definition: boardwidget.cpp:493
QTimer
BoardWidget::resizeTileset
void resizeTileset(const QSize &wsize)
Slot Description.
Definition: boardwidget.cpp:133
BoardWidget::gameCalculated
void gameCalculated()
Signal Description.
TileSprite::setSelected
void setSelected(bool enabled)
Method Description.
Definition: TileSprite.h:94
BoardWidget::hilightTile
void hilightTile(POSITION &, bool on=true, bool refresh=true)
Method Description.
Definition: boardwidget.cpp:770
QWheelEvent::orientation
Qt::Orientation orientation() const
BoardWidget::angleSwitchCCW
void angleSwitchCCW()
Slot Description.
Definition: boardwidget.cpp:1143
BoardWidget::BoardWidget
BoardWidget(QWidget *parent=0)
Class Constructor.
Definition: boardwidget.cpp:34
BoardWidget::statusTextChanged
void statusTextChanged(const QString &, long)
Signal Description.
BoardWidget::removeTile
void removeTile(POSITION &, bool refresh=true)
Method Description.
Definition: boardwidget.cpp:841
GameData::BoardData
UCHAR BoardData(short z, short y, short x)
Method Description.
Definition: GameData.cpp:104
QMouseEvent::button
Qt::MouseButton button() const
Prefs::randomLayout
static bool randomLayout()
Get Whether a random layout is chosen on startup.
Definition: prefs.h:106
BoardWidget::iTimerStep
int iTimerStep
Definition: boardwidget.h:349
BoardWidget::cancelUserSelectedTiles
void cancelUserSelectedTiles()
Method Description.
Definition: boardwidget.cpp:1070
QHashIterator
BoardWidget::~BoardWidget
~BoardWidget()
Class Destructor.
Definition: boardwidget.cpp:81
BoardWidget::requiredHorizontalCells
int requiredHorizontalCells()
Method Description.
Definition: boardwidget.cpp:1111
GameData::allow_redo
int allow_redo
Definition: GameData.h:187
KMahjonggLayout::path
QString path() const
Definition: kmahjongglayout.cpp:123
BoardWidget::tileNumberChanged
void tileNumberChanged(int iMaximum, int iCurrent, int iLeft)
Signal Description.
boardwidget.h
BoardWidget::Match
Definition: boardwidget.h:371
BoardWidget::animateMoveList
void animateMoveList()
Method Description.
Definition: boardwidget.cpp:667
BoardWidget::startDemoMode
void startDemoMode()
Method Description.
Definition: boardwidget.cpp:536
BoardWidget::showMatch
bool showMatch
Definition: boardwidget.h:352
QEvent::spontaneous
bool spontaneous() const
SW
South West.
Definition: KmTypes.h:61
Prefs::setTileSet
static void setTileSet(const QString &v)
Set The tile-set to use.
Definition: prefs.h:20
QRect::contains
bool contains(const QPoint &point, bool proper) const
BoardWidget::loadSettings
void loadSettings()
Slot Description.
Definition: boardwidget.cpp:86
QString
KMahjonggLayout::authorProperty
QString authorProperty(const QString &key) const
Definition: kmahjongglayout.cpp:127
Prefs::setLayout
static void setLayout(const QString &v)
Set The layout of the tiles.
Definition: prefs.h:58
BoardWidget::pause
void pause()
Method Description.
Definition: boardwidget.cpp:448
GameData::MaxTileNum
USHORT MaxTileNum
Definition: GameData.h:190
BoardWidget::requiredVerticalCells
int requiredVerticalCells()
Method Description.
Definition: boardwidget.cpp:1120
QStringList
BoardWidget::mousePressEvent
void mousePressEvent(QMouseEvent *)
Method Description.
Definition: boardwidget.cpp:856
BoardWidget::drawTileNumber
void drawTileNumber()
Method Description.
Definition: boardwidget.cpp:1065
QPixmap
pos::y
USHORT y
Member Description.
Definition: KmTypes.h:37
GameData::TileNum
USHORT TileNum
Definition: GameData.h:189
Prefs::setAngle
static void setAngle(int v)
Set Angle.
Definition: prefs.h:77
QHash::clear
void clear()
QHash::value
const T value(const Key &key) const
BoardWidget::TimerState
enum BoardWidget::STATES TimerState
TileCoord::z
int z() const
Method description.
Definition: TileCoord.h:157
QResizeEvent::size
const QSize & size() const
QHashIterator::next
Item next()
QSize
GameData::moveCount
int moveCount()
Definition: GameData.cpp:951
pos
struct pos POSITION
Definition: KmTypes.h:34
Prefs::tileSet
static QString tileSet()
Get The tile-set to use.
Definition: prefs.h:30
BoardWidget::updateSpriteMap
void updateSpriteMap()
Slot Description.
Definition: boardwidget.cpp:208
GameData::findAllMatchingTiles
short findAllMatchingTiles(POSITION &posA)
Definition: GameData.cpp:1005
QTimer::stop
void stop()
BoardWidget::animateForwardTimer
QTimer * animateForwardTimer
Definition: boardwidget.h:375
BoardWidget::MouseClickPos2
POSITION MouseClickPos2
Definition: boardwidget.h:360
GameData::tilePresent
bool tilePresent(int z, int y, int x)
Method Description.
Definition: GameData.cpp:59
TileCoord::x
int x() const
Method description.
Definition: TileCoord.h:151
BoardWidget::helpMoveStop
void helpMoveStop()
Slot Description.
Definition: boardwidget.cpp:527
QWheelEvent::delta
int delta() const
BoardWidget::stopMatchAnimation
void stopMatchAnimation()
Method Description.
Definition: boardwidget.cpp:648
BoardWidget::matchAnimationTimeout
void matchAnimationTimeout()
Slot Description.
Definition: boardwidget.cpp:627
BoardWidget::gamePaused
bool gamePaused
Definition: boardwidget.h:354
GameData::isMatchingTile
bool isMatchingTile(POSITION &Pos1, POSITION &Pos2)
Definition: GameData.cpp:762
BoardWidget::showHelp
bool showHelp
Definition: boardwidget.h:353
TileSprite
This class wraps tile drawing, so it can blit the selected or unselected background, plus the tileface, positioned in the correct orientation.
Definition: TileSprite.h:41
QRect::width
int width() const
QHash::take
T take(const Key &key)
BoardWidget::loadBoardLayout
bool loadBoardLayout(const QString &)
Slot Description.
Definition: boardwidget.cpp:1098
Prefs::angle
static int angle()
Get Angle.
Definition: prefs.h:87
GameData::shuffle
void shuffle()
Definition: GameData.cpp:1098
QRect::setRect
void setRect(int x, int y, int width, int height)
BoardWidget::TimerPos2
POSITION TimerPos2
Definition: boardwidget.h:362
GameData::random
KRandomSequence random
Definition: GameData.h:198
BoardWidget::demoModeChanged
void demoModeChanged(bool bActive)
Signal Description.
BoardWidget::animatingMoveListBackwards
void animatingMoveListBackwards()
Slot Description.
Definition: boardwidget.cpp:689
GameData::findMove
bool findMove(POSITION &posA, POSITION &posB)
Definition: GameData.cpp:884
BoardWidget::gameOver
void gameOver(unsigned short removed, unsigned short cheats)
Signal Description.
BoardWidget::loadBoard
bool loadBoard()
Slot Description.
Definition: boardwidget.cpp:1035
BoardWidget::wheelEvent
virtual void wheelEvent(QWheelEvent *event)
Overridden virtual method for wheel events.
Definition: boardwidget.cpp:1256
GameData::HighlightData
UCHAR HighlightData(short z, short y, short x)
Method Description.
Definition: GameData.cpp:84
GameData::setHighlightData
void setHighlightData(short z, short y, short x, UCHAR value)
Method Description.
Definition: GameData.cpp:94
QTimer::start
void start(int msec)
GameData
This class implements.
Definition: GameData.h:51
BoardWidget::stopEndAnimation
void stopEndAnimation()
Method Description.
Definition: boardwidget.cpp:703
QHash::contains
bool contains(const Key &key) const
BoardWidget::undoMove
int undoMove()
Method Description.
Definition: boardwidget.cpp:470
BoardWidget::resizeEvent
virtual void resizeEvent(QResizeEvent *event)
Virtual Method Description.
Definition: boardwidget.cpp:122
BoardWidget::TimerPos1
POSITION TimerPos1
Definition: boardwidget.h:361
QMouseEvent::pos
const QPoint & pos() const
QHashIterator::value
const T & value() const
Prefs::background
static QString background()
Get The background to use.
Definition: prefs.h:49
GameData::m_width
short m_width
Definition: GameData.h:193
BoardWidget::loadTileset
bool loadTileset(const QString &)
Slot Description.
Definition: boardwidget.cpp:1078
QString::compare
int compare(const QString &other) const
BoardWidget::Stop
Definition: boardwidget.h:367
pos::f
USHORT f
Member Description.
Definition: KmTypes.h:39
BoardWidget::animatingMoveListForward
void animatingMoveListForward()
Slot Description.
Definition: boardwidget.cpp:673
TILE_OFFSET
#define TILE_OFFSET
Definition: KmTypes.h:64
NW
North West.
Definition: KmTypes.h:58
BoardWidget::theTiles
KMahjonggTileset theTiles
Definition: boardwidget.h:129
BoardWidget::redoMove
void redoMove()
Method Description.
Definition: boardwidget.cpp:658
BoardWidget::theBoardLayout
KMahjonggLayout theBoardLayout
Definition: boardwidget.h:131
BoardWidget::itemAt
KGameCanvasItem * itemAt(const QPoint &point) const
Override the itemAt method of the KGameCanvasWidget.
Definition: boardwidget.cpp:923
QPalette
BoardWidget::requiredWidth
int requiredWidth()
Method Description.
Definition: boardwidget.cpp:1127
BoardWidget::demoMoveTimeout
void demoMoveTimeout()
Slot Description.
Definition: boardwidget.cpp:559
BoardWidget::MouseClickPos1
POSITION MouseClickPos1
Definition: boardwidget.h:359
Prefs::layout
static QString layout()
Get The layout of the tiles.
Definition: prefs.h:68
BoardWidget::stopDemoMode
void stopDemoMode()
Method Description.
Definition: boardwidget.cpp:549
SE
South East.
Definition: KmTypes.h:60
KMahjonggLayout::board
BoardLayout * board()
Definition: kmahjongglayout.cpp:119
QTimer::setSingleShot
void setSingleShot(bool singleShot)
GameData::setRemovedTilePair
void setRemovedTilePair(POSITION &a, POSITION &b)
Definition: GameData.cpp:777
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:18:33 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kmahjongg

Skip menu "kmahjongg"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdegames API Reference

Skip menu "kdegames API Reference"
  • granatier
  • kapman
  • kblackbox
  • kgoldrunner
  • kigo
  • kmahjongg
  • KShisen
  • ksquares
  • libkdegames
  •   highscore
  •   libkdegamesprivate
  •     kgame
  • libkmahjongg
  • palapeli
  •   libpala

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal