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

📄 hearts.cpp

📁 一个扑克牌游戏集合的源码,包含了很多基本c-c++语言应用
💻 CPP
📖 第 1 页 / 共 3 页
字号:
   if (played.size ()) {      // Check if cards of the same colour are available      return (aPos[played[0]->colour ()] == -1)         ? findWorstCard (pile, aPos) : findLowerCard (pile, aPos);   }   else {      // Player starts the round: If he has loads of spades: Play them      unsigned int nrSpades (numberOfCards (aPos, CardWidget::SPADES));      unsigned int missingSpades (cards.size () - nrSpades                                  - aPlayed[CardWidget::SPADES]);      // If there are still spades left (with other players) and either the      // player has no high spades or loads of spades: Play them      if (missingSpades && (!playedSQ)          && (((aPos[CardWidget::SPADES] != -1)               && (pile[aPos[CardWidget::SPADES]]->number ()                   < CardWidget::QUEEN))              || (((missingSpades / 3) + 1) < nrSpades))) {         unsigned int pos ((aPos[1] >= 0)                           ? aPos[1] + 1                           : ((aPos[0] >= 0) ? aPos[0] + 1: 0));         TRACE5 ("Hearts::findPos2Play (unsigned int) - Starting with spade at "                 << pos << " (" << *pile[pos] << ')');         return pos;      }      // Else: Search for a low card      int pos (0);      for (unsigned int card (CardWidget::TWO); card <= CardWidget::ACE;           ++card) {         pos = 0;         while ((pos = pile.find (CardWidget::NUMBERS (card), pos)) != -1) {            CardWidget::COLOURS colour (pile[pos]->colour ());            // Play the lowest card, if there are still cards of that colour            // owned by other players and - if it is a heart - there are            // already played hearts.            TRACE9 ("Hearts::findPos2Play (unsigned int) - Analyzing "                    << *pile[pos] << "; Played: " << aPlayed[colour]                    << "; I have: " << numberOfCards (aPos, colour));            if ((aPlayed[colour] + numberOfCards (aPos, colour))                < (cards.size () / NUM_PLAYERS)) {               TRACE8 ("Hearts::findPos2Play (unsigned int) - Considering to "                       "play " << *pile[pos] << "; Played: " << aPlayed[colour]);                if ((colour != CardWidget::HEARTS)                    || aPlayed[CardWidget::HEARTS]) {                   TRACE5 ("Hearts::findPos2Play (unsigned int) - Starting with "                           << *pile[pos]);                   return pos;                }            }            ++pos;         }      }      TRACE1 ("Hearts::findPos2Play (unsigned int) - All cards for player " << player);   }   return 0;}//-----------------------------------------------------------------------------/// Find a lower card than the previously played ones/// \param pile: Pile from which to play/// \param aPositions: Array with positions of cards/// \returns \c Position of card to play//-----------------------------------------------------------------------------unsigned int Hearts::findLowerCard (const ICardPile& pile, const int aPositions[4]) {   TRACE9 ("Hearts::findLowerCard (const ICardPile&, const int[4]");   CardWidget::COLOURS colour (played[0]->colour ());   unsigned int posWinner (check4Winner ());   // Play queen of spades, if there's already a higher card in the pile   if ((colour == CardWidget::SPADES)       && (played[posWinner]->number () > CardWidget::QUEEN))      return ((pile[aPositions[CardWidget::SPADES]]->number () == CardWidget::QUEEN)              || (numberOfCards (aPositions, CardWidget::SPADES) == 1)              || (pile[aPositions[CardWidget::SPADES] - 1]->number ()                  != CardWidget::QUEEN)              ? aPositions[CardWidget::SPADES] : aPositions[CardWidget::SPADES] - 1);   // Play high card of the colour, if last player and pile contains no   // counting card, except if that would mean to play the queen of spades.   if ((played.size () == (NUM_PLAYERS - 1))       && !pointsOfPile (played))      return ((colour != CardWidget::SPADES)              || (pile[aPositions[CardWidget::SPADES]]->number ()                  != CardWidget::QUEEN)              || numberOfCards (aPositions, CardWidget::SPADES) == 1)         ? aPositions[colour] : aPositions[colour] - 1;   else {      // Play highest card lower than the previously played ones      int card (0);      Check3 (played.size ());      CardWidget::NUMBERS highest (played[posWinner]->number ());      TRACE9 ("Hearts::findLowerCard (const ICardPile&, unsigned int[4]) - Try to"              " be below " << *played[posWinner]);      // Search for a lower card      unsigned int nrCards (numberOfCards (aPositions, colour));      card = aPositions[colour] + 1; Check3 (card >= 1);      do {         Check3 (pile[card - 1]->colour () == colour);         if (pile[--card]->number () < highest) {            // Found a lower card; test if the highest is the ace of            // spades and you have the queen and are about to play the king            if ((colour == CardWidget::SPADES)                && (highest == CardWidget::ACE)                && card                && (pile[card - 1]->number () == CardWidget::QUEEN)                && (pile[card - 1]->colour () == CardWidget::SPADES))               --card;            TRACE5 ("Hearts::findLowerCard (const ICardPile&, unsigned int[4]) - "                    "Playing card at " << card  << ": " << *pile[card]);            return card;         }      } while (--nrCards);      // Try to not play the queen of spades, if possible      if ((colour == CardWidget::SPADES)          && (card < aPositions[CardWidget::SPADES])          && (pile[card]->number () == CardWidget::QUEEN)) {         Check3 (pile[card + 1]->colour () == CardWidget::SPADES);         ++card;      }      if (played.size () == (NUM_PLAYERS - 1))         card = aPositions[colour];      TRACE5 ("Hearts::findLowerCard (const ICardPile&, unsigned int[4]) - "              "Forced to play card at " << card << ": " << *pile[card]);      return card;   }}//-----------------------------------------------------------------------------/// Find the worst card to play (defined as having the highest number of bad/// points (like the queen of spades with 13 points and every heart with 1/// point) or the highest numbered card)./// \param pile: Pile from which to play/// \param aPositions: Array with positions of cards/// \returns \c Position of card to play or -1//-----------------------------------------------------------------------------unsigned int Hearts::findWorstCard (const ICardPile& pile, const int aPositions[4]) {   TRACE9 ("Hearts::findWorstCard (const ICardPile&, const int[4]");   // Search for queen of spades or any heart or a high card   unsigned int cardsPlayed (0);   for (unsigned int i (0); i < NUM_PLAYERS; ++i)      cardsPlayed += players[i].won->size ();   if (cardsPlayed) {      TRACE5 ("Hearts::findWorstCard (const ICardPile&, const int[4]) - Searching"              " for SQ");      if (aPositions[2] > 0)         for (int pos ((aPositions[1] >= 0)                       ? aPositions[1] + 1                       : ((aPositions[0] >= 0) ? aPositions[0] + 1: 0));              pos <= aPositions[2]; ++pos) {            TRACE9 ("Hearts::findWorstCard (const ICardPile&, const int[4]) - "                    "Searching for SQ at position " << pos);            Check3 (pile[pos]->colour () == CardWidget::SPADES);            if (pile[pos]->number () >= CardWidget::QUEEN)               return static_cast<unsigned int> (pos);         }      // No high spade found: Try to play a heart (after the first round)      TRACE5 ("Hearts::findWorstCard (const ICardPile&, unsigned int[4]) - "              "Searching for hearts");      if (aPositions[CardWidget::HEARTS] != -1)         return aPositions[CardWidget::HEARTS];   }   // If everything else failes: Play a high card   TRACE5 ("Hearts::findWorstCard (const ICardPile&, unsigned int[4]) - Searching "           "for high cards");   int pos (0);   for (int card (CardWidget::ACE); card >= CardWidget::TWO;        --card) {      pos = 0;      while ((pos = pile.find (CardWidget::NUMBERS (card), pos))             != -1) {         CardWidget::COLOURS colour (pile[pos]->colour ());         TRACE2 ("Hearts::findWorstCard (const ICardPile&, unsigned int[4]) - "                 "Checking card " << *pile[pos] << " at pos " << pos                 << " against " << aPlayed[colour] << " cards");         if (cardsPlayed             || ((colour == CardWidget::SPADES)                 ? (card != CardWidget::QUEEN)                 : (colour != CardWidget::HEARTS)))            return pos;         ++pos;      }   }   Check3 (0);   return -1U;}//-----------------------------------------------------------------------------/// Counts the points in the passed pile. The queen of spades counts 13 points/// and every heart 1 point/// \param pile: Pile to inspect/// \returns \c unsigned int: Number of points//-----------------------------------------------------------------------------unsigned int Hearts::pointsOfPile (ICardPile& pile) {   unsigned int points (0);   for (unsigned int i (0); i < pile.size (); ++i) {      CardWidget::COLOURS colour (pile[i]->colour ());      if (colour == CardWidget::HEARTS)         ++points;      else         if ((colour == CardWidget::SPADES)             && pile[i]->number () == CardWidget::QUEEN)            points += 13;   }   TRACE7 ("Hearts::pointsOfPile (ICardPile&) - Number of points: " << points);   return points;}//-----------------------------------------------------------------------------/// Changes the names of the playing people/// \param newPlayer: Array holding the new player//-----------------------------------------------------------------------------void Hearts::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 newPlayer: Array holding the new player/// \param pile: ID of the pile to return/// \returns ICardPile*: Pointer to pile to use or NULL//----------------------------------------------------------------------------ICardPile* Hearts::getPileOfPlayer (unsigned int player, unsigned int pile) {   return ((player >= NUM_PLAYERS) || pile) ? NULL : players[player].hand;}//----------------------------------------------------------------------------/// Handles the messages the server might send for the hearts 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 Hearts::handleMessage (unsigned int player, const std::string& message) throw (YGP::ParseError, YGP::CommError) {   if (gameStatus () == EXCHANGE) {      TRACE1 ("Hearts::handleMessage (unsigned int player, const std::string&) - "              << message << " (" << player << ')');      YGP::Tokenize command (message);      std::string cmd (command.getNextNode ('='));      if (cmd == "Exchange") {         std::string cards (command.getNextNode (';'));         cmd = command.getNextNode ('=');         unsigned long lPlayer (player);         if ((cmd == "Player")             && !stringToNumber (lPlayer, command.getNextNode (';').c_str ())             && (lPlayer < NUM_PLAYERS)) {            Check3 (player ? (lPlayer == player) : true);            if (!player)               lPlayer = static_cast<unsigned long> (lPlayer);            register unsigned int save (lPlayer);            lPlayer = (lPlayer - posServer) & 0x3;            // Don't exchange already exchanged cards            if (save != posServer) {               command = cards;               unsigned long card (0);               while (command.getNextNode (' ').size ()) {                  if (stringToNumber (card, command.getActNode ().c_str ()))                     break;                  TRACE9 ("Hearts::handleMessage (unsigned int, const std::string&) - "                          << lPlayer << ": " << card);                  card = players[lPlayer].hand->find (static_cast<unsigned int> (card));                  Check3 (card < players[lPlayer].hand->size ());                  if (card != -1U)                     movePile (aExchange[lPlayer], *players[lPlayer].hand,                               card, card);               }            }            TRACE2 ("Hearts::handleMessage (unsigned int player, const std::string&) - "                    "Exchanged: " << aExchange[lPlayer].size () << " cards");            if (aExchange[lPlayer].size () == 3) {               YGP::ConnectionMgr& cmgr (getConnectionMgr ());               // Inform other clients               if (cmgr.getMode () == YGP::ConnectionMgr::SERVER)                  broadcastMessage (message);               if (cardsExchanged (((cmgr.getMode () == YGP::ConnectionMgr::SERVER)                                    ? (cmgr.getClients ().size () + 1)                                    : NUM_PLAYERS) * 3)) {                  exchangeCards ();                  startPlaying ();               }            }            return true;         }      }   }   return Game::handleMessage (player, message);}//----------------------------------------------------------------------------/// Checks if the number of exchanged cards is equal to the passed value./// \param cards: Number of cards to exchange/// \returns bool: True, if all cards have been exchanged/// \pre Game must be in EXCHANGE state//----------------------------------------------------------------------------bool Hearts::cardsExchanged (unsigned int cards) {   Check1 (gameStatus () == EXCHANGE);   for (unsigned i (0); i < NUM_PLAYERS; ++i)      cards -= aExchange[i].size ();   TRACE9 ("Hearts::cardsExchanged (unsigned int) - Remaining: " << cards);   return !(cards - played.size ());}//-----------------------------------------------------------------------------/// Adds game-specific menus/// \param mgrUI: UIManager to add to//-----------------------------------------------------------------------------void Hearts::addMenus (Glib::RefPtr<Gtk::UIManager> mgrUI) {   Check1 (mgrUI);   Glib::ustring ui ("<menubar name='Menu'>"		     "  <placeholder name='GameMenu'>"		     "    <menu action='MB'>"		     "      <menuitem action='HeartSort'/>"		     "      <menuitem action='HeartSortCol'/>"		     "    </menu></placeholder></menubar>");   Glib::RefPtr<Gtk::ActionGroup> grpAction (Gtk::ActionGroup::create ());   grpAction->add (Gtk::Action::create ("MB", _("H_earts")));   grpAction->add (Gtk::Action::create ("HeartSort", Gtk::Stock::SORT_ASCENDING,					_("_Sort won cards (by number)")),		   Gtk::AccelKey ("<shft>S"),		   mem_fun (*this, &Hearts::sortWonByNumber));   grpAction->add (Gtk::Action::create ("HeartSortCol", Gtk::Stock::SORT_ASCENDING,					_("Sort won cards (by _colour)")),		   Gtk::AccelKey ("S"),		   mem_fun (*this, &Hearts::sortWonByColour));   mgrUI->insert_action_group (grpAction);   idMrg = mgrUI->add_ui_from_string (ui);}//-----------------------------------------------------------------------------/// Removes the game-specific menus/// \param mgrUI: UIManager to remove from//-----------------------------------------------------------------------------void Hearts::removeMenus (Glib::RefPtr<Gtk::UIManager> mgrUI) {   Check1 (mgrUI);   mgrUI->remove_ui (idMrg);}

⌨️ 快捷键说明

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