twopart.cpp
来自「一个扑克牌游戏集合的源码,包含了很多基本c-c++语言应用」· C++ 代码 · 共 1,255 行 · 第 1/4 页
CPP
1,255 行
//$Id: Twopart.cpp,v 1.73 2006/06/05 21:38:20 markus Rel $//PROJECT : Cardgames//SUBSYSTEM : Twopart//REFERENCES ://TODO ://BUGS ://REVISION : $Revision: 1.73 $//AUTHOR : Markus Schwab//CREATED : 20.7.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 <ctime>#include <cstdlib>#include <sstream>#include <glibmm/main.h>#include <gtkmm/box.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 <CardSet.h>#include <CardWidget.h>#include "Twopart.h"const unsigned int Twopart::COLS_PLAYER[NUM_PLAYERS] = { 7, 1, 7, 13 };const unsigned int Twopart::ROWS_PLAYER[NUM_PLAYERS] = { 4, 8, 10, 8 };char Twopart::sortOrder[4];//-----------------------------------------------------------------------------/// Defaultconstructor; all widget are created/// \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 players: Vector of player/// \param posPlayer: Position of player for the server/// \param mxSerialize: Mutex to serialize messages from the server//-----------------------------------------------------------------------------Twopart::Twopart (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, 12, 15) , bfPlayers ((1 << NUM_PLAYERS) - 1), offPos (0) , bfOldPlayers (bfPlayers), pTrump (NULL) , played (ICardPile::COMPRESSED, ICardPile::SHOWFACE) , staple (ICardPile::VERY_COMPRESSED, ICardPile::SHOWBACK) { staple.show (); attach (staple, 2, 3, 2, 3, Gtk::SHRINK, Gtk::SHRINK, 5, 5); 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) { players[i].name.show (); attach (players[i].name, COLS_PLAYER[i], COLS_PLAYER[i] + 3, ROWS_PLAYER[i] + ((i == 2) ? 3 : 1), ROWS_PLAYER[i] + ((i == 2) ? 4 : 2), Gtk::EXPAND, Gtk::EXPAND, 1); TRACE9 ("Twopart::Twopart () - Name at: " << COLS_PLAYER[i] << '/' << ROWS_PLAYER[i] + ((i == 2) ? 3 : 1)); players[i].won.show (); attach (players[i].won, COLS_PLAYER[i] + 1, COLS_PLAYER[i] + 2, ROWS_PLAYER[i] + ((i == 2) ? 2 : -2), ROWS_PLAYER[i] + ((i == 2) ? 3 : -1), Gtk::SHRINK, Gtk::SHRINK, 1); TRACE9 ("Twopart::Twopart () - Won pile at: " << COLS_PLAYER[i] + 1 << '/' << ROWS_PLAYER[i] + ((i == 2) ? 2 : -2)); players[i].hand.show (); attach (players[i].hand, COLS_PLAYER[i], COLS_PLAYER[i] + 3, ROWS_PLAYER[i], ROWS_PLAYER[i] + 1, Gtk::SHRINK, Gtk::SHRINK, 1); TRACE9 ("Twopart::Twopart () - Hand at: " << COLS_PLAYER[i] << '/' << ROWS_PLAYER[i]); players[i].won.setShowOption (ICardPile::SHOWBACK); players[i].hand.setShowOption (i ? ICardPile::SHOWBACK : ICardPile::SHOWFACE); players[i].won.set_size_request (width + 20, height + 5); players[i].hand.set_size_request (width * 3, height + 5); } played.show (); attach (played, 3, 11, 6, 9, Gtk::SHRINK, Gtk::SHRINK, 0, 5); played.set_size_request (width + 150, height); staple.set_size_request (width, height);}//-----------------------------------------------------------------------------/// Destructor//-----------------------------------------------------------------------------Twopart::~Twopart () { TRACE9 ("Twopart::~Twopart ()"); clean ();}//-----------------------------------------------------------------------------/// Starts the game//-----------------------------------------------------------------------------void Twopart::start () { TRACE8 ("Twopart::start ()"); Game::start (); if (randomizeCardsToPile (staple)) { // Show cards on the table: For all players put 3 cards in hand for (unsigned int i (0); i < NUM_PLAYERS; ++i) for (unsigned int j (0); j < 3; ++j) players[(i - posServer) & 0x3].hand.insertSorted (staple.removeTopCard ()); for (unsigned int i (0); i < (NUM_PLAYERS - 1); ++i) startPos[i] = 0; offPos = 0; bfPlayers = bfOldPlayers = (1 << NUM_PLAYERS) - 1; for (unsigned int i (1); i < NUM_PLAYERS; ++i) { players[i].hand.setStyle (ICardPile::COMPRESSED); players[i].won.setStyle (ICardPile::VERY_COMPRESSED); } players[0].hand.setStyle (ICardPile::NORMAL); players[0].won.setStyle (ICardPile::QUITE_COMPRESSED); pos1Play = pos2Play = -1U; if (getConnectionMgr ().getMode () != YGP::ConnectionMgr::CLIENT) { setNextPlayer (startPlayer = rand () & 0x3); broadcastStartPlayer (startPlayer); displayTurn (currentPlayer ()); makeNextMoves (); } }}//-----------------------------------------------------------------------------/// Enables the cards of the passed player/// \returns bool: Flag, if timer should be continued; False/// \remarks Depending of the status of the game (PLAYING2) also the top card/// of the played pile is enabled//-----------------------------------------------------------------------------bool Twopart::enableHuman () { Check3 (activeCards.empty ()); Check3 (gameStatus () >= PLAYING); TRACE2 ("Twopart::enableHuman () - 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, (&Twopart::cardSelected)), i))); if ((gameStatus () == PLAYING2) && (played.size ())) activeCards.push_back (played.getTopCard ().signal_clicked ().connect (mem_fun (*this, (&Twopart::playedSelected)))); return Game::enableHuman ();}//-----------------------------------------------------------------------------/// Moving played cards (of last person) to the passed player/// \param player: ID of player who should get the cards/// \returns unsigned int: Next player/// \pre Call only in part 2 of the game//-----------------------------------------------------------------------------unsigned int Twopart::pickUpPlayedPile (unsigned int player) { TRACE3 ("Twopart::pickUpPlayedPile (unsigned int) - Player " << player << " picks up played pile"); Check3 (gameStatus () == PLAYING2); Check3 (bfPlayers); // Move played cards to player Check3 (offPos > 0); Check3 (offPos < NUM_PLAYERS); movePlayedCardsToPlayer (player, startPos[--offPos]); removePlayer (player); // Calculate players to re-enable: They are the number of players still // in game (with cards) minus the players still in round; but maximal 2 unsigned int num (0); for (unsigned int i (0); i < NUM_PLAYERS; ++i) if (players[i].hand.size ()) ++num; num -= playersInBitfield (bfPlayers); if (num > 2) num = 2; TRACE8 ("Twopart::pickUpPlayedPile (unsigned int) - Adding " << num << " players to left " << playersInBitfield (bfPlayers)); // Re-enable next two players (having cards); continue with first of them unsigned int next; for (unsigned int i (0); num; ++i) { Check3 (i < NUM_PLAYERS); if ((!(bfPlayers & (1 << (next = (player + i + 1) & 0x3)))) && players[next].hand.size ()) { TRACE5 ("Twopart::pickUpPlayedPile (unsigned int) - Re-adding player " << next); addPlayer (next); --num; } } Glib::ustring stat ( _("%1 can't continue -> Picking up last cards; ")); Check3 (actPlayers.size () > player); Check3 (actPlayers[player]); stat.replace (stat.find ("%1"), 2, actPlayers[player]->getName ()); player = findNextPlayer (player); displayTurn (player, stat); return player;}//-----------------------------------------------------------------------------/// Callback after clicking the top card of the played pile/// \pre Call only in part 2 of the game//-----------------------------------------------------------------------------void Twopart::playedSelected () { TRACE3 ("Twopart::playedSelected (unsigned int) - Human picks up played pile"); Check3 (gameStatus () == PLAYING2); Check3 (bfPlayers); if (getConnectionMgr ().getMode () != YGP::ConnectionMgr::NONE) { Check3 (startPos[offPos - 1] < played.size ()); std::ostringstream msg; msg << "Play=" << played[startPos[offPos - 1]]->id () << ";Target=1"; if (getConnectionMgr ().getMode () == YGP::ConnectionMgr::CLIENT) ignoreNextMsg = true; broadcastMessage (msg.str ()); } setNextPlayer (pickUpPlayedPile (0)); makeNextMoves (); disableHuman ();}//-----------------------------------------------------------------------------/// Callback after clicking on a card in hand/// \param player: ID of player/// \param start: Offset of first card to play/// \param end: Offset of last card to play/// \returns bool: Status of moving; true: Card could be moved; false else//-----------------------------------------------------------------------------bool Twopart::moveSelectedCardToPlayed (unsigned int player, unsigned int start, unsigned int end) { TRACE5 ("Twopart::moveSelectedCardToPlayed (unsigned int, unsigned int) - Player: " << player << " at position " << start << " to " << end); Check3 (player < NUM_PLAYERS); Check3 (end < players[player].hand.size ()); Check3 (start <= end); Check3 (gameStatus () >= PLAYING); if (gameStatus () == PLAYING) { Check3 (start == end); TRACE8 ("Twopart::moveSelectedCardToPlayed (unsigned int, unsinged int)" " - Player " << player << "; Card at " << end << " = " << *players[player].hand[end]); movePile (played, players[player].hand, start, end); if (staple.size ()) { CardWidget& card (staple.removeShownTopCard ()); players[player].hand.insertSorted (card); if (!staple.size ()) { Check3 (!pTrump); pTrump = new CardWidget (card); Check3 (pTrump); staple.hide (); } } } else { if (offPos < (NUM_PLAYERS - 1)) startPos[offPos++] = played.size ();#if TRACELEVEL > 8 for (unsigned int i (0); i < (NUM_PLAYERS - 1); ++i) TRACE ("Twopart::moveSelectedCardToPlayed (unsigned int, unsinged int) - " << i << ". Position: " << startPos[i]);#endif movePile (played, players[player].hand, start, end); } return true;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?