📄 sgtmayor.cpp
字号:
player -= posServer; Check3 (player < NUM_PLAYERS); Check3 (!pile); return ((player >= NUM_PLAYERS) || pile) ? NULL : &players[player].hand;}//-----------------------------------------------------------------------------/// Reads card- and playernumber from the next tokens/// \param src: String to analyze/// \param card: Filled with number of card/// \param player: Filled with player number/// \returns bool: True, if parsing was successfull//-----------------------------------------------------------------------------bool SgtMayor::readCardInfo (YGP::Tokenize& src, unsigned long& card, unsigned long& player) { std::string strCard (src.getNextNode (';')); std::string from (src.getNextNode ('=')); std::string strPlayer (src.getNextNode (';')); if ((from == "From") && !stringToNumber (card, strCard.c_str ()) && (card < 52) && !stringToNumber (player, strPlayer.c_str ()) && (player < NUM_PLAYERS)) return true; return false;}//----------------------------------------------------------------------------/// Handles the messages the server might send for the Sgt.Mayor cardgame/// \param player: ID of player sending the message/// \param message: Message received from the server/// \returns bool: True, if message has been completey processed/// \throw YGP::ParseError, YGP::CommError: In case of an error an describing text//----------------------------------------------------------------------------bool SgtMayor::handleMessage (unsigned int player, const std::string& message) throw (YGP::ParseError, YGP::CommError) { TRACE1 ("SgtMayor::handleMessage (unsigned int player, const std::string&) - " << message << " (" << player << ')'); YGP::Tokenize command (message); std::string cmd (command.getNextNode ('=')); if (cmd == "Exchange") { unsigned long card1, card2; unsigned long player1, player2; if (readCardInfo (command, card1, player1) && (command.getNextNode ('=') == "With") && (readCardInfo (command, card2, player2))) { player1 = (NUM_PLAYERS + player1 - posServer) % NUM_PLAYERS; player2 = (NUM_PLAYERS + player2 - posServer) % NUM_PLAYERS; card1 = players[player1].hand.find (static_cast <unsigned int> (card1)); card2 = players[player2].hand.find (static_cast <unsigned int> (card2)); if ((card1 == -1U) || (card2 == -1U)) throw YGP::ParseError (N_("Card not found!")); status.pop (); if (getConnectionMgr ().getMode () == YGP::ConnectionMgr::CLIENT) { doExchangeCards (player2, card2, player1, card1); } else exchangeCards (player2, card2, player1, card1); makeExchange (); return true; } } else if (cmd == "Trump") { unsigned long trumpColour; if (!stringToNumber (trumpColour, command.getNextNode (';').c_str ())) { if (getConnectionMgr ().getMode () == YGP::ConnectionMgr::CLIENT) doShowTrump ((CardWidget::COLOURS)trumpColour); else showTrump ((CardWidget::COLOURS)trumpColour); makeNextMoves (); return true; } } bool rc (Game::handleMessage (player, message)); if (cmd == "ActPlayer") { startPlayer = currentPlayer (); if ((startPlayer + posServer - 1) >= NUM_PLAYERS) startPlayer -= 1; TRACE9 ("SgtMayor::handleMessage (unsigned int player, const std::string&) - Start with " << startPlayer); showNeededTicks (); makeExchange (); } return rc;}//----------------------------------------------------------------------------/// Shows the special colour on the board (the ace with that colour). Also/// inform connected player about it/// \param colour: The special colour to display//----------------------------------------------------------------------------void SgtMayor::showTrump (CardWidget::COLOURS colour) { TRACE9 ("SgtMayor::showTrump (CardWidget::COLOURS) - " << colour); if (getConnectionMgr ().getMode () != YGP::ConnectionMgr::NONE) { if (getConnectionMgr ().getMode () == YGP::ConnectionMgr::CLIENT) ignoreNextMsg = true; std::ostringstream msg; msg << "Trump=" << colour; broadcastMessage (msg.str ()); } doShowTrump (colour);}//----------------------------------------------------------------------------/// Shows the special colour on the board (the ace with that colour)/// \param colour: The special colour to display//----------------------------------------------------------------------------void SgtMayor::doShowTrump (CardWidget::COLOURS colour) { TRACE9 ("SgtMayor::doShowTrump (CardWidget::COLOURS) - " << colour); for (unsigned int i (0); i < cards.size (); ++i) { if ((cards.getCards ()[i]->number () == CardWidget::ACE) && (cards.getCards ()[i]->colour () == colour)) { Check3 (!pTrump); pTrump = new CardWidget (*cards.getCards ()[i]); pTrump->show (); pTrump->showFace (); attach (*pTrump, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 5, 1); displayTurn (convertPlayer (startPlayer)); return; } } Check3 (0);}//----------------------------------------------------------------------------/// Plays the passed card; find winner and give him the cards at the end of a/// turn./// \param player: Player on turn/// \param card: Card to play/// \returns unsigned int: Next player; or -1U, if end of game//----------------------------------------------------------------------------unsigned int SgtMayor::playCard (unsigned int player, unsigned int card) { TRACE3 ("SgtMayor::playCard (unsigned int, unsigned int) - Player " << player); playedCards[players[player].hand[card]->colour ()].set (players[player].hand[card]->number ()); movePile (played, players[player].hand, card, card); if (played.size () == NUM_PLAYERS) { // Find the winner CardVPile::const_iterator i (played.begin ()); CardWidget::NUMBERS nr ((*i)->number ()); CardWidget::COLOURS col ((*i)->colour ()); unsigned int bestPlayer (0); Check3 (pTrump); while (++i != played.end ()) { TRACE8 ("SgtMayor::playCard (unsigned int, unsigned int) - Comparing " << (**(i - 1)) << " - " << **i); if ((col != pTrump->colour ()) && ((*i)->colour () == pTrump->colour ())) { TRACE9 ("SgtMayor::playCard (unsigned int, unsigned int) - Found trump "); col = pTrump->colour (); nr = (*i)->number (); bestPlayer = i - played.begin (); continue; } if (((*i)->number () > nr) && ((*i)->colour () == col)) { TRACE9 ("SgtMayor::playCard (unsigned int, unsigned int) - New best card " << **i); nr = (*i)->number (); bestPlayer = i - played.begin (); } } TRACE9 ("SgtMayor::playCard (unsigned int, unsigned int) - Calc. winner from " << player << " and " << bestPlayer); player = (player + 1 + bestPlayer) % NUM_PLAYERS; TRACE9 ("SgtMayor::playCard (unsigned int, unsigned int) - Winner " << player); // Move the cards to his won pile (but show only one of them) while (played.size () > 1) { CardWidget& card (played.remove (0)); card.hide (); players[player].won.append (card); } players[player].won.append (played.removeTopCard ()); Check3 (played.empty ()); if (!player) enableWonCards (players[0].won); } else player = calcNextPlayer (player); if (players[player].hand.size ()) { Check3 ((posServer + player) < actPlayers.size ()); displayTurn (convertPlayer (player)); return player; } Glib::ustring stat (_("Game ended; %1 has %2 %7, %3 %4 and %5 %6 %8")); unsigned int neededTicks[NUM_PLAYERS] = { 6, 3, 8 }; player = startPlayer; for (unsigned int i (0); i < NUM_PLAYERS; ++i) { int madeTicks (players[player].won.size () / 3); diffTicks[player] = madeTicks - neededTicks[i]; TRACE9 ("SgtMayor::playCard (unsigned int, unsigned int) - Player " << player << " made " << madeTicks << " = " << (int)diffTicks[player]); player = calcNextPlayer (player); } // Create score-dialog if (!pScoreDlg) { // Resort player for score dialogue std::vector<Player*> player; for (unsigned int i (0); i < NUM_PLAYERS; ++i) player.push_back (actPlayers[i]); pScoreDlg = ScoreDlg::create (player); pScoreDlg->get_window ()->set_transient_for (get_window ()); } pScoreDlg->addPoints (diffTicks); pScoreDlg->show (); int points; pScoreDlg->getMaxPoints (points, player); Check3 (points >= 0); if ((unsigned int)points >= ENDTRICKS) { Glib::ustring won (_("; %1 won")); won.replace (won.find ("%1"), 2, actPlayers[convertPlayer (player)]->getName ()); stat += won; } stat.replace (stat.find ("%1"), 2, actPlayers[0]->getName ()); stat.replace (stat.find ("%3"), 2, actPlayers[convertPlayer (1)]->getName ()); stat.replace (stat.find ("%5"), 2, actPlayers[convertPlayer (2)]->getName ()); stat.replace (stat.find ("%2"), 2, formatNumber (*diffTicks)); stat.replace (stat.find ("%4"), 2, formatNumber (diffTicks[1])); stat.replace (stat.find ("%6"), 2, formatNumber (diffTicks[2])); stat.replace (stat.find ("%7"), 2, (ngettext ("tick", "ticks", (*diffTicks < 0) ? -*diffTicks : *diffTicks))); stat.replace (stat.find ("%8"), 2, (ngettext ("tick", "ticks", (diffTicks[2] < 0) ? -diffTicks[2] : diffTicks[2]))); status.pop (); status.push (stat); setGameStatus (STOPPED); return -1U;}//-----------------------------------------------------------------------------/// Formats a number with sign character always shown/// \param nr: Number to format/// \returns std::string: Formatted number/// \remarks Shows the sign always (e.g. also the plus sign (+)//-----------------------------------------------------------------------------std::string SgtMayor::formatNumber (int nr) { std::ostringstream msg; msg << std::showpos << nr; return msg.str ();}//----------------------------------------------------------------------------/// Checks if the passed card is the highest card of its colour, which has/// not been played./// \param card: Card to inspect/// \return bool: True, if card is the highest unplayed one//----------------------------------------------------------------------------bool SgtMayor::isHighest (const CardWidget& card) const { TRACE8 ("SgtMayor::isHighest (const CardWidget&) - " << card); int nr (card.number ()); while (++nr <= CardWidget::ACE) { if (!playedCards[card.colour ()][nr]) return false; } return true;}//----------------------------------------------------------------------------/// Tries to get the tick with a trump card; returns a bad card, if there's no/// trump./// \param pile: Pile to play from/// \return unsigned int: Position of card to play//----------------------------------------------------------------------------unsigned int SgtMayor::tryToGetTickWithTrump (const ICardPile& pile) const { TRACE8 ("SgtMayor::tryToGetTickWithTrump (const ICardPile&) - Size " << pile.size ()); Check3 (pile.size ()); unsigned int pos (pile.find (pTrump->colour ())); if (pos == -1U) pos = pile.findLowestCard (pTrump->colour ()); return pos;}//----------------------------------------------------------------------------/// Exchanges cards between players having too much/too less ticks in the last/// round.//----------------------------------------------------------------------------void SgtMayor::makeExchange () { TRACE5 ("SgtMayor::makeExchange () - Exchanging cards: " << (*diffTicks > 0 ? (int)*diffTicks : 0) + (diffTicks[1] > 0 ? (int)diffTicks[1] : 0) + (diffTicks[2] > 0 ? (int)diffTicks[2] : 0)); Check3 (*diffTicks + diffTicks[1] == -diffTicks[2]); bool humanExchange (*diffTicks); for (unsigned int i (startPlayer); (i - startPlayer) < NUM_PLAYERS; ++i) { TRACE9 ("SgtMayor::makeExchange () - " << i % NUM_PLAYERS << "'s ticks: " << (int)diffTicks[i % NUM_PLAYERS]); while (diffTicks[i % NUM_PLAYERS] > 0) { Check3 ((diffTicks[(i + 1) % NUM_PLAYERS] < 0) || (diffTicks[(i + 2) % NUM_PLAYERS] < 0)); for (unsigned int j (1); j < NUM_PLAYERS; ++j) { TRACE9 ("SgtMayor::makeExchange () - With " << (i + j) % NUM_PLAYERS << "'s ticks: " << (int)diffTicks[(i + j) % NUM_PLAYERS]); if (diffTicks[(j + i) % NUM_PLAYERS] < 0) { if (i % NUM_PLAYERS) { if ((getConnectionMgr ().getMode () == YGP::ConnectionMgr::CLIENT) || (typeid (*actPlayers[convertPlayer (i % NUM_PLAYERS)])
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -