/*************************************************************************** * Copyright (C) 2006 by FThauer FHammer * * f.thauer@web.de * * * * 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 "game.h" #include #include #include "localexception.h" #include "engine_msg.h" #include using namespace std; Game::Game(GuiInterface* gui, boost::shared_ptr factory, const PlayerDataList &playerDataList, const GameData &gameData, const StartData &startData, int gameId) : myFactory(factory), myGui(gui), currentHand(0), currentBoard(0), startQuantityPlayers(startData.numberOfPlayers), startCash(gameData.startMoney), startSmallBlind(gameData.firstSmallBlind), myGameID(gameId), currentSmallBlind(gameData.firstSmallBlind), currentHandID(0), dealerPosition(0), lastHandBlindsRaised(1), lastTimeBlindsRaised(0), myGameData(gameData) { blindsList = myGameData.manualBlindsList; if(DEBUG_MODE) { startSmallBlind = 10; currentSmallBlind = startSmallBlind; } int i; // determine dealer position PlayerDataList::const_iterator player_i = playerDataList.begin(); PlayerDataList::const_iterator player_end = playerDataList.end(); while (player_i != player_end) { if ((*player_i)->GetUniqueId() == startData.startDealerPlayerId) break; ++player_i; } if (player_i == player_end) throw LocalException(__FILE__, __LINE__, ERR_DEALER_NOT_FOUND); dealerPosition = startData.startDealerPlayerId; // create board currentBoard = myFactory->createBoard(); // create player lists seatsList = PlayerList(new std::list >); activePlayerList = PlayerList(new std::list >); runningPlayerList = PlayerList(new std::list >); // create player player_i = playerDataList.begin(); player_end = playerDataList.end(); for(i=0; i myNetSession; if (player_i != player_end) { uniqueId = (*player_i)->GetUniqueId(); type = (*player_i)->GetType(); myName = (*player_i)->GetName(); myAvatarFile = (*player_i)->GetAvatarFile(); myNetSession = (*player_i)->GetNetSessionData(); // TODO: set player type ++player_i; } // create player objects boost::shared_ptr tmpPlayer = myFactory->createPlayer(currentBoard, i, uniqueId, type, myName, myAvatarFile, startCash, startQuantityPlayers > i, 0); tmpPlayer->setNetSessionData(myNetSession); // fill player lists seatsList->push_back(tmpPlayer); if(startQuantityPlayers > i) { activePlayerList->push_back(tmpPlayer); } (*runningPlayerList) = (*activePlayerList); } currentBoard->setPlayerLists(seatsList, activePlayerList, runningPlayerList); //start timer blindsTimer.reset(); blindsTimer.start(); } Game::~Game() { delete currentBoard; currentBoard = 0; delete currentHand; currentHand = 0; } HandInterface *Game::getCurrentHand() { return currentHand; } const HandInterface *Game::getCurrentHand() const { return currentHand; } void Game::initHand() { size_t i; PlayerListConstIterator it_c; PlayerListIterator it; currentHandID++; // calculate smallBlind raiseBlinds(); // set player action none for(it=seatsList->begin(); it!=seatsList->end(); it++) { (*it)->setMyAction(PLAYER_ACTION_NONE); } // set player with empty cash inactive it = activePlayerList->begin(); while( it!=activePlayerList->end() ) { if((*it)->getMyCash() == 0) { (*it)->setMyActiveStatus(false); it = activePlayerList->erase(it); } else { it++; } } // delete possible existing hands if(currentHand) { delete currentHand; currentHand = 0; } runningPlayerList->clear(); (*runningPlayerList) = (*activePlayerList); // create Hand currentHand = myFactory->createHand(myFactory, myGui, currentBoard, seatsList, activePlayerList, runningPlayerList, currentHandID, startQuantityPlayers, dealerPosition, currentSmallBlind, startCash); // shifting dealer button -> TODO exception-rule !!! bool nextDealerFound = false; PlayerListConstIterator dealerPositionIt = currentHand->getSeatIt(dealerPosition); if(dealerPositionIt == seatsList->end()) { throw LocalException(__FILE__, __LINE__, ERR_SEAT_NOT_FOUND); } for(i=0; isize(); i++) { dealerPositionIt++; if(dealerPositionIt == seatsList->end()) dealerPositionIt = seatsList->begin(); it_c = currentHand->getActivePlayerIt( (*dealerPositionIt)->getMyUniqueID() ); if(it_c != activePlayerList->end() ) { nextDealerFound = true; dealerPosition = (*it_c)->getMyUniqueID(); break; } } if(!nextDealerFound) { throw LocalException(__FILE__, __LINE__, ERR_NEXT_DEALER_NOT_FOUND); } } void Game::startHand() { myGui->nextRoundCleanGui(); // log new hand myGui->logNewGameHandMsg(myGameID, currentHandID); myGui->flushLogAtGame(myGameID); currentHand->start(); } boost::shared_ptr Game::getPlayerByUniqueId(unsigned id) { boost::shared_ptr tmpPlayer; PlayerListIterator i = getSeatsList()->begin(); PlayerListIterator end = getSeatsList()->end(); while (i != end) { if ((*i)->getMyUniqueID() == id) { tmpPlayer = *i; break; } ++i; } return tmpPlayer; } boost::shared_ptr Game::getCurrentPlayer() { boost::shared_ptr tmpPlayer = getPlayerByUniqueId(getCurrentHand()->getCurrentBeRo()->getCurrentPlayersTurnId()); if (!tmpPlayer.get()) throw LocalException(__FILE__, __LINE__, ERR_CURRENT_PLAYER_NOT_FOUND); return tmpPlayer; } void Game::raiseBlinds() { bool raiseBlinds = false; if (myGameData.raiseIntervalMode == RAISE_ON_HANDNUMBER) { if (lastHandBlindsRaised + myGameData.raiseSmallBlindEveryHandsValue <= currentHandID) { raiseBlinds = true; lastHandBlindsRaised = currentHandID; } } else { if (lastTimeBlindsRaised + myGameData.raiseSmallBlindEveryMinutesValue <= blindsTimer.elapsed().total_seconds()/60) { raiseBlinds = true; lastTimeBlindsRaised = blindsTimer.elapsed().total_seconds()/60; } } if (raiseBlinds) { // At this point, the blinds must be raised // Now we check how the blinds should be raised if (myGameData.raiseMode == DOUBLE_BLINDS) { currentSmallBlind *= 2; } else { if(!blindsList.empty()) { currentSmallBlind = blindsList.front(); blindsList.pop_front(); } else { // The position exceeds the list if (myGameData.afterManualBlindsMode == AFTERMB_DOUBLE_BLINDS) { currentSmallBlind *= 2; } else { if(myGameData.afterManualBlindsMode == AFTERMB_RAISE_ABOUT) { currentSmallBlind += myGameData.afterMBAlwaysRaiseValue; } } } } } }