⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kmahjongg.cpp

📁 四川麻将程序代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        case 4:            hilightTile( TimerPos1, false, false );            hilightTile( TimerPos2, false );            break;	// remove matching tiles from game board        case 5:            setRemovedTilePair(TimerPos1, TimerPos2);	            removeTile( TimerPos1, false );            removeTile( TimerPos2 );            drawTileNumber();            break;    }    // restart timer if demo mode is still active    if( TimerState == Demo )        QTimer::singleShot( ANIMSPEED, this, SLOT( demoMoveTimeout() ) );}// ---------------------------------------------------------void BoardWidget::setShowMatch( bool show ){    if( showMatch )        stopMatchAnimation();    showMatch = show;}// ---------------------------------------------------------void BoardWidget::matchAnimationTimeout(){    if (matchCount == 0)        return;    if( iTimerStep++ & 1 )    {        for(short Pos = 0; Pos < matchCount; Pos++)        {            hilightTile(PosTable[Pos], true);        }    }    else    {        for(short Pos = 0; Pos < matchCount; Pos++)        {            hilightTile(PosTable[Pos], false);        }    }    if( TimerState == Match )        QTimer::singleShot( ANIMSPEED, this, SLOT( matchAnimationTimeout() ) );}// ---------------------------------------------------------void BoardWidget::stopMatchAnimation(){    for(short Pos = 0; Pos < matchCount; Pos++)    {        hilightTile(PosTable[Pos], false);    }    TimerState = Stop;    matchCount = 0;}void BoardWidget::redoMove(void){        		setRemovedTilePair(Game.MoveList[Game.TileNum-1],Game.MoveList[Game.TileNum-2]);        removeTile(Game.MoveList[Game.TileNum-1], false);        removeTile(Game.MoveList[Game.TileNum-1]);        drawTileNumber();}// ---------------------------------------------------------void BoardWidget::animateMoveList(){    setStatusText( i18n("Congratulations. You have won!") );    while( Game.TileNum < Game.MaxTileNum )    {        // put back all tiles        putTile(Game.MoveList[Game.TileNum]);        Game.TileNum++;        putTile(Game.MoveList[Game.TileNum], false);        Game.TileNum++;        drawTileNumber();    }    while( Game.TileNum > 0 )    {        // remove all tiles        removeTile(Game.MoveList[Game.TileNum-1], false);        removeTile(Game.MoveList[Game.TileNum-1]);        drawTileNumber();    }    calculateNewGame();}// ---------------------------------------------------------void BoardWidget::calculateNewGame( int gNumber){    cancelUserSelectedTiles();    initialiseRemovedTiles();    setStatusText( i18n("Calculating new game...") );    if( !loadBoard())    {        setStatusText( i18n("Error converting board information!") );        return;    }    if (gNumber == -1) {    	gameGenerationNum = 0;    } else {	gameGenerationNum = gNumber;    }    random.setSeed(gameGenerationNum);    // try max. 64 times    for( short nr=0; nr<64; nr++ )    {        if( generateStartPosition2() )        {            drawBoard();            setStatusText( i18n("Ready. Now it's your turn.") );			cheatsUsed=0;	    return;        }    }    drawBoard();    setStatusText( i18n("Error generating new game!") );}bool BoardWidget::generateStartPosition2() {	int totalTiles=0;	POSITION tilesLeft[BoardLayout::maxTiles];	memset(tilesLeft, 0, sizeof(tilesLeft));	// zero out all face values		for (int z=0; z< BoardLayout::depth; z++) {	    for (int y=0; y<BoardLayout::height; y++) {		for (int x=0; x<BoardLayout::width; x++) {			Game.Board[z][y][x]=0;			if (Game.Mask[z][y][x] == '1') {				tilesLeft[totalTiles].x = x;						tilesLeft[totalTiles].y = y;						tilesLeft[totalTiles].e = z;				tilesLeft[totalTiles].f = 254;						totalTiles++;			}		}	    }	}	// Initialise the faces to allocate. For the classic	// dragon board there are 144 tiles. So we allocate and	// randomise the assignment of 144 tiles. If there are > 144	// tiles we will reallocate and re-randomise as we run out.	// One advantage of this method is that the pairs to assign are	// non-linear. In kmahjongg 0.4, If there were > 144 the same	// allocation series was followed. So 154 = 144 + 10 rods.	// 184 = 144 + 40 rods (20 pairs) which overwhemed the board	// with rods and made deadlock games more likely.	int remaining = totalTiles;	randomiseFaces();	for (int tile=0; tile <totalTiles; tile+=2) {		int p1;		int p2;		if (remaining > 2) {			p2 = p1 = random.getLong(remaining-2);			int bail = 0;				while (p1 == p2) {				p2 = random.getLong(remaining-2);				if (bail >= 100) {					printf("Bail!\n");					break;				}				if ((tilesLeft[p1].y == tilesLeft[p2].y) &&				    (tilesLeft[p1].e == tilesLeft[p2].e)) {					// skip if on same y line					bail++;					p2=p1;					continue;				}			}		} else {			p1 = 0;			p2 = 1;		}		POSITION a, b;		a = tilesLeft[p1];		b = tilesLeft[p2];		tilesLeft[p1] = tilesLeft[remaining - 1];		tilesLeft[p2] = tilesLeft[remaining - 2];		remaining -= 2;			getFaces(a, b);		Game.putTile(a);		Game.putTile(b);	}    Game.TileNum = Game.MaxTileNum;	return 1;	}void BoardWidget::getFaces(POSITION &a, POSITION &b) {	a.f = tilePair[tilesUsed];	b.f = tilePair[tilesUsed+1];	tilesUsed += 2;	if (tilesUsed >= 144) {		randomiseFaces();	}	}void BoardWidget::randomiseFaces(void) {	int nr;	int numAlloced=0;	// stick in 144 tiles in pairsa.        for( nr=0; nr<9*4; nr++)		tilePair[numAlloced++] = TILE_CHARACTER+(nr/4); // 4*9 Tiles        for( nr=0; nr<9*4; nr++)		tilePair[numAlloced++] = TILE_BAMBOO+(nr/4); // 4*9 Tiles        for( nr=0; nr<9*4; nr++)		tilePair[numAlloced++] = TILE_ROD+(nr/4); // 4*9 Tiles        for( nr=0; nr<4;   nr++)		tilePair[numAlloced++] = TILE_FLOWER+nr;         // 4 Tiles        for( nr=0; nr<4;   nr++)		tilePair[numAlloced++] = TILE_SEASON+nr;         // 4 Tiles        for( nr=0; nr<4*4; nr++)		tilePair[numAlloced++] = TILE_WIND+(nr/4);  // 4*4 Tiles        for( nr=0; nr<3*4; nr++)		tilePair[numAlloced++] = TILE_DRAGON+(nr/4);     // 3*4 Tiles	//randomise. Keep pairs together. Ie take two random	//odd numbers (n,x) and swap n, n+1 with x, x+1	int at=0;	int to=0;	for (int r=0; r<200; r++) {		to=at;		while (to==at) {			to = random.getLong(144);			if ((to & 1) != 0)				to--;		}		UCHAR tmp = tilePair[at];		tilePair[at] = tilePair[to];		tilePair[to] = tmp;		tmp = tilePair[at+1];		tilePair[at+1] = tilePair[to+1];		tilePair[to+1] = tmp;		at+=2;		if (at >= 144)			at =0;	}	tilesAllocated = numAlloced;	tilesUsed = 0;/*	printf("Allocated %d tiles\n",numAlloced);	for (int t=0; t<numAlloced; t++) {		printf("%2.2X ", tilePair[t]);		if ((t % 20) == 19)			printf("\n");	}	printf("\n");*/}// ---------------------------------------------------------bool isFlower( UCHAR Tile ){    return( Tile >= TILE_FLOWER  &&  Tile <=TILE_FLOWER+3 );}bool isSeason( UCHAR Tile ){    return( Tile >= TILE_SEASON  &&  Tile <=TILE_SEASON+3 );}bool isBamboo(UCHAR t) {    return( t >= TILE_BAMBOO && t <TILE_BAMBOO+9);}bool isCharacter(UCHAR t) {    return( t >= TILE_CHARACTER && t <TILE_CHARACTER + 9);}bool isRod(UCHAR t) {    return( t >= TILE_ROD && t <TILE_ROD + 9);}bool isDragon(UCHAR t) {    return( t >= TILE_DRAGON && t < TILE_DRAGON +3);}bool isWind(UCHAR t) {    return( t >= TILE_WIND && t < TILE_WIND +4);}bool BoardWidget::isMatchingTile( POSITION& Pos1, POSITION& Pos2 ){    // don't compare 'equal' positions    if( memcmp( &Pos1, &Pos2, sizeof(POSITION) ) )    {        UCHAR FA = Pos1.f;        UCHAR FB = Pos2.f;        if( (FA == FB)         || ( isFlower( FA ) && isFlower( FB ) )         || ( isSeason( FA ) && isSeason( FB ) ) )            return( true );    }    return( false );}// ---------------------------------------------------------bool BoardWidget::findMove( POSITION& posA, POSITION& posB ){    short Pos_Ende = Game.MaxTileNum;  // Ende der PosTable    for( short E=0; E<BoardLayout::depth; E++ )    {        for( short Y=0; Y<BoardLayout::height-1; Y++ )        {            for( short X=0; X<BoardLayout::width-1; X++ )            {                if( Game.Mask[E][Y][X] != (UCHAR) '1' )                    continue;                if( ! Game.Board[E][Y][X] )                    continue;                if( E < 4 )                {                    if( Game.Board[E+1][Y][X] || Game.Board[E+1][Y+1][X] ||                        Game.Board[E+1][Y][X+1] || Game.Board[E+1][Y+1][X+1] )                        continue;                }                if( (Game.Board[E][Y][X-1] || Game.Board[E][Y+1][X-1]) &&                    (Game.Board[E][Y][X+2] || Game.Board[E][Y+1][X+2]) )                    continue;                Pos_Ende--;                PosTable[Pos_Ende].e = E;                PosTable[Pos_Ende].y = Y;                PosTable[Pos_Ende].x = X;                PosTable[Pos_Ende].f = Game.Board[E][Y][X];            }        }    } //   PosTable[0].e = BoardLayout::depth;  // 1. Paar noch nicht gefunden    iPosCount = 0;  // Hier Anzahl der gefunden Paare merken	    // The new tile layout with non-contiguos horizantle spans    // can lead to huge numbers of matching pairs being exposed.    // we alter the loop to bail out when BoardLayout::maxTiles/2 pairs are found    // (or less);    while( Pos_Ende < Game.MaxTileNum-1 && iPosCount <BoardLayout::maxTiles-2)    {        for( short Pos = Pos_Ende+1; Pos < Game.MaxTileNum; Pos++)        {            if( isMatchingTile(PosTable[Pos], PosTable[Pos_Ende]) )            {		if (iPosCount <BoardLayout::maxTiles-2) {                	PosTable[iPosCount++] = PosTable[Pos_Ende];                	PosTable[iPosCount++] = PosTable[Pos];		}            }        }        Pos_Ende++;    }    if( iPosCount>=2 )    {        random.setSeed(0); // WABA: Why is the seed reset?        short Pos = random.getLong(iPosCount) & -2;  // Gerader Wert        posA = PosTable[Pos];        posB = PosTable[Pos+1];        return( true );    }    else        return( false );}// ---------------------------------------------------------short BoardWidget::findAllMatchingTiles( POSITION& posA ){    short Pos = 0;    for( short E=0; E<BoardLayout::depth; E++ )    {        for( short Y=1; Y<BoardLayout::height-1; Y++ )        {            for( short X=1; X<BoardLayout::width-1; X++ )            {                if( Game.Mask[E][Y][X] != (UCHAR) '1' )                    continue;                if( ! Game.Board[E][Y][X] )                    continue;                if( E < 4 )                {                    if( Game.Board[E+1][Y][X] || Game.Board[E+1][Y+1][X] ||                        Game.Board[E+1][Y][X+1] || Game.Board[E+1][Y+1][X+1] )                        continue;                }                if( (Game.Board[E][Y][X-1] || Game.Board[E][Y+1][X-1]) &&                    (Game.Board[E][Y][X+2] || Game.Board[E][Y+1][X+2]) )                    continue;                PosTable[Pos].e = E;                PosTable[Pos].y = Y;                PosTable[Pos].x = X;                PosTable[Pos].f = Game.Board[E][Y][X];                if( isMatchingTile(posA, PosTable[Pos]) )                    Pos++;            }        }    }    return Pos;}// ---------------------------------------------------------// This function replaces the old method of hilighting by// modifying color 21 to color 20. This was single tileset// specific. We now have two tile faces, one selected one not.void BoardWidget::hilightTile( POSITION& Pos, bool on, bool doRepaint ){	if (on) {		Game.hilighted[Pos.e][Pos.y][Pos.x]=1;	} else {		Game.hilighted[Pos.e][Pos.y][Pos.x]=0;	}	if (doRepaint) {		updateBackBuffer=true;		repaint(0,0,-1,-1, false);	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -