Files
pokerth/src/game.cpp
T

358 lines
11 KiB
C++
Raw Normal View History

2007-01-13 02:40:33 +00:00
/***************************************************************************
* 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 <enginefactory.h>
#include <guiinterface.h>
#include <iostream>
#include <sstream>
2007-01-13 20:47:48 +00:00
2007-01-13 02:40:33 +00:00
using namespace std;
Game::Game(GuiInterface* gui, boost::shared_ptr<EngineFactory> factory,
2007-09-29 00:08:19 +00:00
const PlayerDataList &playerDataList, const GameData &gameData,
const StartData &startData, int gameId)
: myFactory(factory), myGui(gui), actualHand(0), actualBoard(0),
startQuantityPlayers(startData.numberOfPlayers),
2007-05-23 22:31:56 +00:00
startCash(gameData.startMoney), startSmallBlind(gameData.smallBlind),
startHandsBeforeRaiseSmallBlind(gameData.handsBeforeRaise),
2007-09-28 05:23:13 +00:00
myGameID(gameId), actualSmallBlind(gameData.smallBlind), actualHandID(0), dealerPosition(0), lastHandBlindsRaised(1), lastTimeBlindsRaised(0), myGameData(gameData)
2007-01-13 02:40:33 +00:00
{
if(DEBUG_MODE) {
startSmallBlind = 20;
actualSmallBlind = startSmallBlind;
}
// cout << "Create Game Object" << "\n";
2007-01-13 02:40:33 +00:00
int i;
actualHandID = 0;
2007-08-10 23:16:21 +00:00
// for(i=0; i<MAX_NUMBER_OF_PLAYERS; i++) {
// playerArray[i] = 0;
// }
2007-01-13 02:40:33 +00:00
// Dealer Position bestimmen
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;
}
2007-09-27 14:17:07 +00:00
assert(player_i != player_end);
dealerPosition = startData.startDealerPlayerId;
2007-01-13 02:40:33 +00:00
// Board erstellen
2007-01-13 22:29:17 +00:00
actualBoard = myFactory->createBoard();
seatsList = PlayerList(new std::list<boost::shared_ptr<PlayerInterface> >);
activePlayerList = PlayerList(new std::list<boost::shared_ptr<PlayerInterface> >);
runningPlayerList = PlayerList(new std::list<boost::shared_ptr<PlayerInterface> >);
// Player erstellen
player_i = playerDataList.begin();
player_end = playerDataList.end();
for(i=0; i<MAX_NUMBER_OF_PLAYERS; i++) {
2007-01-19 19:13:59 +00:00
string myName;
string myAvatarFile;
unsigned uniqueId = 0;
PlayerType type = PLAYER_TYPE_COMPUTER;
boost::shared_ptr<SessionData> 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;
}
2007-01-19 19:13:59 +00:00
2007-09-23 21:30:51 +00:00
// create Player Objects
boost::shared_ptr<PlayerInterface> tmpPlayer = myFactory->createPlayer(actualBoard, i, uniqueId, type, myName, myAvatarFile, startCash, startQuantityPlayers > i, 0);
tmpPlayer->setNetSessionData(myNetSession);
2007-09-23 21:30:51 +00:00
// fill player lists
playerArray.push_back(tmpPlayer); // delete
seatsList->push_back(tmpPlayer);
2007-09-23 21:30:51 +00:00
if(startQuantityPlayers > i) {
activePlayerList->push_back(tmpPlayer);
2007-09-23 21:30:51 +00:00
}
(*runningPlayerList) = (*activePlayerList);
2007-08-10 23:16:21 +00:00
playerArray[i]->setNetSessionData(myNetSession); // delete
2007-01-13 02:40:33 +00:00
}
actualBoard->setPlayerLists(playerArray, seatsList, activePlayerList, runningPlayerList); // delete playerArray
2007-09-28 05:23:13 +00:00
//start timer
blindsTimer.reset();
blindsTimer.start();
2007-01-13 02:40:33 +00:00
}
Game::~Game()
{
// cout << "Delete Game Object" << "\n";
2007-01-13 02:40:33 +00:00
delete actualBoard;
actualBoard = 0;
delete actualHand;
actualHand = 0;
}
HandInterface *Game::getCurrentHand()
{
return actualHand;
}
const HandInterface *Game::getCurrentHand() const
{
return actualHand;
}
void Game::initHand()
2007-01-13 02:40:33 +00:00
{
2007-05-03 22:44:08 +00:00
size_t i;
PlayerListConstIterator it_c;
PlayerListIterator it, it_2;
2007-01-13 02:40:33 +00:00
actualHandID++;
2007-09-28 05:23:13 +00:00
// calculate smallBlind
raiseBlinds();
2007-01-13 02:40:33 +00:00
//Spieler Action auf 0 setzen
// for(i=0; i<MAX_NUMBER_OF_PLAYERS; i++) {
// playerArray[i]->setMyAction(0);
// }
2007-09-23 21:30:51 +00:00
//Spieler Action auf 0 setzen
2007-10-02 20:50:28 +00:00
for(it_c=seatsList->begin(); it_c!=seatsList->end(); it_c++) {
(*it_c)->setMyAction(PLAYER_ACTION_NONE);
}
// Spieler mit leerem Cash auf inactive setzen
it = activePlayerList->begin();
while( it!=activePlayerList->end() ) {
2007-09-23 21:30:51 +00:00
if((*it)->getMyCash() == 0) {
// cout << "playerID: " << (*it)->getMyID() << endl;
2007-09-23 21:30:51 +00:00
(*it)->setMyActiveStatus(0);
it = activePlayerList->erase(it);
} else {
it++;
2007-09-23 21:30:51 +00:00
}
2007-01-13 02:40:33 +00:00
}
2007-10-03 12:28:10 +00:00
// eventuell vorhandene Hand löschen
if(actualHand) {
// TODO HACK
2007-10-03 12:28:10 +00:00
for(it=seatsList->begin(); it!=seatsList->end(); it++) {
if (!(*it)->getMyActiveStatus())
{
2007-10-03 12:28:10 +00:00
if ((*it)->getMyUniqueID() == getCurrentHand()->getCurrentBeRo()->getCurrentPlayersTurnId())
{
it_2 = it;
it_2++;
if (it_2 == seatsList->end())
it_2 = seatsList->begin();
getCurrentHand()->getCurrentBeRo()->setCurrentPlayersTurnId((*it_2)->getMyUniqueID());
}
}
}
2007-10-03 12:28:10 +00:00
delete actualHand;
actualHand = 0;
}
runningPlayerList->clear();
(*runningPlayerList) = (*activePlayerList);
2007-06-08 19:37:21 +00:00
// Hand erstellen
actualHand = myFactory->createHand(myFactory, myGui, actualBoard, playerArray, seatsList, activePlayerList, runningPlayerList, actualHandID, startQuantityPlayers, dealerPosition, actualSmallBlind, startCash); // delete playerArray
2007-06-08 19:37:21 +00:00
// Dealer-Button weiterschieben --> Achtung inactive -> TODO exception-rule !!! DELETE
// for(i=0; (i<MAX_NUMBER_OF_PLAYERS && !(playerArray[dealerPosition]->getMyActiveStatus())) || i==0; i++) {
//
// dealerPosition = (dealerPosition+1)%(MAX_NUMBER_OF_PLAYERS);
// }
// Dealer-Button weiterschieben --> Achtung inactive -> TODO exception-rule !!!
bool nextDealerFound = false;
PlayerListConstIterator dealerPositionIt = actualHand->getSeatIt(dealerPosition);
assert( dealerPositionIt != seatsList->end() );
for(i=0; i<seatsList->size(); i++) {
dealerPositionIt++;
if(dealerPositionIt == seatsList->end()) dealerPositionIt = seatsList->begin();
it = actualHand->getActivePlayerIt( (*dealerPositionIt)->getMyUniqueID() );
if(it != activePlayerList->end() ) {
nextDealerFound = true;
dealerPosition = (*it)->getMyUniqueID();
break;
}
2007-08-10 22:39:44 +00:00
}
assert(nextDealerFound);
}
void Game::startHand()
{
assert(actualHand);
//GUI bereinigen
myGui->nextRoundCleanGui();
2007-01-13 02:40:33 +00:00
//Log new Hand
2007-02-04 13:46:27 +00:00
myGui->logNewGameHandMsg(myGameID, actualHandID);
//Log blinds sets for new Hand
PlayerListConstIterator it_sB, it_bB;
it_sB = actualHand->getActivePlayerIt(actualHand->getCurrentBeRo()->getSmallBlindPositionId());
it_bB = actualHand->getActivePlayerIt(actualHand->getCurrentBeRo()->getBigBlindPositionId());
if(it_sB != actualHand->getActivePlayerList()->end() && it_bB != actualHand->getActivePlayerList()->end()) {
myGui->logNewBlindsSetsMsg(myGameID, (*it_sB)->getMySet(), (*it_bB)->getMySet(), (*it_sB)->getMyName().c_str(), (*it_bB)->getMyName().c_str());
}
else { cout << "Log Error: cannot find sBID or bBID" << "\n"; }
actualHand->start();
2007-01-13 02:40:33 +00:00
}
2007-08-10 23:16:21 +00:00
boost::shared_ptr<PlayerInterface> Game::getPlayerByUniqueId(unsigned id)
{
2007-08-10 23:16:21 +00:00
boost::shared_ptr<PlayerInterface> tmpPlayer;
2007-09-27 14:17:07 +00:00
PlayerListIterator i = getSeatsList()->begin();
PlayerListIterator end = getSeatsList()->end();
while (i != end)
{
2007-09-27 14:17:07 +00:00
if ((*i)->getMyUniqueID() == id)
{
2007-09-27 14:17:07 +00:00
tmpPlayer = *i;
break;
}
2007-09-27 14:17:07 +00:00
++i;
}
return tmpPlayer;
}
boost::shared_ptr<PlayerInterface> Game::getCurrentPlayer()
{
2007-09-27 14:17:07 +00:00
boost::shared_ptr<PlayerInterface> tmpPlayer = getPlayerByUniqueId(getCurrentHand()->getCurrentBeRo()->getCurrentPlayersTurnId());
assert(tmpPlayer.get());
return tmpPlayer;
}
2007-09-28 05:23:13 +00:00
void Game::raiseBlinds() {
// cout << "timer minutes " << blindsTimer.elapsed().total_seconds()/60 << "\n";
2007-09-29 19:23:14 +00:00
// cout << "gameData.RaiseIntervalMode " << myGameData.RaiseIntervalMode << "\n";
2007-09-28 05:23:13 +00:00
// cout << "gameData.raiseMode " << myGameData.raiseMode << "\n";
// cout << "gameData.afterManualBlindsMode " << myGameData.afterManualBlindsMode << "\n";
bool raiseBlinds = false;
2007-09-29 19:23:14 +00:00
if (myGameData.raiseIntervalMode == RAISE_ON_HANDNUMBER) {
2007-09-28 05:23:13 +00:00
if (lastHandBlindsRaised + myGameData.raiseSmallBlindEveryHandsValue <= actualHandID) {
raiseBlinds = true;
lastHandBlindsRaised = actualHandID;
// cout << "raise now on hands \n";
2007-09-28 05:23:13 +00:00
}
}
else {
if (lastTimeBlindsRaised + myGameData.raiseSmallBlindEveryMinutesValue <= blindsTimer.elapsed().total_seconds()/60) {
raiseBlinds = true;
lastTimeBlindsRaised = blindsTimer.elapsed().total_seconds()/60;
// cout << "raise now on minutes \n";
2007-09-28 05:23:13 +00:00
}
}
if (raiseBlinds) {
// At this point, the blinds must be raised
// Now we check how the blinds should be raised
if (myGameData.raiseMode == DOUBLE_BLINDS) {
actualSmallBlind *= 2;
// cout << "double small blind \n";
2007-09-28 05:23:13 +00:00
}
else {
// Increase the position of the list
list<int> blindsList = myGameData.manualBlindsList;
list<int>::iterator it;
if(!blindsList.empty()) {
it = find(blindsList.begin(), blindsList.end(), actualSmallBlind);
if(it != blindsList.end()) {
it++;
// cout << "increase position in blindslist \n";
2007-09-28 05:23:13 +00:00
}
else {
// cout << "blindslist exceeds\n";
2007-09-28 05:23:13 +00:00
if(actualSmallBlind == myGameData.firstSmallBlind) {
it = blindsList.begin();
}
}
}
// else { cout << "blindslist is empty \n"; }
2007-09-28 05:23:13 +00:00
// Check if we can get an element of the list or the position exceeds the lis
if (blindsList.empty() || it == blindsList.end()) {
// The position exceeds the list
if (myGameData.afterManualBlindsMode == AFTERMB_DOUBLE_BLINDS) {
actualSmallBlind *= 2;
// cout << "after blindslist double blind\n";
2007-09-28 05:23:13 +00:00
}
else {
if(myGameData.afterManualBlindsMode == AFTERMB_RAISE_ABOUT) {
actualSmallBlind += myGameData.afterMBAlwaysRaiseValue;
// cout << "after blindslist increase about x \n";
2007-09-28 05:23:13 +00:00
}
// else { /* Stay at last blind */ cout << "after blindslist stay at last blind \n"; }
2007-09-28 05:23:13 +00:00
}
} else {
// Grab the blinds amount from the list
actualSmallBlind = *it;
// cout << "set new small blind from blindslist \n";
2007-09-28 05:23:13 +00:00
}
}
}
}