📄 kmahjongg.cpp
字号:
}// ---------------------------------------------------------void BoardWidget::drawBoard(bool ){ updateBackBuffer=true; repaint(0,0,-1,-1,false); drawTileNumber();}// ---------------------------------------------------------void BoardWidget::putTile( POSITION& Pos, bool doRepaint ){ short E=Pos.e; short Y=Pos.y; short X=Pos.x; // we ensure that any tile we put on has highlighting off Game.putTile( E, Y, X, Pos.f ); Game.hilighted[E][Y][X] = 0; if (doRepaint) { updateBackBuffer=true; repaint(0,0,-1,-1, false); }}// ---------------------------------------------------------void BoardWidget::removeTile( POSITION& Pos , bool doRepaint){ short E = Pos.e; short Y = Pos.y; short X = Pos.x; Game.TileNum--; // Eine Figur weniger Game.MoveList[Game.TileNum] = Pos; // Position ins Protokoll eintragen // remove tile from game board Game.putTile( E, Y, X, 0 ); if (doRepaint) { updateBackBuffer=true; repaint(0,0,-1, -1, false); }}// ---------------------------------------------------------void BoardWidget::mousePressEvent ( QMouseEvent* event ){ if (gamePaused) return; if( event->button() == LeftButton ) { if( TimerState == Demo ) { stopDemoMode(); } else if( showMatch ) { stopMatchAnimation(); } if( MouseClickPos1.e == BoardLayout::depth ) // first tile { transformPointToPosition( event->pos(), MouseClickPos1 ); if( MouseClickPos1.e != BoardLayout::depth && showMatch ) { matchCount = findAllMatchingTiles( MouseClickPos1 ); TimerState = Match; iTimerStep = 1; matchAnimationTimeout(); cheatsUsed++; } } else // second tile { transformPointToPosition( event->pos(), MouseClickPos2 ); if( MouseClickPos2.e == BoardLayout::depth ) { cancelUserSelectedTiles(); } else { if( isMatchingTile( MouseClickPos1, MouseClickPos2 ) ) { // update the removed tiles (we do this before the remove below // so that we only require 1 screen paint for both actions) setRemovedTilePair(MouseClickPos1, MouseClickPos2); // now we remove the tiles from the board removeTile(MouseClickPos1, false); removeTile(MouseClickPos2); // removing a tile means redo is impossible without // a further undo. Game.allow_redo=false; demoModeChanged(false); drawTileNumber(); // if no tiles are left, the player has `won`, so celebrate if( Game.TileNum == 0 ) { KMessageBox::information(this, i18n("Game over: You have won!")); animateMoveList(); gameOver(Game.MaxTileNum,cheatsUsed); } // else if no more moves are possible, display the sour grapes dialog else if( ! findMove( TimerPos1, TimerPos2 ) ) { KMessageBox::information(this, i18n("Game over: You have no moves left")); } } else { // redraw tiles in normal state hilightTile( MouseClickPos1, false, false ); hilightTile( MouseClickPos2, false ); } MouseClickPos1.e = BoardLayout::depth; // mark tile position as invalid MouseClickPos2.e = BoardLayout::depth; } } }}// ----------------------------------------------------------/** Transform window point to board position. @param point Input: Point in window coordinates @param MouseClickPos Output: Position in game board*/void BoardWidget::transformPointToPosition( const QPoint& point, POSITION& MouseClickPos ){ short E,X,Y; // iterate over E coordinate from top to bottom for( E=BoardLayout::depth-1; E>=0; E-- ) { // calculate mouse coordiantes --> position in game board // the factor -theTiles.width()/2 must keep track with the // offset for blitting in the print Event (FIX ME) X = ((point.x()-theTiles.width()/2)- (E+1)*theTiles.shadowSize()) / theTiles.qWidth(); Y = ((point.y()-theTiles.height()/2) + E*theTiles.shadowSize()) / theTiles.qHeight(); // changed to allow x == 0 // skip when position is illegal if (X<0 || X>=BoardLayout::width || Y<0 || Y>=BoardLayout::height) continue; // switch( Game.Mask[E][Y][X] ) { case (UCHAR)'3': X--;Y--; break; case (UCHAR)'2': X--; break; case (UCHAR)'4': Y--; break; case (UCHAR)'1': break; default : continue; } // if gameboard is empty, skip if ( ! Game.Board[E][Y][X] ) continue; // tile must be 'free' (nothing left, right or above it) if( E < 4 ) { if( Game.Board[E+1][Y][X] || Game.Board[E+1][Y+1][X] || (X<BoardLayout::width-2 && Game.Board[E+1][Y][X+1]) || (X<BoardLayout::width-2 && Game.Board[E+1][Y+1][X+1]) ) continue; } // No left test on left edge if (( X > 0) && (Game.Board[E][Y][X-1] || Game.Board[E][Y+1][X-1])) { if ((X<BoardLayout::width-2) && (Game.Board[E][Y][X+2] || Game.Board[E][Y+1][X+2])) { continue; } } // here, position is legal MouseClickPos.e = E; MouseClickPos.y = Y; MouseClickPos.x = X; MouseClickPos.f = Game.Board[E][Y][X]; // give visible feedback hilightTile( MouseClickPos ); break; }}// ---------------------------------------------------------bool BoardWidget::loadBoard( ){ GAMEDATA newGame; memset( &newGame, 0, sizeof( newGame ) ); theBoardLayout.copyBoardLayout((UCHAR *) newGame.Mask, newGame.MaxTileNum); Game = newGame; return(true);}// ---------------------------------------------------------void BoardWidget::setStatusText( const QString & pszText ){ emit statusTextChanged( pszText, gameGenerationNum );}// ---------------------------------------------------------bool BoardWidget::loadBackground( const QString& pszFileName, bool bShowError ){ if( ! theBackground.load( pszFileName, requiredWidth(), requiredHeight()) ) { if( bShowError ) KMessageBox::sorry(this, i18n("Failed to load image:\n%1").arg(pszFileName) ); return( false ); } preferences.setBackground(pszFileName); return( true );}// ---------------------------------------------------------void BoardWidget::drawTileNumber(){ emit tileNumberChanged( Game.MaxTileNum, Game.TileNum );}// ---------------------------------------------------------void BoardWidget::cancelUserSelectedTiles(){ if( MouseClickPos1.e != BoardLayout::depth ) { hilightTile( MouseClickPos1, false ); // redraw tile MouseClickPos1.e = BoardLayout::depth; // mark tile invalid }}// ---------------------------------------------------------void BoardWidget::setRemovedTilePair(POSITION &a, POSITION &b) { if (isFlower(a.f)) { removedFlower[a.f-TILE_FLOWER]++; removedFlower[b.f-TILE_FLOWER]++; return; } if (isSeason(a.f)) { removedSeason[a.f-TILE_SEASON]++; removedSeason[b.f-TILE_SEASON]++; return; } if (isCharacter(a.f)) { removedCharacter[a.f - TILE_CHARACTER]+=2; return; } if (isBamboo(a.f)) { removedBamboo[a.f - TILE_BAMBOO]+=2; return; } if (isRod(a.f)) { removedRod[a.f - TILE_ROD]+=2; return; } if (isDragon(a.f)){ removedDragon[a.f - TILE_DRAGON]+=2; return; } if (isWind(a.f)){ removedWind[a.f - TILE_WIND]+=2; return; }}void BoardWidget::clearRemovedTilePair(POSITION &a, POSITION &b) { if (isFlower(a.f)) { removedFlower[a.f-TILE_FLOWER]--; removedFlower[b.f-TILE_FLOWER]--; return; } if (isSeason(a.f)) { removedSeason[a.f-TILE_SEASON]--; removedSeason[b.f-TILE_SEASON]--; return; } if (isCharacter(a.f)) { removedCharacter[a.f - TILE_CHARACTER]-=2; return; } if (isBamboo(a.f)) { removedBamboo[a.f - TILE_BAMBOO]-=2; return; } if (isRod(a.f)){ removedRod[a.f - TILE_ROD]-=2; return; } if (isDragon(a.f)){ removedDragon[a.f - TILE_DRAGON]-=2; return; } if (isWind(a.f)){ removedWind[a.f - TILE_WIND]-=2; return; }}void BoardWidget::initialiseRemovedTiles(void) { for (int pos=0; pos<9; pos++) { removedCharacter[pos]=0; removedBamboo[pos]=0; removedRod[pos]=0; removedDragon[pos %3] = 0; removedFlower[pos % 4] = 0; removedWind[pos % 4] = 0; removedSeason[pos % 4] = 0; }}// ---------------------------------------------------------void BoardWidget::showMessage( const QString& pszText ){ emit message( pszText );}bool BoardWidget::loadTileset(const QString &path) { if (theTiles.loadTileset(path)) { preferences.setTileset(path); return(true); } else { return(false); }}bool BoardWidget::loadBoardLayout(const QString &file) { if (theBoardLayout.loadBoardLayout(file)) { preferences.setLayout(file); return true; } else { return false; }}void BoardWidget::updateScaleMode(void) { theBackground.scaleModeChanged();}// calculate the required window width (board + removed tiles)int BoardWidget::requiredWidth(void) { int res = ((BoardLayout::width+12)* theTiles.qWidth()); return(res);}// calculate the required window height (board + removed tiles)int BoardWidget::requiredHeight(void) { int res = ((BoardLayout::height+3)* theTiles.qHeight()); return(res);}void BoardWidget::tileSizeChanged(void) { theTiles.setScaled(preferences.miniTiles()); theBackground.sizeChanged(requiredWidth(), requiredHeight());}// shuffle the remaining tiles around, useful if a deadlock ocurrs// this is a big cheat so we penalise the user.void BoardWidget::shuffle(void) { int count = 0; // copy positions and faces of the remaining tiles into // the pos table for (int e=0; e<BoardLayout::depth; e++) { for (int y=0; y<BoardLayout::height; y++) { for (int x=0; x<BoardLayout::width; x++) { if (Game.Board[e][y][x] && Game.Mask[e][y][x] == '1') { PosTable[count].e = e; PosTable[count].y = y; PosTable[count].x = x; PosTable[count].f = Game.Board[e][y][x]; count++; } } } } // now lets randomise the faces, selecting 400 pairs at random and // swapping the faces. for (int ran=0; ran < 400; ran++) { int pos1 = random.getLong(count); int pos2 = random.getLong(count); if (pos1 == pos2) continue; BYTE f = PosTable[pos1].f; PosTable[pos1].f = PosTable[pos2].f; PosTable[pos2].f = f; } // put the rearranged tiles back. for (int p=0; p<count; p++) Game.putTile(PosTable[p]); // force a redraw updateBackBuffer=true; repaint(0,0,-1,-1, false); // I consider this s very bad cheat so, I punish the user // 300 points per use cheatsUsed += 15;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -