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

📄 hearts.cpp

📁 一个扑克牌游戏集合的源码,包含了很多基本c-c++语言应用
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//$Id: Hearts.cpp,v 1.51 2006/08/09 16:33:32 markus Rel $//PROJECT     : Cardgames//SUBSYSTEM   : Hearts//REFERENCES  ://TODO        ://BUGS        ://REVISION    : $Revision: 1.51 $//AUTHOR      : Markus Schwab//CREATED     : 24.12.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 <sstream>#include <cardgames-cfg.h>#include <gtkmm/menu.h>#include <gtkmm/stock.h>#include <gtkmm/statusbar.h>#include <gtkmm/messagedialog.h>#include <YGP/Check.h>#include <YGP/Trace.h>#include <YGP/ConnMgr.h>#include <YGP/Tokenize.h>#include <Player.h>#include <ScoreDlg.h>#include "Hearts.h"const unsigned int Hearts::COLS_PLAYER[NUM_PLAYERS] = { 5, 3, 5, 9 };const unsigned int Hearts::ROWS_PLAYER[NUM_PLAYERS] = { 3, 7, 10, 7 };unsigned int Hearts::ENDPOINTS (100);//-----------------------------------------------------------------------------/// Constructor/// \param parent: Parent widget to display the game in/// \param statusbar: Status bar widget to display information about the game/// \param cardset: Cardset to use/// \param player: Vector of player/// \param posPlayer: Position of player for the server/// \param mxSerialize: Mutex to serialize messages from the server//-----------------------------------------------------------------------------Hearts::Hearts (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, 18, 12),     playedSQ (false), player2Exchange (3),     played (ICardPile::COMPRESSED, ICardPile::SHOWFACE),     pScoreDlg (NULL) {   TRACE9 ("Hearts::Hearts (Box&, Statusbar&, CardSet&, ...");   CardHPile* hand0 (new CardHPile); players[0].hand = hand0;   CardHPile* won0 (new CardHPile); players[0].won = won0;   CardHPile* hand2 (new CardHPile); players[2].hand = hand2;   CardHPile* won2 (new CardHPile); players[2].won = won2;   CardVPile* hand1 (new CardVPile); players[1].hand = hand1;   CardVPile* won1 (new CardVPile); players[1].won = won1;   CardVPile* hand3 (new CardVPile); players[3].hand = hand3;   CardVPile* won3 (new CardVPile); players[3].won = won3;   int width (cards.getCard (0).getImageWidth ());   int height (cards.getCard (0).getImageHeight ());   attach (*won0, COLS_PLAYER[0], COLS_PLAYER[0] + 3,	   ROWS_PLAYER[0] - 2, ROWS_PLAYER[0] - 1, Gtk::EXPAND);   attach (*hand0, COLS_PLAYER[0], COLS_PLAYER[0] + 3,	   ROWS_PLAYER[0], ROWS_PLAYER[0] + 1, Gtk::EXPAND);   won0->set_size_request (width + 12 * 7, height + 5);   hand0->set_size_request (width + 12 * 18, height + 5);   attach (*won1, COLS_PLAYER[1] - 2, COLS_PLAYER[1] - 1,	   ROWS_PLAYER[1], ROWS_PLAYER[1] + 1, Gtk::EXPAND);   attach (*hand1, COLS_PLAYER[1], COLS_PLAYER[1] + 1,	   ROWS_PLAYER[1], ROWS_PLAYER[1] + 1, Gtk::EXPAND);   won1->set_size_request (width + 5, height + 12 * 7);   hand1->set_size_request (width + 5, height + 12 * 7);   attach (*won2, COLS_PLAYER[2], COLS_PLAYER[2] + 3,	   ROWS_PLAYER[2] + 4, ROWS_PLAYER[2] + 5, Gtk::EXPAND);   attach (*hand2, COLS_PLAYER[2], COLS_PLAYER[2] + 3,	   ROWS_PLAYER[2], ROWS_PLAYER[2] + 1, Gtk::EXPAND);   won2->set_size_request (width + 12 * 7, height + 5);   hand2->set_size_request (width + 12 * 18, height + 5);   attach (*won3, COLS_PLAYER[3] + 2, COLS_PLAYER[3] + 3,	   ROWS_PLAYER[3], ROWS_PLAYER[3] + 1, Gtk::EXPAND);   attach (*hand3, COLS_PLAYER[3], COLS_PLAYER[3] + 1,	   ROWS_PLAYER[3], ROWS_PLAYER[3] + 1, Gtk::EXPAND);   won3->set_size_request (width + 5, height + 12 * 7);   hand3->set_size_request (width + 5, height + 12 * 7);   // Show and attach card-piles   changeNames (player);   for (unsigned int i (0); i < NUM_PLAYERS; ++i) {      attach (players[i].name, COLS_PLAYER[i], COLS_PLAYER[i] + ((i & 1) ? 1 : 3),	      ROWS_PLAYER[i] + 2, ROWS_PLAYER[i] + 3,              Gtk::EXPAND, Gtk::EXPAND, 1);      players[i].won->setShowOption (ICardPile::SHOWBACK);      players[i].hand->setShowOption (i ? ICardPile::SHOWBACK : ICardPile::SHOWFACE);      players[i].hand->setStyle ((i & 1) ? ICardPile::QUITE_COMPRESSED : ICardPile::COMPRESSED);      players[i].won->setStyle (ICardPile::VERY_COMPRESSED);   }   // Show played area   played.setStyle (ICardPile::COMPRESSED);   attach (played, 6, 7, 7, 8, Gtk::SHRINK, Gtk::SHRINK, 5);   played.set_size_request (width + 150, height);   show_all ();}//-----------------------------------------------------------------------------/// Destructor//-----------------------------------------------------------------------------Hearts::~Hearts () {   TRACE9 ("Hearts::~Hearts ()");   delete pScoreDlg;   clean ();}//-----------------------------------------------------------------------------/// Makes the move for the next player./// \param player: Actual player/// \returns \c int: Next player or -1 if end of game//-----------------------------------------------------------------------------int Hearts::makeMove (unsigned int player) {   TRACE5 ("Hearts::makeMove () - Turn of player " << player);   Check1 (gameStatus () == PLAYING);   Check3 (pos2Play == pos1Play);   if (pos2Play == -1U) {      pos2Play = pos1Play = findPos2Play (player);      TRACE8 ("Hearts::makeMove (unsigned int) - Going to play card at pos " << pos2Play);      flipCards2Play (*players[player].hand, pos1Play, pos2Play);   }   else {      TRACE9 ("Hearts::makeMove (unsigned int) - Playing card at pos " << pos2Play);      ICardPile& pile (*players[player].hand);      Check3 (pos2Play < pile.size ());      aPlayed[pile[pos2Play]->colour ()]++;      if ((pile[pos2Play]->colour () == CardWidget::SPADES)          && (pile[pos2Play]->number () == CardWidget::QUEEN))          playedSQ = true;      movePile (played, pile, pos1Play, pos2Play);      pos1Play = pos2Play = -1U;      player = calcNextPlayer (player);   }   return player;}//-----------------------------------------------------------------------------/// Starts the game by dealing the cards//-----------------------------------------------------------------------------void Hearts::start () {   TRACE9 ("Hearts::start ()");   Game::start ();   // Hide won pile again (if not in debug-mode)#if TRACELEVEL > 0   if (players[1].won->getShowOption () == ICardPile::SHOWBACK)#endif      showWonCards (false);   Check2 (!played.size ());   ICardPile pile;   if (randomizeCardsToPile (pile)) {      for (unsigned int i (0); i < NUM_PLAYERS; ++i)         for (unsigned int j (0); j < (cards.size () / NUM_PLAYERS); ++j)            players[(i - posServer) & 0x3].hand->insertColourSorted (pile.removeTopCard ());      if (pScoreDlg) {         unsigned int player;         int points;         pScoreDlg->getMaxPoints (points, player);         if ((unsigned int)points >= ENDPOINTS) {             delete pScoreDlg;             pScoreDlg = NULL;         }      }      if (player2Exchange) {         Glib::ustring stat (_("Select 3 cards to exchange with %1"));         Check3 (actPlayers.size () > player2Exchange);         Check3 (actPlayers[player2Exchange & 0x3]);         stat.replace (stat.find ("%1"), 2,                       actPlayers[player2Exchange]->getName ());         status.pop ();         status.push (stat);         setGameStatus (EXCHANGE);         setNextPlayer (0);         enableHuman ();      }      else         startPlaying ();   }}//-----------------------------------------------------------------------------/// Remove cards from everything which can hold them//-----------------------------------------------------------------------------void Hearts::clean () {   TRACE9 ("Hearts::clean ()");   for (unsigned int i (0); i < NUM_PLAYERS; ++i) {      players[i].hand->clear ();      players[i].won->clear ();   }   played.clear ();   disableHuman ();   Game::clean ();}//-----------------------------------------------------------------------------/// Shows or hides the cards of the computer player/// \param open: Flag if cards should be shown or hidden//-----------------------------------------------------------------------------void Hearts::playOpen (bool open) {   for (unsigned int i (1); i < NUM_PLAYERS; ++i) {      players[i].hand->setShowOption (open ? ICardPile::SHOWFACE : ICardPile::SHOWBACK);      players[i].hand->setStyle (open ? ICardPile::COMPRESSED : ICardPile::QUITE_COMPRESSED);      players[i].won->setShowOption (open ? ICardPile::SHOWFACE : ICardPile::SHOWBACK);      players[i].won->setStyle (open ? ICardPile::COMPRESSED : ICardPile::VERY_COMPRESSED);   }   players[0].won->setShowOption (open ? ICardPile::SHOWFACE : ICardPile::SHOWBACK);   players[0].won->setStyle (open ? ICardPile::COMPRESSED : ICardPile::VERY_COMPRESSED);}//-----------------------------------------------------------------------------/// Enables the cards of the human player/// \returns \c Flag, if time should be continued/// \remarks Depending of the status of the game (PLAYING2) also the top card///     of the played pile is enabled//-----------------------------------------------------------------------------bool Hearts::enableHuman () {   Check3 (activeCards.empty ());   Check3 ((gameStatus () == PLAYING) || (gameStatus () == EXCHANGE));   TRACE2 ("Hearts::enableHuman () - Human has " << players[0].hand->size () << " cards");   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, (&Hearts::cardSelected)), i)));   if (gameStatus () == EXCHANGE)      for (int i (played.size () - 1); i >= 0; --i)         activeCards.push_back            (played[i]->signal_clicked ().connect             (bind (mem_fun (*this, (&Hearts::takeCard)), i)));   return Game::enableHuman ();}//-----------------------------------------------------------------------------/// Callback after clicking on a card in the played field/// \param iCard: Offset of card in hand//-----------------------------------------------------------------------------void Hearts::takeCard (unsigned int iCard) {   TRACE9 ("Hearts::takeCard (unsigned int) - Picking up card " << iCard);   Check1 (iCard < played.size ());   Check1 (gameStatus () == EXCHANGE);   movePile (*players[0].hand, played, iCard, iCard);   players[0].hand->sortByColour ();   makeNextMoves ();}//-----------------------------------------------------------------------------/// Callback after clicking on a card in hand/// \param iCard: Offset of card in hand//-----------------------------------------------------------------------------void Hearts::cardSelected (unsigned int iCard) {   TRACE5 ("Hearts::cardSelected (unsigned int) - Position " << iCard);   Check1 (iCard < players[0].hand->size ());   Check3 ((gameStatus () == PLAYING) || (gameStatus () == EXCHANGE));   Check3 (pos1Play == -1U);   Check3 (pos2Play == -1U);   // Hide won pile again (if not in debug-mode)#if TRACELEVEL > 0   if (players[1].won->getShowOption () == ICardPile::SHOWBACK)#endif      showWonCards (false);   if (moveSelectedCardToPlayed (0, iCard)) {      if (gameStatus () == PLAYING) {         if (getConnectionMgr ().getMode () != YGP::ConnectionMgr::NONE) {            // Send played card to all clients (if any)            std::ostringstream msg;            msg << "Play=" << played[played.size () - 1]->id () << ";Target=0";            if (getConnectionMgr ().getMode () == YGP::ConnectionMgr::CLIENT)               ignoreNextMsg = true;            broadcastMessage (msg.str ());         }         setNextPlayer (calcNextPlayer (currentPlayer ()));      }      else {         Check3 (gameStatus () == EXCHANGE);         if (played.size () == 3) {            // Exchange the cards in pre-play            TRACE7 ("Hearts::cardSelected (unsigned int) - Finished exchange");            if (getConnectionMgr ().getMode () == YGP::ConnectionMgr::NONE) {               exchangeCards ();               startPlaying ();            }            else {               std::ostringstream msg;               msg << "Exchange=" << played[0]->id () << ' ' << played[1]->id ()                   << ' ' << played[2]->id () << ";Player=" << posServer;               broadcastMessage (msg.str ());               YGP::ConnectionMgr& cmgr (getConnectionMgr ());               if ((cmgr.getMode () == YGP::ConnectionMgr::SERVER)                   && cardsExchanged ((cmgr.getClients ().size () + 1) * 3)) {                  exchangeCards ();                  startPlaying ();               }               else {                  status.pop ();                  status.push (_("Waiting for other player to exchange their cards ..."));               }            }            disableHuman ();            return;         }      }      makeNextMoves ();   }}//-----------------------------------------------------------------------------/// Starts the playing phase of the game//-----------------------------------------------------------------------------void Hearts::startPlaying () {   TRACE7 ("Hearts::startPlaying ()");   // Clear variables for a new game   memset (aPlayed, 0, sizeof (aPlayed));

⌨️ 快捷键说明

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