📄 buraco.cpp
字号:
ignoreNextMsg = true; broadcastMessage (msg.str ()); } playerPile.insertSorted (staple.removeTopCard (), compByNumberWithJokers); } gStatus.startGame = 0; dumpedCard.show (); } if (target == -1U) target = executeMove (player); flipCards2Play (playerPile, pos1Play, pos2Play); return target;}//-----------------------------------------------------------------------------/// Executes a move for the passed player; only one move is made at every/// timer-iteration/// \param player: Actual player/// \returns \c ID for target (32 Bit: Pile << 16 + Position)//-----------------------------------------------------------------------------int Buraco::executeMove (unsigned int player) { TRACE6 ("Buraco::executeMove (player) - " << player); ICardPile& playerPile (hands[player]); // Check if any card can be added to an existing pile if (tablePiles[player & 1].size ()) for (ICardPile::const_iterator p (playerPile.begin ()); p != playerPile.end (); ++p) { TRACE8 ("Buraco::executeMove (unsigned int) - Adding card " << **p << '?'); unsigned int target (cardFitsOnPlayedPile (player, p - playerPile.begin ())); if ((target != -1U) && canDumpCards (player, 1, ((int)target) >> 16)) return target; } // Check for 3 cards belonging to a serie unsigned int i (0); for (; i < playerPile.size (); ++i) { TRACE8 ("Buraco::executeMove (unsigned int) - Analyzing card " << *playerPile[i]); std::map<unsigned int, unsigned int> aPos; // diff, pos std::vector<unsigned int> aOrder; unsigned int nrs (playerPile.getSeries (*playerPile[i], aPos, aOrder, &cardDistance)); // Play found cards (if any) // - Play jokers if there are at least 5 and the team has still the // reserve and the other team has no burraco and the reserve // - Play the bigger of the found matching cards, if there are >= 3 if (isJoker (*playerPile[i]) ? ((((nrs > 4) && reserve[player & 1].size ()) || (nrs > 5)) && ((points[(player + 1) & 1] < 101) || (nrs > 6) || ((hands[(player + 2) % 3].size () > 5) && (hands[(player + 1) % 3].size () > 3)))) : ((nrs > aPos.size ()) ? (nrs > 2) : (aPos.size () > 2))) { unsigned int firstPos (i); if (nrs < aPos.size ()) { firstPos = playerPile.sortColourSerie (aPos, aOrder); nrs = aPos.size (); } if (nrs > 7) nrs = 7; bool canDump (canDumpCards (player, nrs)); if (canDump || (nrs > 5)) { if (!canDump) nrs = 3; if (isJoker (*playerPile[firstPos])) ++unfinishedMonoPiles[player & 1]; // Create new pile with the found cards makeNewPile (player & 1); pos1Play = firstPos; pos2Play = firstPos + nrs - 1; return (tablePiles[player & 1].size () - 1) << 16; } else hands[player].sort (compByNumberWithJokers); } } // Check if all cards in the hand can (and should) be played TRACE8 ("Buraco::executeMove (unsigned int) - Playing all?"); if (!unfinishedMonoPiles[player & 1] && ((points[player & 1] > 100) || (reserve[player & 1].size () && canGetRidOfCards (player)))) { ICardPile::const_iterator ci (playerPile.begin ()); // If pile still has normal cards (no joker) while (!((ci == playerPile.end ()) || isJoker (**ci))) { ICardPile::const_iterator next (playerPile.getFittingCard (**ci, ci + 1, &cardDistance)); if ((next != playerPile.end ()) && isJoker (*playerPile[playerPile.size () - 1])) { TRACE1 ("Buraco::executeMove (unsigned int) - Have two with joker: " << **ci << " and " << **next); int diff (cardDistance (**next, **ci)); Check3 (diff ? (*next)->colour () == (*ci)->colour () : true); if (diff < 0) { Check3 (diff >= -2); playerPile.move (playerPile.size () - 2, next - playerPile.begin ()); playerPile.move (playerPile.size () + ((diff == -2) ? -1 : -2), ci - playerPile.begin ()); } else { Check3 (diff <= 2); playerPile.move (playerPile.size () - 1, next - playerPile.begin ()); playerPile.move (playerPile.size () - 1 - diff, ci - playerPile.begin ()); } // Create a new pile with the found pair and a joker makeNewPile (player & 1); pos1Play = playerPile.size () - 3; pos2Play = playerPile.size () - 1; return (tablePiles[player & 1].size () - 1) << 16; } ++ci; } } // Play all jokers if team has a cerrado, or leave one, if the player has // >= 2 normal cards left. if (playerPile.size () && (points[player & 1] > 100)) { if ((isJoker (*playerPile[playerPile.size () - 1])) && ((playerPile.size () <= 2) || ((!isJoker (*playerPile[1])) || isJoker (*playerPile[playerPile.size () - 2])))) { unsigned int bestPile (-1U); unsigned int size (0); for (std::vector<BuracoPile*>::const_iterator p (tablePiles[player & 1].begin ()); p != tablePiles[player & 1].end (); ++p) { if ((((*p)->size () < 7) && ((*p)->getPosJoker () > 6)) && (((*p)->size () > size) || (((*p)->size () == size) && ((*p)->getPotentialPoints () > tablePiles[player & 1][bestPile]->getPotentialPoints ())) || ((*p)->getPotentialPoints ()) >= 1000)) { bestPile = p - tablePiles[player & 1].begin (); size = (*p)->size (); } } if (bestPile != -1U) { pos1Play = pos2Play = playerPile.size () - 1; unsigned int pos, move; Check3 (bestPile < tablePiles[player & 1].size ()); tablePiles[player & 1][bestPile]->getPosition4Card (*playerPile[playerPile.size () - 1], pos, move); return (bestPile << 16) + pos; } } } if (containsOnlyJoker (playerPile)) if (!reserve[player & 1].empty ()) { addBuraco (player); return executeMove (player); } // No more cards to put down: Find a card to dump TRACE8 ("Buraco::executeMove (unsigned int) - Searching for a card to dump"); for (i = 0; i < playerPile.size () - 1; ++i) { ICardPile::const_iterator p (playerPile.getFittingCard (*playerPile[i], playerPile.begin (), &cardDistance)); if (static_cast<unsigned int> (p - playerPile.begin ()) == i) p = playerPile.getFittingCard (*playerPile[i], ++p, &cardDistance); if (p == playerPile.end ()) break; } while (i && isJoker (*playerPile[i])) // Try to not dump jokers --i; Check3 (i < playerPile.size ()); pos1Play = pos2Play = i; return 0xffff0000;}//-----------------------------------------------------------------------------/// Starts the game by dealing the cards//-----------------------------------------------------------------------------void Buraco::start () { TRACE9 ("Buraco::start ()"); Game::start (); if (pScoreDlg) { unsigned int player; int points; pScoreDlg->getMaxPoints (points, player); if (points >= (int)ENDPOINTS) { delete pScoreDlg; pScoreDlg = NULL; } } pos1Play = pos2Play = 0; target = -1U; if (randomizeCardsToPile (staple)) { for (unsigned int j (0); j < CARDS2DEAL; ++j) { for (unsigned int i (0); i < NUM_PLAYERS; ++i) hands[(i - posServer) & 0x3].setTopCard (staple.removeTopCard ()); for (unsigned int i (0); i < (sizeof (reserve) / sizeof (reserve[0])); ++i) reserve[(i - posServer) & 1].push_back (&staple.removeTopCard ()); } for (unsigned int i (0); i < NUM_PLAYERS; ++i) hands[i].sort (compByNumberWithJokers); for (unsigned int i (1); i < NUM_PLAYERS; ++i) { hands[i].setStyle (ICardPile::QUITE_COMPRESSED); hands[i].setShowOption (ICardPile::SHOWBACK); } dumped.setTopCard (staple.removeTopCard ()); gStatus.startTurn = gStatus.startGame = 1; gStatus.team1Buraco = gStatus.team2Buraco = 0x3; gStatus.pickUpPlayed = 0; points[0] = points[1] = 0; unfinishedMonoPiles[0] = unfinishedMonoPiles[1] = 0; updateInfo (); // Set random startplayer (if not already set) if (startPlayer == -1U) startPlayer = rand () & 0x3; setStartPlayer (); if (getConnectionMgr ().getMode () == YGP::ConnectionMgr::CLIENT) dumped.getTopCard ().hide (); }}//----------------------------------------------------------------------------/// Sets the startplayer; including showing it in the status bar/// \param player: Player to start the game//----------------------------------------------------------------------------void Buraco::setStartPlayer () { if (getConnectionMgr ().getMode () != YGP::ConnectionMgr::CLIENT) { setNextPlayer (startPlayer); broadcastStartPlayer (startPlayer); } if (startPlayer) dumped.getTopCard ().hide (); else dumped.getTopCard ().show (); displayTurn (startPlayer++); startPlayer &= 0x3; makeNextMoves ();}//-----------------------------------------------------------------------------/// Remove cards from everything which can hold them//-----------------------------------------------------------------------------void Buraco::clean () { TRACE9 ("Buraco::clean ()"); disableHuman (); for (unsigned int i (0); i < NUM_PLAYERS; ++i) hands[i].clear (); staple.clear (); dumped.clear (); for (unsigned int i (0); i < (NUM_PLAYERS >> 1); ++i) { for (std::vector<BuracoPile*>::iterator p (tablePiles[i].begin ()); p != tablePiles[i].end (); ++p) { boxTeam[i].remove (**p); delete *p; } tablePiles[i].clear (); } for (unsigned int i (0); i < (sizeof (reserve) / sizeof (reserve[0])); ++i) reserve[i].clear (); Game::clean ();}//-----------------------------------------------------------------------------/// Enables the cards the human can pick up./// \returns \c 0//-----------------------------------------------------------------------------bool Buraco::enableHuman () { Check3 (!stapleTop.connected ()); Check3 (!dumpedTop.connected ()); if (staple.size ()) stapleTop = staple.getTopCard ().signal_clicked ().connect (mem_fun (*this, (&Buraco::stapleSelected))); if (dumped.size ()) dumpedTop = dumped.getTopCard ().signal_clicked ().connect (mem_fun (*this, (&Buraco::dumpedSelected))); return Game::enableHuman ();}//-----------------------------------------------------------------------------/// Enables the cards in the hand of the human player//-----------------------------------------------------------------------------void Buraco::enableHumanHand () { Check1 (activeCards.empty ()); Check1 (gameStatus () == PLAYING); Check3 (hands[0].size ()); for (unsigned int i (0); i < hands[0].size (); ++i) { registerHandDND (i); enableCard (i); } Check3 (aDNDHand.size () == hands[0].size ()); TRACE2 ("Buraco::enableHuman () - Human has " << hands[0].size () << " cards"); newPile.drag_dest_set (dndType, Gtk::DEST_DEFAULT_ALL, Gdk::ACTION_MOVE); aDNDTable[NULL] = newPile.signal_drag_data_received ().connect (bind (mem_fun (*this, &Buraco::cardDroppedOnTable), -1U)); for (unsigned int i (0); i < tablePiles[0].size (); ++i) { Check3 (tablePiles[0][i]); for (unsigned int j (0); j < tablePiles[0][i]->size (); ++j) registerTableDND (*(*tablePiles[0][i])[j], (i << 8) + j); } if (acceptCards == -1U) { menuSort->set_sensitive (); menuSort2->set_sensitive (); }}//-----------------------------------------------------------------------------/// Disables the cards the human player can select//-----------------------------------------------------------------------------void Buraco::disableHuman () { TRACE2 ("Buraco::disableHuman () - DND: " << aDNDHand.size () << "; " << aDNDTable.size ()); Game::disableHuman ();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -