📄 rovhult.cpp
字号:
//$Id: Rovhult.cpp,v 1.94 2006/08/03 18:15:05 markus Rel $//PROJECT : Cardgames//SUBSYSTEM : Rovhult//REFERENCES ://TODO ://BUGS ://REVISION : $Revision: 1.94 $//AUTHOR : Markus Schwab//CREATED : 28.3.2002//COPYRIGHT : Copyright (C) 2002 - 2006// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.#include <cardgames-cfg.h>#include <sstream>#include <gtk/gtkdnd.h>#include <glibmm/main.h>#include <gtkmm/statusbar.h>#include <gtkmm/accelgroup.h>#include <gtkmm/messagedialog.h>#include <YGP/Check.h>#include <YGP/Trace.h>#include <YGP/ConnMgr.h>#include <YGP/Tokenize.h>#include <CardValue.h>#include <CardWidget.h>#include <ComputerPlayer.h>#include "Rovhult.h"std::vector<Gtk::TargetEntry> Rovhult::dndTypeHand;std::vector<Gtk::TargetEntry> Rovhult::dndTypeTable;const unsigned int Rovhult::COLS_PLAYER[NUM_PLAYERS] = { 7, 1, 7, 13 };const unsigned int Rovhult::ROWS_PLAYER[NUM_PLAYERS] = { 4, 7, 13, 7 };CardWidget::NUMBERS Rovhult::cardNuke (CardWidget::TEN);CardWidget::NUMBERS Rovhult::cardSkip (CardWidget::EIGHT);CardWidget::NUMBERS Rovhult::cardReverse (CardWidget::SEVEN);//-----------------------------------------------------------------------------/// Defaultconstructor; all widgets are created/// \param parent: Parent widget (box) to display the game in/// \param statusbar: Status bar widget to display information about the game/// \param cardset: Cardset to use/// \param names: Vector of players/// \param posPlayer: Position of player for the server/// \param mxSerialize: Mutex to serialize messages from the server//-----------------------------------------------------------------------------Rovhult::Rovhult (Gtk::Box& parent, Gtk::Statusbar& statusbar, CardSet& cardset, const std::vector<Player*>& player, unsigned int posPlayer, YGP::Mutex& mxSerialize) : Game (parent, statusbar, cardset, player, posPlayer, mxSerialize, 16, 20) , played (ICardPile::VERY_COMPRESSED, ICardPile::SHOWFACE) , staple (ICardPile::VERY_COMPRESSED) , aExchanged (0) { TRACE9 ("Rovhult::Rovhult (Gtk::Box& Gtk::Statusbar&, CardSet&," " const std::vector<Glib::ustring>&)"); staple.show (); attach (staple, 3, 4, 2, 7); Check3 (cards.size ()); int width (cards.getCard (0).getImageWidth ()); int height (cards.getCard (0).getImageHeight ()); // Show and attach card-piles changeNames (player); for (unsigned int i (0); i < NUM_PLAYERS; ++i) { for (int j (0); j < 3; ++j) { players[i].reserve[j].setStyle (ICardPile::QUITE_COMPRESSED); players[i].reserve[j].show (); attach (players[i].reserve[j], COLS_PLAYER[i] + (j << 1), COLS_PLAYER[i] + 1 + (j << 1), ROWS_PLAYER[i], ROWS_PLAYER[i] + 2, Gtk::SHRINK, Gtk::SHRINK, 0); TRACE9 ("Rovhult::Rovhult () - Set at: " << COLS_PLAYER[i] + (j << 1) << '/' << ROWS_PLAYER[i]); players[i].reserve[j].set_size_request (width, height + 7); } players[i].name.show (); attach (players[i].name, COLS_PLAYER[i], COLS_PLAYER[i] + 5, ROWS_PLAYER[i] + (i ? 5 : 2), ROWS_PLAYER[i] + (i ? 6 : 3), Gtk::EXPAND, Gtk::EXPAND, 1); players[i].hand.set_size_request (width * 3, height); players[i].hand.setStyle (i ? ICardPile::QUITE_COMPRESSED : ICardPile::NORMAL); players[i].hand.setShowOption (i ? ICardPile::SHOWBACK : ICardPile::SHOWFACE); players[i].hand.show (); attach (players[i].hand, COLS_PLAYER[i], COLS_PLAYER[i] + 5, ROWS_PLAYER[i] + (i ? 3 : -3), ROWS_PLAYER[i] + (i ? 3 : -3) + 2, Gtk::FILL | Gtk::EXPAND, Gtk::FILL | Gtk::EXPAND, 0); TRACE9 ("Rovhult::Rovhult () - 2nd set at: " << COLS_PLAYER[i] << '/' << ROWS_PLAYER[i] + (i ? 3 : -3)); } played.show (); played.set_size_request (width, height); staple.set_size_request (width, height + 50); staple.setShowOption (ICardPile::SHOWBACK); attach (played, 7, 11, 5, 14, Gtk::SHRINK, Gtk::SHRINK, 1); if (dndTypeHand.empty ()) { Check3 (dndTypeTable.empty ()); dndTypeHand.push_back (Gtk::TargetEntry ("icon/card/hand", Gtk::TARGET_SAME_APP, HAND)); dndTypeTable.push_back (Gtk::TargetEntry ("icon/card/table", Gtk::TARGET_SAME_APP, TABLE)); }}//-----------------------------------------------------------------------------/// Destructor//-----------------------------------------------------------------------------Rovhult::~Rovhult () { TRACE8 ("Rovhult::~Rovhult ()"); clean ();}//-----------------------------------------------------------------------------/// Starts the game//-----------------------------------------------------------------------------void Rovhult::start () { Game::start (); setGameStatus (EXCHANGE); if (randomizeCardsToPile (staple)) { dealCards (); pos1Play = pos2Play = -1U; aExchanged = 0; if (getConnectionMgr ().getMode () != YGP::ConnectionMgr::CLIENT) { setNextPlayer (rand () & 0x3); broadcastStartPlayer (currentPlayer ()); } }}//-----------------------------------------------------------------------------/// Callback after finishing card-exchange/// \param iCard: Offset of card in hand//-----------------------------------------------------------------------------void Rovhult::finishedExchange (unsigned int iCard) { unregisterDND (); disableHuman (); setGameStatus (EXCHANGED); sortReserve (0); players[0].hand.setStyle (ICardPile::COMPRESSED); sendExchangedCards (0); exchangeAutoplayerCards (); players[0].hand.sortByNumber (); sortReserve (0); players[0].hand.setStyle (ICardPile::COMPRESSED); status.pop (); displayTurn (currentPlayer ()); if ((getConnectionMgr ().getMode () == YGP::ConnectionMgr::NONE) || (aExchanged == 0xf)) { setGameStatus (PLAYING); makeNextMoves (); } else status.push (_("Waiting for other player to exchange their cards ..."));}//-----------------------------------------------------------------------------/// Values a card; this ranges from 3 to 9, J, K, A, 2, 10/// \param card: Card to value/// \returns unsigned int: Value representing the card//-----------------------------------------------------------------------------unsigned int Rovhult::getCardValue (const CardWidget& card) { return ((card.number () == CardWidget::TWO) ? CardWidget::ACE + 1 : (card.number () == cardNuke) ? CardWidget::ACE + 2 : card.number ());}//-----------------------------------------------------------------------------/// Compares two cards according the rules of Rovhult/// \param lhs, rhs: Cards to compare/// \returns \c int: >0, if number of lhs is smaller; 0 if equal or >0 if/// bigger//-----------------------------------------------------------------------------int Rovhult::compareCards (const CardWidget& lhs, const CardWidget& rhs) { return getCardValue (lhs) - getCardValue (rhs);}//-----------------------------------------------------------------------------/// Exchanges the cards of the computer-players/// \param player: Not really a void*, but actually the (next computer)player//-----------------------------------------------------------------------------void Rovhult::exchangeAutoplayerCards () { if (getConnectionMgr ().getMode () != YGP::ConnectionMgr::CLIENT) for (unsigned int i (getConnectionMgr ().getClients ().size () + 1); i < NUM_PLAYERS; ++i) { for (unsigned int j (0); j < 3; ++j) { unsigned int posPile (0); unsigned int posHand (0); // Search for smallest card in pile and biggest in hand for (unsigned int k (1); k < 3; ++k) { if (compareCards (players[i].reserve[k].getTopCard (), players[i].reserve[posPile].getTopCard ()) < 0) posPile = k; if (compareCards (*players[i].hand[k], *players[i].hand[posHand]) > 0) posHand = k; } // and exchange them, if hand is bigger than pile if (compareCards (players[i].reserve[posPile].getTopCard (), *players[i].hand[posHand]) < 0) { CardWidget& cardPile (players[i].reserve[posPile].removeTopCard ()); CardWidget& cardHand (players[i].hand.remove (posHand, true)); TRACE3 ("Rovhult::exchangeAutoplayerCards () - exchanging card " << cardHand << " in hand (" << posHand << ") with card on pile " << posPile << " (" << cardPile << ')'); // Swap cards players[i].reserve[posPile].setTopCard (cardHand); players[i].hand.insert (cardPile, posHand); } } Check3 (players[i].hand.size () == 3); Check3 (players[i].reserve[0].size () == 2); Check3 (players[i].reserve[1].size () == 2); Check3 (players[i].reserve[2].size () == 2); players[i].hand.sortByNumber (); sortReserve (i); sendExchangedCards (i); }}//----------------------------------------------------------------------------/// Broadcasts the exchanged cards to the clients/// \param player: Player whose cards to send//----------------------------------------------------------------------------void Rovhult::sendExchangedCards (unsigned int player) { // Send starting positions to the clients if (getConnectionMgr ().getMode () != YGP::ConnectionMgr::NONE) { std::ostringstream msg; msg << "Exchange=" << players[player].hand[0]->id () << ' ' << players[player].hand[1]->id () << ' ' << players[player].hand[2]->id () << ' ' << players[player].reserve[0].getTopCard ().id () << ' ' << players[player].reserve[1].getTopCard ().id () << ' ' << players[player].reserve[2].getTopCard ().id () << ";Player=" << ((player + posServer) & 0x3); if (getConnectionMgr ().getMode () == YGP::ConnectionMgr::CLIENT) ignoreNextMsg = true; broadcastMessage (msg.str ()); aExchanged |= (1 << player); }}//-----------------------------------------------------------------------------/// Sorts the cards on the reserve piles/// \param player: Player whose cards should be sorted//-----------------------------------------------------------------------------void Rovhult::sortReserve (unsigned int player) { // Sort cards on piles for (int j (0); j < 2; ++j) for (int k (j); k >= 0; --k) if (compareCards (players[player].reserve[k + 1].getTopCard (), players[player].reserve[k].getTopCard ()) < 0) { CardWidget& low (players[player].reserve[k + 1].removeTopCard ()); CardWidget& high (players[player].reserve[k].removeTopCard ()); TRACE3 ("Rovhult::exchangeAutoplayerCards () - exchanging card " << low << " on pile " << (k + 1) << " with card " << high << " on pile " << k); players[player].reserve[k + 1].setTopCard (high); players[player].reserve[k].setTopCard (low); }}//-----------------------------------------------------------------------------/// Enables the cards of the human player/// \param player: Player to enable//-----------------------------------------------------------------------------bool Rovhult::enableHuman () { Check3 (activeCards.empty ()); if (players[0].hand.size ()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -