📄 sgtmayor.cpp
字号:
if (playColour != pTrump->colour ()) bfColours |= (1 << playColour); } } if (getConnectionMgr ().getMode () != YGP::ConnectionMgr::NONE) { // Send played card to all clients (if any) std::ostringstream msg; msg << "Play=" << selCard.id () << ";Target=0"; if (getConnectionMgr ().getMode () == YGP::ConnectionMgr::CLIENT) ignoreNextMsg = true; broadcastMessage (msg.str ()); } unsigned int player (playCard (0, iCard)); if (player != -1U) { setNextPlayer (convertPlayer (player)); makeNextMoves (); } else disableHuman ();}//-----------------------------------------------------------------------------/// Callback after clicking on a card to select the special colour/// \param iCard: Offset of card in hand//-----------------------------------------------------------------------------void SgtMayor::cardColourSelect (unsigned int iCard) { TRACE5 ("SgtMayor::cardColourSelect (unsigned int) - Position " << iCard); Check1 (iCard < players[0].hand.size ()); Check2 (gameStatus () == PLAYING); showTrump (players[0].hand[iCard]->colour ()); disableHuman (); makeNextMoves ();}//-----------------------------------------------------------------------------/// Callback after clicking on a card to exchange bad cards with good ones/// \param iCard: Offset of card in hand//-----------------------------------------------------------------------------void SgtMayor::cardExchange (unsigned int iCard) { TRACE5 ("SgtMayor::cardExchange (unsigned int) - Position " << iCard); Check3 (diffTicks[0]); for (unsigned int i (1); i < NUM_PLAYERS; ++i) { if (diffTicks[i] < 0) { exchangeCards (0, iCard, i); break; } } disableHuman ();}//-----------------------------------------------------------------------------/// Selects the trump/// \returns bool: False, if a human must exchange the two of spades//-----------------------------------------------------------------------------bool SgtMayor::selectTrump () { TRACE9 ("SgtMayor::selectTrump ()"); Glib::ustring stat; unsigned int trumpPlayer ((startPlayer + 2) % 3); if (trumpPlayer) { unsigned int displayPlayer (convertPlayer (startPlayer)); TRACE9 ("SgtMayor::selectTrump () - Trumpplayer: " << trumpPlayer); if (typeid (*actPlayers[trumpPlayer]) == typeid (RemotePlayer)) { status.pop (); stat = _("Waiting for %1 to select the special colour ..."); stat.replace (stat.find ("%1"), 2, actPlayers[displayPlayer]->getName ()); status.push (stat); } else { Check3 (typeid (*actPlayers[trumpPlayer]) == typeid (ComputerPlayer)); // Find special colour ICardPile& pile (players[trumpPlayer].hand); int number[] = { 0, 0, 0, 0 }; int points[] = { 0, 0, 0, 0 }; for (unsigned int i (0); i < (pile.size () - 1); ++i) { ++number[pile[i]->colour ()]; points[pile[i]->colour ()] += pile[i]->number () + 1; } unsigned int trumpColour (0); for (unsigned int i (1); i < 4; ++i) { if ((number[i] > number[i - 1]) || ((number[i] == number[i - 1]) && (points[i] > points[i - 1]))) trumpColour = i; } showTrump ((CardWidget::COLOURS)trumpColour); displayTurn (displayPlayer, stat); } } else { status.pop (); stat = _("Select the special colour"); status.push (stat); for (int i (players[0].hand.size () - 1); i >= 0; --i) activeCards.push_back (players[0].hand[i]->signal_clicked ().connect (bind (mem_fun (*this, (&SgtMayor::cardColourSelect)), i))); return false; } return true;}//-----------------------------------------------------------------------------/// Starts the playing phase of the game//-----------------------------------------------------------------------------void SgtMayor::startPlaying () { TRACE7 ("SgtMayor::startPlaying ()"); Check3 (!diffTicks[0]); Check3 (!diffTicks[1]); Check3 (!diffTicks[2]); playedCards[CardWidget::SPADES].set (CardWidget::TWO); setNextPlayer (convertPlayer (startPlayer)); if (selectTrump ()) makeNextMoves ();}//-----------------------------------------------------------------------------/// Searches for the card to play/// \param player: Player to inspect//-----------------------------------------------------------------------------unsigned int SgtMayor::findPos2Play (unsigned int player) { TRACE8 ("SgtMayor::findPos2Play (unsigned int) - Player " << player); Check1 (player < NUM_PLAYERS); Check2 (pTrump); unsigned int pos (0); ICardPile& pile (players[player].hand); // Get the number of cards of each colour unsigned int cColours[] = { 0, 0, 0, 0 }; unsigned int posColours[] = { -1U, -1U, -1U, -1U }; for (unsigned int i (0); i < (pile.size () - 1); ++i) { ++cColours[pile[i]->colour ()]; if (pile[i]->colour () != pile[i + 1]->colour ()) posColours[pile[i]->colour ()] = i; } posColours[pile[pile.size () - 1]->colour ()] = pile.size () - 1; ++cColours[pile[pile.size () - 1]->colour ()]; TRACE8 ("SgtMayor::findPos2Play (unsigned int) - Nr: " << cColours[0] << '/' << cColours[1] << '/' << cColours[2] << '/' << cColours[3]); TRACE9 ("SgtMayor::findPos2Play (unsigned int) - Pos: " << (int)posColours[0] << '/' << (int)posColours[1] << '/' << (int)posColours[2] << '/' << (int)posColours[3]); TRACE9 ("SgtMayor::findPos2Play (unsigned int) - Out: " << std::hex << (int)bfColours << std::dec); switch (played.size ()) { case 0: { // - Play trumps? Check3 (pTrump); unsigned int trumpsLeft (13 - playedCards[pTrump->colour ()].count ()); TRACE8 ("SgtMayor::findPos2Play (unsigned int) - Trumps: " << trumpsLeft << '/' << playedCards[pTrump->colour ()].count ()); Check3 (trumpsLeft <= 13); // If others have trumps left, but we have more; if player is not the // startplayer, assume, that the 3rd player has no more trumps left if ((trumpsLeft > cColours[pTrump->colour ()]) && ((trumpsLeft / ((player == startPlayer) ? 3 : 2)) < cColours[pTrump->colour ()])) { Check3 (pile.size () > posColours[pTrump->colour ()]); pos = posColours[pTrump->colour ()]; if (!isHighest (*pile[posColours[pTrump->colour ()]])) pos -= cColours[pTrump->colour ()] - 1; break; } trumpsLeft -= cColours[pTrump->colour ()]; // - Have dead cards? int maxDiff (0); CardWidget::COLOURS maxColour (CardWidget::HEARTS); for (unsigned int i (0); i < (sizeof (cColours) / sizeof (*cColours)); ++i) { int diff (cColours[i] - (13 - playedCards[i].count ()) / 3); if ((diff > maxDiff) && ((int)i != pTrump->colour ())) { maxDiff = diff; maxColour = (CardWidget::COLOURS)i; } } TRACE8 ("SgtMayor::findPos2Play (unsigned int) - Dead cards: " << maxDiff << ": " << (int)maxColour); if (maxDiff) { Check2 (pTrump); Check3 (posColours[maxColour] != -1U); pos = posColours[maxColour]; Check3 ((playedCards[maxColour].count () + cColours[maxColour]) <= 13); if (!isHighest (*pile[posColours[maxColour]]) || (trumpsLeft && (((playedCards[maxColour].count () + cColours[maxColour]) > 11) || ((bfColours & (0x111 << maxColour)) && !((bfColours >> maxColour) & (bfColours >> pTrump->colour ())))))) pos -= cColours[maxColour] - 1; break; } // Try to find the highest card pos = 0; while (pos < pile.size ()) { pos = pile.findLastEqualColour (pos); if (isHighest (*pile[pos]) && (pile[pos]->colour () != pTrump->colour ()) && !(trumpsLeft && (bfColours & (0x110 << pile[pos]->colour ())))) break; ++pos; } if (pos >= pile.size ()) pos = pile.findLowestCard (pTrump->colour ()); break; } case 1: { Check3 ((playedCards[played[0]->colour ()].count () + cColours[played[0]->colour ()]) <= 13); bool nextHasntColour ((bfColours & ((1 << played[0]->colour ()) << (calcNextPlayer (player) << 2))) || ((playedCards[played[0]->colour ()].count () + cColours[played[0]->colour ()]) > 12)); pos = posColours[played[0]->colour ()]; TRACE9 ("SgtMayor::findPos2Play (unsigned int) - Play: " << (int)pos << "; Next: " << nextHasntColour); if (pos == -1U) { Check3 ((playedCards[pTrump->colour ()].count () + cColours[pTrump->colour ()]) <= 13); bfColours |= ((1 << played[0]->colour ()) << (player << 2)); pos = posColours[pTrump->colour ()]; if ((pos == -1U) || (nextHasntColour && !isHighest (*pile[pos]) && ((cColours[pTrump->colour ()] + playedCards[pTrump->colour ()].count ()) < 13))) { pos = pile.findLowestCard (pTrump->colour ()); bfColours |= (1 << pTrump->colour ()); } else pos -= cColours[pTrump->colour ()] - 1; } else // If the next is know to not have the colour or player has not the // highest left of this colour, play a low one if (nextHasntColour || !isHighest (*pile[pos]) || played[0]->number () > pile[pos]->number ()) pos -= cColours[played[0]->colour ()] - 1; break; } case 2: // The tick is taken by the second player with a trump. Either play a // small card or use a bigger trump. if ((played[0]->colour () != pTrump->colour ()) && (played[1]->colour () == pTrump->colour ())) { pos = pile.find (played[0]->colour ()); if (pos == -1U) { pos = pile.find1EqualOrBiggerByColour (*played[1]); if (pos == -1U) { bfColours |= ((1 << played[0]->colour ()) << (player << 2)); pos = pile.findLowestCard (pTrump->colour ()); if (pile[pos]->colour () != pTrump->colour ()) bfColours |= (1 << pTrump->colour ()); } } } else { pos = pile.find1EqualOrBiggerByColour (((played[0]->colour () != played[1]->colour ()) || (played[0]->number () > played[1]->number ())) ? *played[0] : *played[1]); if ((pos == -1U) || (pile[pos]->colour () != played[0]->colour ())) { pos = (pile.exists (played[0]->colour ()) ? pile.find (played[0]->colour ()) : (bfColours |= ((1 << played[0]->colour ()) << (player << 2)), tryToGetTickWithTrump (pile))); if (pile[pos]->colour () != pTrump->colour ()) bfColours |= (1 << pTrump->colour ()); } } break; default: Check3 (0); } Check3 (pos < pile.size ()); return pos;}//-----------------------------------------------------------------------------/// Changes the names of the playing people/// \param newPlayer: Array holding the new player//-----------------------------------------------------------------------------void SgtMayor::changeNames (const std::vector<Player*>& newPlayer) { Game::changeNames (newPlayer); std::vector<Player*> player; for (unsigned int i (0); i < NUM_PLAYERS; ++i) { player.push_back (actPlayers[(i + posServer) & 0x3]); players[i].name.set_text (actPlayers[i]->getName ()); } if (pScoreDlg) pScoreDlg->update (player);}//----------------------------------------------------------------------------/// Converts a pile-number to the actual pile/// \param player: Actual player/// \param pile: ID of the pile to return/// \returns ICardPile*: Pointer to pile to use or NULL//----------------------------------------------------------------------------ICardPile* SgtMayor::getPileOfPlayer (unsigned int player, unsigned int pile) { TRACE9 ("SgtMayor::getPileOfPlayer (2x unsigned int) - Player " << player << "; " << pile); if ((player + posServer) >= NUM_PLAYERS)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -