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

📄 machiavelli.cpp

📁 一个扑克牌游戏集合的源码,包含了很多基本c-c++语言应用
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//-----------------------------------------------------------------------------void Machiavelli::getDropData (const Glib::RefPtr<Gdk::DragContext>& pContext,                               Gtk::SelectionData& data, guint, guint32 time,                               unsigned int cardPos) {   Check1 (pContext->get_is_source ());   data.set (data.get_target (), 8, reinterpret_cast <guchar*> (&cardPos),             sizeof (cardPos));}//-----------------------------------------------------------------------------/// Callback after dropping a card on the table/// \param pContext: Context of the drag (contains things like source,/// \param target, action, ...)/// \param data: Describes the thing which was dropped/// \param info: Describes the type of data (should be 0)/// \param time: Timestamp of the drag/// \param iCard: Combination of card and pile on which card was dropped/// \pre \c pContext not NULL;//-----------------------------------------------------------------------------void Machiavelli::cardDroppedOnTable (const Glib::RefPtr<Gdk::DragContext>& context,                                      gint, gint, const Gtk::SelectionData& data,                                      guint info, guint32 time, unsigned int iCard) {   TRACE1 ("Machiavelli::cardDroppedOnTable (...) - Card dropped on " << std::hex           << (int)iCard << std::dec << "; " << info);   Check1 (!context->get_is_source ());   Check1 (data.get_length () == sizeof (int));   Check1 (data.get_format () == 8);   Check1 ((info == HAND) || (info == TABLE));   unsigned int* pValue (reinterpret_cast <unsigned int*>                         (const_cast<guint8*> (data.get_data ())));   TRACE1 ("Machiavelli::cardDroppedOnTable (...) - Inserting card " << std::hex           << *pValue << std::hex << " in pile");   Check2 (pValue);   unsigned int nrpile (*pValue >> 8);   unsigned int off (*pValue & 0xff);   Check2 ((info == HAND)           ? (off < hands[0].size ())           : (nrpile < tablePiles.size () && (off < tablePiles[nrpile]->size ())));   // Move dropped card to a (new) pile on the table   unsigned int iPile (0);   MachiPile* pile (NULL);   ICardPile& src ((info == HAND) ? hands[0] : *tablePiles[nrpile]);   CardWidget* moved (src[off]);   unsigned int nr (((info == HAND)                     || (tablePiles[nrpile]->getType () == MachiPile::NUMBER))                    ? 1 : (src.size () - off));   TRACE4 ("Machiavelli::cardDroppedOnTable (...) - Card dropped: " << *moved);   if (iCard == -1U) {    // If card was dropped on the new label: Create pile      iPile = tablePiles.size ();      pile = &makeNewPile ();      iCard = 0;   }   else {      // Else check pile to use      iPile = iCard >> 8;      // Ignore dnd from a pile to itself      if ((info == TABLE) && (iPile == nrpile)) {         context->drag_finish (true, false, time);         return;      }      Check1 (iPile < tablePiles.size ());      pile = tablePiles[iPile];      iCard = pile->getPosition4Card (*moved);      if (iCard == -1U) {         context->drag_finish (true, false, time);         Gtk::MessageDialog dlg (_("This card does not fit on that pile!"),                                 Gtk::MESSAGE_ERROR);         dlg.set_title (_("Invalid move"));         dlg.run ();         return;      }      if (info == TABLE) {         // Move only one card from/to a numbered pile         if ((pile->getType () == MachiPile::NUMBER)             || ((pile->getType () == MachiPile::UNDEFINED)                 ? ((pile->size () == 1)                    && ((*pile)[0]->number () == moved->number ()))                 : !iCard)             || (tablePiles[nrpile]->getType () == MachiPile::NUMBER))            nr = 1;         // Check if only cards from an edge are moved to the beginning of         // a coloured pile or a numbered pile         if ((tablePiles[nrpile]->getType () == MachiPile::COLOUR)             && (((off + 1) != src.size ()) && off)             && ((iCard != pile->size ())                 || (pile->getType () == MachiPile::NUMBER))) {            context->drag_finish (true, false, time);            Gtk::MessageDialog dlg (_("Card is not on the edge of the origen - try splitting the origin first!"),                                    Gtk::MESSAGE_ERROR);            dlg.set_title (_("Invalid move"));            dlg.run ();            return;         }      }   }   Check3 (pile);   // End old drag   context->drag_finish (true, false, time);   // Store undo-info 4 Bytes: Target-pile, target-card, source-pile,   // source-card; if played from hand, set source-pile to 0xff   undoValue val (iPile, iCard, (info == HAND) ? 0xff : nrpile, off, nr);   // Send move   if (getConnectionMgr ().getMode () != YGP::ConnectionMgr::NONE) {      std::ostringstream msg;      if (info == HAND)         msg << "Play=" << src[off]->id ();      else         msg << "Reorder=" << ((nr << 16) + (nrpile << 8) + off);      msg << ";Target=" << (iPile << 16) + iCard;      if (info ==TABLE)         msg << ";Now=1";      if (getConnectionMgr ().getMode () == YGP::ConnectionMgr::CLIENT)          ++ignoreNextMsg;      broadcastMessage (msg.str ());   }   while (nr--) {      TRACE9 ("Machiavelli::cardDroppedOnTable (...) - Insert to: " << iPile              << "; Pos: " << iCard);      Check3 (iCard != -1U);      // Unregister old card      src.remove (off);      (info == HAND) ? unregisterHandDND (*moved) : unregisterTableDND (*moved);      // Insert card into pile and register it for DND      Check3 (iCard <= pile->size ());      pile->insert (*moved, iCard);      registerTableDND (*moved, (iPile << 8) + iCard);      if (iCard < (pile->size () - 1))         registerTableDND (iPile, iCard + 1, pile->size () - 1);      moved = src[off];      iCard++;   }   if (hands[0].empty ()) {      YGP::StatusObject obj;      checkPiles (obj);      if (obj.getType () == YGP::StatusObject::UNDEFINED) {         unsigned int nextPlayer (findNextPlayer (0));         if (nextPlayer == findNextPlayer (nextPlayer)) {            endGame (nextPlayer);            disableHuman ();            return;         }      }   }   if (info == TABLE) {      if (src.empty ()) {                             // Pile moved completely?         std::vector<MachiPile*>::iterator i (tablePiles.begin () + nrpile);         Check3 (*i == &src);         tablePiles.erase (i);         delete &src;         val.create = true;         if (nrpile > iPile)             nrpile = iPile;         // Re-register the following piles         while (nrpile < tablePiles.size ()) {             registerTableDND (nrpile, 0, tablePiles[nrpile]->size () - 1);             ++nrpile;         }      }      else {        for (MachiPile::iterator i (tablePiles[nrpile]->begin ());             i != tablePiles[nrpile]->end (); ++i) {           unregisterTableDND (**i);           registerTableDND (**i, (nrpile << 8) + i - tablePiles[nrpile]->begin ());        }      }   }   // Re-register the cards in the hand of the human for DND   if ((info ==HAND) && *pValue < hands[0].size ())      registerHandDND (*pValue, hands[0].size () - 1);   Check3 (aDNDHand.size () == hands[0].size ());   undo.push (val);   undo1->set_sensitive (true);   undoAll->set_sensitive (true);}//----------------------------------------------------------------------------/// Finds the next player still having cards/// \param player: Player to find next player to/// \return unsigned int: Next player having cards/// \remarks We assume (without really checking), that there's a next player.//----------------------------------------------------------------------------unsigned int Machiavelli::findNextPlayer (unsigned int player) const {   for (unsigned int i (0); i < NUM_PLAYERS; ++i) {      player = (player + 1) & 0x3;      if (hands[player].size ()) {         TRACE8 ("Machiavelli::findNextPlayer (unsigned int) const - Player: " << player);         break;      }   }   Check3 (player < NUM_PLAYERS);   return player;}//-----------------------------------------------------------------------------/// Makes a new pile./// \returns MachiPile&: New created pile//-----------------------------------------------------------------------------MachiPile& Machiavelli::makeNewPile () {   TRACE9 ("Machiavelli::makeNewPile ()");   MachiPile* pile (new MachiPile ());   pile->show ();   piles.add (*pile);   tablePiles.push_back (pile);   TRACE9 ("Machiavelli::makeNewPile () - Pile " << tablePiles.size ());   return *pile;}//-----------------------------------------------------------------------------/// Makes a new pile in a certain position/// \param pos: Position of pile on the table/// \returns MachiPile&: New created pile//-----------------------------------------------------------------------------MachiPile& Machiavelli::makeNewPile (unsigned int pos) {   TRACE9 ("Machiavelli::makeNewPile ()");   MachiPile* pile (new MachiPile ());   pile->show ();   Check3 (pos <= tablePiles.size ());   piles.insert (*pile, pos);   tablePiles.insert (tablePiles.begin () + pos, pile);   return *pile;}//-----------------------------------------------------------------------------/// Searches the passed pile, if it has a serie of 3 or more. This method also/// \param playerPile: Pile to inspect/// \returns \c bool:/// \requires The pile must have at least 3 cards/// \remarks: Sets pos1Play and pos2Play, if a serie is found//-----------------------------------------------------------------------------bool Machiavelli::hasSerie (ICardPile& playerPile) {   Check3 (playerPile.size () >= 3);   // Check for 3 cards belonging to a serie   for (unsigned int i (0); i < (playerPile.size () - 2); ++i) {      TRACE8 ("Machiavelli::hasSerie (ICardPile&) - 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,                                              &MachiPile::cardDistance, false));      // Play the bigger of the found matching cards, if there are >= 3      if ((nrs > aPos.size ()) ? (nrs > 2) : (aPos.size () > 2)) {         if (nrs <= aPos.size ()) {            i = playerPile.sortColourSerie (aPos, aOrder);            nrs = aPos.size ();         }         pos1Play = i;         pos2Play = i + nrs - 1;         return true;      }   }   return false;}//-----------------------------------------------------------------------------/// Searches for cards to play and shows them in the hand of the actual player/// \param player: Player to inspect/// \returns \c ID of the target (32 Bit: Pile << 16 + Position) or -1U;/// \remarks: - Sets pos1Play and pos2Play approbiatly///    - Creates a new pile if needed//-----------------------------------------------------------------------------unsigned int Machiavelli::cardFitsToPile (const CardWidget& card, unsigned int offset) {   TRACE8 ("Machiavelli::cardFitsToPile (const CardWidget&, unsigned int) - Adding card "           << card << '?');   unsigned int dest (-1U);   for (std::vector<MachiPile*>::const_iterator m (tablePiles.begin ());        m != tablePiles.end (); ++m) {      Check2 ((*m)->getType () != MachiPile::UNDEFINED);      // Check if the card can be added to an existing pile      dest = (*m)->getPosition4Card (card);      if (dest != -1U) {         pos1Play = pos2Play = offset;         return ((m - tablePiles.begin ()) << 16) + dest;      }      // Or can the card be added by splitting the pile?      int diff (MachiPile::cardDistance (card, *(**m)[0]));      if (((*m)->getType () == MachiPile::COLOUR)          ? ((diff < 0) || (card.colour () != (**m)[0]->colour ()))          : diff)         continue;      int pos ((*m)->size () - static_cast<unsigned int> (diff));      TRACE8 ("Machiavelli::cardFitsToPile (const CardWidget&unsigned int) - Splitting "              << (m - tablePiles.begin ()) << " at " << diff << " (" << pos << ")?");      // A new pile can be made directly (enough cards on both sides)      if ((pos > 2) && (diff > 1)) {         // Move cards to remove to hand (to be shown); The card from the         // hand will be added in the next move         ++diff;         pos1Play = pos2Play = offset;         posPiles.push_back ((((*m)->size () - diff) << 16)                             + ((m - tablePiles.begin ()) << 8) + diff);         TRACE9 ("Machiavelli::cardFitsToPile (const CardWidget&unsigned int) - Marked pile: "                 << std::hex << pos2Play << std::dec);         do {            Check3 ((unsigned int)diff < (*m)->size ());            (**m)[diff]->mark ();         } while (static_cast<unsigned int> (++diff) < (*m)->size ());         makeNewPile ();         return (tablePiles.size () - 1) << 16;      }   }   return -1U;

⌨️ 快捷键说明

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