📄 rovhult.cpp
字号:
TRACE2 ("Rovhult::enableHuman () - Has " << players[0].hand.size () << " card(s) in the hand"); 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, &Rovhult::handSelected), i))); } else { TRACE2 ("Rovhult::enableHuman () - Enable reserve of human"); for (int i (0); i < 3; ++i) if (players[0].reserve[i].size ()) { TRACE8 ("Rovhult::enableHuman () - Pile " << i << " has " << players[0].reserve[i].size () << " card(s)"); activeCards.push_back (players[0].reserve[i].getTopCard ().signal_clicked ().connect (bind (mem_fun (*this, &Rovhult::pileSelected), i))); } } if (played.size ()) { TRACE2 ("Rovhult::enablePlayer (unsigned int) - Enable last played card"); activeCards.push_back (played.getTopCard ().signal_clicked ().connect (mem_fun (*this, &Rovhult::takeCards))); } return Game::enableHuman ();}//-----------------------------------------------------------------------------/// Callback after clicking on a card on the table/// \param pile: Offset of selected pile//-----------------------------------------------------------------------------void Rovhult::pileSelected (unsigned int pile) { TRACE1 ("Rovhult::pileSelected (unsinged int) - Pile " << pile); Check3 (pile < 3); ICardPile& actPile (players[0].reserve[pile]); CardWidget& card (actPile.getTopCard ()); bool showsFace (card.showsFace ()); // If played from bottom of pile (with invisible cards): Flip card first if (!showsFace) { for (unsigned int i (0); i < 3; ++i) if (players[0].reserve[i].size () && players[0].reserve[i].getTopCard ().showsFace ()) { Gtk::MessageDialog dlg (_("You must first play the visible cards!"), Gtk::MESSAGE_ERROR); dlg.set_title (_("Invalid move")); dlg.run (); return; } card.showFace (); } TRACE1 ("Rovhult::pileSelected (unsinged int) - Card " << card); if (!cardValid (card.number ())) { // If selected card is not valid: Return if (!showsFace) { played.append (actPile.removeTopCard ()); // Inform the others about the move if (getConnectionMgr ().getMode () != YGP::ConnectionMgr::NONE) { // Send played card to all clients (if any) std::ostringstream msg; msg << "Play=" << card.id () << ";Target=" << (pile + 5); if (getConnectionMgr ().getMode () == YGP::ConnectionMgr::CLIENT) ignoreNextMsg = true; broadcastMessage (msg.str ()); } setNextPlayer (movePlayedCardsToLooser (0)); makeNextMoves (); } return; } // Inform the others about the move if (getConnectionMgr ().getMode () != YGP::ConnectionMgr::NONE) { // Send played card to all clients (if any) std::ostringstream msg; msg << "Play=" << card.id () << ";Target=" << (pile + 1); if (getConnectionMgr ().getMode () == YGP::ConnectionMgr::CLIENT) ignoreNextMsg = true; broadcastMessage (msg.str ()); } // If face of card was visible: Just go on (as the user knows what he has // selected); if not: Continue after GUI update. if (showsFace) playFromPile (pile); else Glib::signal_timeout ().connect (bind (mem_fun (*this, &Rovhult::playFromPile), pile), ComputerPlayer::TIMEOUT);}//-----------------------------------------------------------------------------/// Performs playing from a pile/// \param pile: Offset of selected pile/// \returns \c bool: Always false to stop the timer (if called from one,/// that's it)//-----------------------------------------------------------------------------bool Rovhult::playFromPile (unsigned int pile) { Check1 (pile < 3); TRACE1 ("Rovhult::playFromPile (unsinged int) - Card at pos " << pile); setNextPlayer (doPileSelected (0, pile)); makeNextMoves (); return false;}//-----------------------------------------------------------------------------/// Executes the move from a pile: Moves the cards and enables next/// \param player: ID of player/// \param pile: Offset of selected pile/// \returns \c int: player to continue//-----------------------------------------------------------------------------int Rovhult::doPileSelected (unsigned int player, unsigned int pile) { TRACE1 ("Rovhult::doPileSelected (unsigned int, unsinged int) - " << player << '/' << pile); Check1 (player < NUM_PLAYERS); Check1 (pile < 3); ICardPile* actPile (&players[player].reserve[pile]); Check3 (actPile->size ()); CardWidget& card (actPile->removeShownTopCard ()); // Move card (and visible cards with equal number on other piles) from // player to played staple if (card.number () == cardNuke) played.clear (); else played.append (card); while (pile) { actPile = &players[player].reserve[--pile]; if (actPile->size () && actPile->topCardShowsFace () && (actPile->getTopCard ().number () == card.number ())) { CardWidget& sameCard (actPile->removeShownTopCard ()); if (sameCard.number () != cardNuke) played.append (sameCard); } else break; } return executeMove (player, card.number ());}//-----------------------------------------------------------------------------/// Check if played card is valid (equal or bigger) The following cards have/// special meaning:/// - 2: Can be played always/// - cardReverse (7): The next card must be equal or *smaller*/// - cardSkip (8): Skips the next player/// - cardNuke (10): Clears the staple; the/// same player can continue with cards in hand/// \param nr: Card to check/// \param silent: Flag, if error should be displayed/// \returns \c bool: True, if card can be played//-----------------------------------------------------------------------------bool Rovhult::cardValid (CardWidget::NUMBERS nr, bool silent) const { TRACE5 ("Rovhult::cardValid (CardWidget::NUMBERS, bool) const - Checking " << nr << " in " << played.size () << " cards"); if ((nr != CardWidget::TWO) && (nr != cardNuke)) { if (played.size ()) { Glib::ustring error; CardWidget& lastPlayed (played.getTopCard ()); if (lastPlayed.number () == cardReverse) { if (nr > cardReverse) { error = _("After a %1, the played card must be equal or smaller!"); error.replace (error.find ("%1"), 2, CardValue::get ()[cardReverse]); } } else if (nr < lastPlayed.number ()) error = _("The played card must be equal or bigger!"); if (error.size ()) { if (!silent) { Gtk::MessageDialog dlg (error, Gtk::MESSAGE_ERROR); dlg.set_title (_("Invalid move")); dlg.run (); } return false; } } } return true;}//-----------------------------------------------------------------------------/// Callback after clicking on a card in hand/// \param pos: Offset of card in hand//-----------------------------------------------------------------------------void Rovhult::handSelected (unsigned int pos) { TRACE3 ("Rovhult::handSelected (unsinged int) - Checking card at " << pos); Check3 (pos < players[0].hand.size ()); CardWidget& card (*players[0].hand[pos]); TRACE1 ("Rovhult::handSelected (unsinged int) - Card " << pos << " = " << card); if (!cardValid (card.number ())) return; // Inform the others about the move unsigned int start (players[0].hand.findFirstEqual (pos)); if (getConnectionMgr ().getMode () != YGP::ConnectionMgr::NONE) { // Send played card to all clients (if any) std::ostringstream msg; msg << "Play="; for (unsigned int i (start); i < pos; ++i) msg << players[0].hand[i]->id () << ' '; msg << players[0].hand[pos]->id () << ";Target=0"; if (getConnectionMgr ().getMode () == YGP::ConnectionMgr::CLIENT) ignoreNextMsg = true; broadcastMessage (msg.str ()); } playCardsFromHand (0, start, pos); setNextPlayer (executeMove (0, card.number ())); makeNextMoves ();}//-----------------------------------------------------------------------------/// Move card (and cards with equal number below) from player to played/// staple. The cards are replaced, if the staple contains cards/// \param player: ID of player who played the last card/// \param start: Offset of first card in hand to play/// \param end: Offset of last card in hand to play/// \returns \c CardWidget::NUMBERS: Number of played card//-----------------------------------------------------------------------------CardWidget::NUMBERS Rovhult::playCardsFromHand (unsigned int player, unsigned int start, unsigned int end) { TRACE5 ("Rovhult::playCardsFromHand (unsigned int, unsigned int, unsigned int)" " - Player " << player << " from " << start << " to " << end); Check3 (end < players[player].hand.size ()); Check3 (start <= end); CardWidget::NUMBERS nr (players[player].hand[start]->number ()); do { CardWidget& movedCard (players[player].hand.remove (start)); if (movedCard.number () == cardNuke) played.clear (); else played.append (movedCard); } while (start < end--); // If staple contains cards and no 10 was played (except if hand is empty): // Fill up cards til player has 3 (or one, in case of a ten) if ((nr != cardNuke) || (!players[player].hand.size ())) fillUpPile (players[player].hand, (nr != cardNuke) ? 3 : 1); return nr;}//-----------------------------------------------------------------------------/// Executes the move -> Check consequences for next in round and calculate/// next player/// \param player: ID of player who played the last card/// \param nr: Played card/// \returns \c int: The next player//-----------------------------------------------------------------------------int Rovhult::executeMove (unsigned int player, CardWidget::NUMBERS nr) { TRACE3 ("Rovhult::executeMove (unsigned int, CardWidget::NUMBERS) - Player " << player << "; Card " << nr); Check3 (player < NUM_PLAYERS); Glib::ustring stat; // If last 4 cards have the same number or ten was played: Don't increase // player (except of course, if actual player don't have anymore cards) if (!((nr == cardNuke) || clearPlayedIf4Equal ()) || (static_cast<int> (player) != nextAvailablePlayer ((player - 1) & 0x3))) { player = nextAvailablePlayer (player); Check3 (actPlayers.size () > player); Check3 (actPlayers[player]); if (nextAvailablePlayer (player) == -1) { status.pop (); stat = _("%1 lost"); stat.replace (stat.find ("%1"), 2, actPlayers[player]->getName ()); status.push (stat); setGameStatus (STOPPED); return -1; } if (nr == cardSkip) { stat = _("Skipping %1; "); stat.replace (stat.find ("%1"), 2, actPlayers[player]->getName ()); player = nextAvailablePlayer (player); } } else stat = _("Pile cleared; "); displayTurn (player, stat); return player;}//-----------------------------------------------------------------------------/// Callback after selection top card on played pile -> Moves all its card to/// the passed player/// \param player: ID of player picking up the cards//-----------------------------------------------------------------------------void Rovhult::takeCards () { TRACE2 ("Rovhult::takeCards ()"); if (getConnectionMgr ().getMode () != YGP::ConnectionMgr::NONE) { std::ostringstream msg; msg << "Play=" << played.getTopCard ().id () << ";Target=4"; if (getConnectionMgr ().getMode () == YGP::ConnectionMgr::CLIENT) ignoreNextMsg = true; broadcastMessage (msg.str ()); } setNextPlayer (movePlayedCardsToLooser (0)); makeNextMoves ();}//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -