📄 rovhult.cpp
字号:
// (upper visible) and 3 (visible ones) in hand for (unsigned int i (0); i < NUM_PLAYERS; ++i) for (unsigned int j (0); j < 3; ++j) { for (unsigned int k (0); k < 2; ++k) { // Set cards on table CardWidget& card (staple.removeTopCard ()); players[(i - posServer) & 0x3].reserve[j].setTopCard (card, k); } // end-for two cards pro pile (in reserve) // Put card into hand players[(i - posServer) & 0x3].hand.insertSorted (staple.removeTopCard ()); } // Enable drag-and-drop for cards in the hand (of human player) for (unsigned int i (0); i < players[i].hand.size (); ++i) { registerHandDND (*players[0].hand[i], i); registerTableDND (players[0].reserve[i].getTopCard (), i); } Check3 (staple.size ()); status.pop (); status.push (_("Exchange the cards in your hand with the one on the " "table (with drag and drop) - click on one card to start playing"));}//-----------------------------------------------------------------------------/// Callback after dropping a card onto (cards on) 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 pile: Number of pile/// \param Requieres : pContext not NULL; Expects info to be 0//-----------------------------------------------------------------------------void Rovhult::cardDroppedOnTable (const Glib::RefPtr<Gdk::DragContext>& context, int, int, const Gtk::SelectionData& data, guint info, guint32 time, unsigned int pile) { Check3 (!context->get_is_source ()); Check3 (data.get_length () == sizeof (int)); Check3 (data.get_format () == 8); Check3 (pile < 3); unsigned int* pValue (reinterpret_cast <unsigned int*> (const_cast<guint8*> (data.get_data ()))); Check3 (pValue); TRACE1 ("Rovhult::cardDroppedOnTable (...) - Data = " << *pValue << " <-> " << pile); // End old dnd context->drag_finish (true, false, time); Glib::signal_idle ().connect (bind (mem_fun (*this, &Rovhult::doSwapCards), pile, *pValue));}//-----------------------------------------------------------------------------/// Swaps a card in the hand with one (top-card) on the table/// \param pile: Offset of pile whose top-card should be swapped/// \param card: Offset of card in the hand which should be swapped/// \returns bool: Always false//-----------------------------------------------------------------------------bool Rovhult::doSwapCards (unsigned int pile, unsigned int card) { CardWidget& cardTable (players[0].reserve[pile].removeTopCard ()); CardWidget& cardHand (players[0].hand.remove (card)); TRACE1 ("Rovhult::doSwapCards (unsigned int, unsigned int) - Exchanging cards " << cardHand.id () << "<->" << cardTable.id ()); activeCards[card].disconnect (); disconnectCardInHand (cardHand); disconnectCardOnTable (cardTable); unregisterDND (cardHand); unregisterDND (cardTable); // Swap cards players[0].reserve[pile].setTopCard (cardHand); players[0].hand.insert (cardTable, card); // Adapt dnd-settigns registerHandDND (cardTable, card); registerTableDND (cardHand, pile); return false;}//-----------------------------------------------------------------------------/// Callback after dropping a card onto onto hand/// \param context: 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 card: Number of card/// \param Requieres : Expects info to be 0//-----------------------------------------------------------------------------void Rovhult::cardDroppedOnHand (const Glib::RefPtr<Gdk::DragContext>& context, int, int, const Gtk::SelectionData& data, guint info, guint32 time, unsigned int card) { Check3 (!context->get_is_source ()); Check3 (data.get_length () == sizeof (int)); Check3 (data.get_format () == 8); Check3 (card < players[0].hand.size ()); unsigned int* pValue (reinterpret_cast <unsigned int*> (const_cast<guint8*> (data.get_data ()))); Check3 (pValue); TRACE1 ("Rovhult::cardDroppedOnHand (...) - Data = " << *pValue << " <-> " << card); // End old DND context->drag_finish (true, false, time); Glib::signal_idle ().connect (bind (mem_fun (*this, &Rovhult::doSwapCards), *pValue, card));}//-----------------------------------------------------------------------------/// Callback to query the data to drop/// \param context: Context of the drag (contains things like source,/// \param target, action, ...)/// \param data: Describes the thing which was dropped/// \param time: Timestamp of the drag/// \param cardPos: Position of card (either in hand or pile on table)/// \param Requieres : pContext not NULL; Expects info to be 0//-----------------------------------------------------------------------------void Rovhult::getDropData (const Glib::RefPtr<Gdk::DragContext>& context, Gtk::SelectionData& data, guint info, guint32 time, unsigned int cardPos) { Check3 (info < 2); Check3 (context->get_is_source ()); data.set (data.get_target (), 8, reinterpret_cast <guchar*> (&cardPos), sizeof (cardPos));}//-----------------------------------------------------------------------------/// Shows the cards the user is about to play/// \param player: Player in turn//-----------------------------------------------------------------------------void Rovhult::showCards2Play (unsigned int player) { TRACE2 ("Rovhult::showCards2Play (unsigned int, unsigned int) - " "For player " << player); Check3 (player < NUM_PLAYERS); findCard2Play (player, pos1Play, pos2Play); Check3 (pos1Play <= pos2Play); if (players[player].hand.size ()) flipCards2Play (players[player].hand, pos1Play, pos2Play); else { ICardPile& pile (players[player].reserve[pos2Play]); unsigned int target (pos2Play + 1); if (!cardValid (pile.getTopCard ().number (), true)) target += 4; for (unsigned int i (pos1Play); i <= pos2Play; ++i) { Check3 (players[player].reserve[i].size ()); CardWidget& card (players[player].reserve[i].getTopCard ()); ((pile.size () > 1) || (target > 3) || (players[player].reserve[i].getTopCard ().number () != cardNuke)) ? card.mark () : card.showFace (); } // Inform the others about the move if (getConnectionMgr ().getMode () == YGP::ConnectionMgr::SERVER) { // Send played card to all clients (if any) std::ostringstream msg; msg << "Play=" << pile.getTopCard ().id () << ";Target=" << target; broadcastMessage (msg.str ()); } }}//-----------------------------------------------------------------------------/// Finds an executes the turn of a (computer controled) player/// \returns \c int: The next player//-----------------------------------------------------------------------------int Rovhult::makeMove (unsigned int player) { TRACE2 ("Rovhult::makeMove (unsigned int) - Player " << player); if (pos2Play == -1U) { if (playerCanContinue (player, (played.size () ? played.getTopCard ().number () : CardWidget::TWO))) showCards2Play (player); else { if (getConnectionMgr ().getMode () == YGP::ConnectionMgr::SERVER) { std::ostringstream msg; msg << "Play=" << played[played.size () - 1]->id () << ";Target=4"; broadcastMessage (msg.str ()); } player = movePlayedCardsToLooser (player); } } else { TRACE2 ("Rovhult::makeMove (unsigned int) - play cards " << pos1Play << " to " << pos2Play); Check3 (pos1Play <= pos2Play); if (players[player].hand.size ()) { Check3 (pos2Play < players[player].hand.size ()); if (players[player].hand[pos1Play]->number () == cardNuke) { Check3 (players[player].hand[pos2Play]->number () == cardNuke); played.clear (); } player = executeMove (player, playCardsFromHand (player, pos1Play, pos2Play)); } else { Check3 (pos1Play <= pos2Play); Check3 (pos2Play < 3); for (unsigned int i (pos1Play); i <= pos2Play; ++i) players[player].reserve[i].getTopCard ().unmark (); // If cards are visible if (players[player].reserve[pos1Play].size () > 1) player = doPileSelected (player, pos2Play); // Execute move else { Check3 (pos1Play == pos2Play); // If card is valid: Play it CardWidget& card (players[player].reserve[pos2Play].getTopCard ()); if (cardValid (card.number (), true)) player = doPileSelected (player, pos2Play); else { // Card is not valid: Take up pile players[player].reserve[pos2Play].removeTopCard (); played.append (card); movePlayedCardsToLooser (player); player = executeMove (player, CardWidget::UNREACHABLE); } } } pos2Play = -1U; } return player;}//-----------------------------------------------------------------------------/// Checks if there are only special cards up to the passed position/// \param pile: Pile to inspect/// \param start: Lower position of cards to inspect/// \param end: Upper position of cards to inspect/// \returns \c bool: True, if there are only special cards//-----------------------------------------------------------------------------bool Rovhult::existOnlySpecialCards (const ICardPile& pile, unsigned int start, unsigned int end) const { Check3 (start <= end); Check3 (end < pile.size ()); do { if (!isSpecialCard (pile[start]->number ())) return false; } while (++start <= end); TRACE8 ("Rovhult::existOnlySpecialCards (const ICardPile&, unsigned int) - Yes"); return true;}//-----------------------------------------------------------------------------/// Finds the next card to play (for a computer controlled player)/// \param player: Player to inspect/// \param start: Position of (first) card to play/// \param end: Position of (last) card to play//-----------------------------------------------------------------------------void Rovhult::findCard2Play (unsigned int player, unsigned int& start, unsigned int& end) const { TRACE2 ("Rovhult::findCard2Play (unsigned int) - Player " << player); Check3 (player < NUM_PLAYERS); // Search for minimal card to play; this is either a card equal or // bigger or - if no previous card is played or the last card // played was a cardReverse (7) - the smallest available CardWidget::NUMBERS cardMin (CardWidget::THREE); if (played.size () && (played.getTopCard ().number () != cardReverse) && (played.getTopCard ().number () != CardWidget::TWO)) cardMin = played.getTopCard ().number (); TRACE5 ("Rovhult::findCard2Play (unsigned int) - Card to beat " << cardMin); // Check if to play from hand or to play from reserve unsigned int nrCards (players[player].hand.size ()); if (nrCards) { // Special handling if cards of next player are know: Try to give him // the whole pile CardWidget::NUMBERS nextMin, nextMax; int hpPos (-1); start = (played.size () && getPileLimits (nextAvailablePlayer (player), nextMin, nextMax) && (((nextMin > cardReverse) && ((hpPos = players[player].hand.find (cardReverse)) =! -1)) || (((hpPos = (players[player].hand.findFirstEqualOrBigger (CardWidget::NUMBERS (nextMax + 1)))) != -1) && ((hpPos = skip (cardReverse, players[player].hand, hpPos)) != -1) && ((hpPos = skip (cardNuke, players[player].hand, hpPos)) != -1)) && cardValid (players[player].hand[hpPos]->number (), true))) ? hpPos : players[player].hand.findFirstEqualOrBigger (cardMin); TRACE6 ("Rovhult::findCard2Play (unsigned int) - First matching card" " at pos " << start); // Check if no matching normal card is found or found card is // bigger than the played cardReverse (7). If so, use special // card instead We know one card must match as // playerCanContinue() reported this player as valid if ((start == -1U) || (played.size () && ((played.getTopCard ().number () == cardReverse) && players[player].hand[start]->number () > cardReverse))) { TRACE7 ("Rovhult::findCard2Play (unsigned int) - Ordinary cards don't" " match -> Searching for special card"); if (players[player].hand[0]->number () == CardWidget::TWO) start = 0; else { start = players[player].hand.findFirstEqualOrBigger (cardNuke);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -