1 /*****************************************************************************
2  * PokerTH - The open source texas holdem engine                             *
3  * Copyright (C) 2006-2012 Felix Hammer, Florian Thauer, Lothar May          *
4  *                                                                           *
5  * This program is free software: you can redistribute it and/or modify      *
6  * it under the terms of the GNU Affero General Public License as            *
7  * published by the Free Software Foundation, either version 3 of the        *
8  * License, or (at your option) any later version.                           *
9  *                                                                           *
10  * This program is distributed in the hope that it will be useful,           *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
13  * GNU Affero General Public License for more details.                       *
14  *                                                                           *
15  * You should have received a copy of the GNU Affero General Public License  *
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.     *
17  *                                                                           *
18  *                                                                           *
19  * Additional permission under GNU AGPL version 3 section 7                  *
20  *                                                                           *
21  * If you modify this program, or any covered work, by linking or            *
22  * combining it with the OpenSSL project's OpenSSL library (or a             *
23  * modified version of that library), containing parts covered by the        *
24  * terms of the OpenSSL or SSLeay licenses, the authors of PokerTH           *
25  * (Felix Hammer, Florian Thauer, Lothar May) grant you additional           *
26  * permission to convey the resulting work.                                  *
27  * Corresponding Source for a non-source form of such a combination          *
28  * shall include the source code for the parts of OpenSSL used as well       *
29  * as that of the covered work.                                              *
30  *****************************************************************************/
31 
32 #include "localbero.h"
33 
34 #include "localexception.h"
35 #include "engine_msg.h"
36 #include <core/loghelper.h>
37 
38 using namespace std;
39 
LocalBeRo(HandInterface * hi,unsigned dP,int sB,GameState gS)40 LocalBeRo::LocalBeRo(HandInterface* hi, unsigned dP, int sB, GameState gS)
41 	: BeRoInterface(), myHand(hi), myBeRoID(gS), dealerPosition(dP), smallBlindPosition(0), smallBlindPositionId(0), bigBlindPositionId(0), smallBlind(sB), highestSet(0), minimumRaise(2*sB), fullBetRule(false), firstRun(true), firstRunGui(true), firstRound(true), firstHeadsUpRound(true), currentPlayersTurnId(0), firstRoundLastPlayersTurnId(0), logBoardCardsDone(false)
42 {
43 	currentPlayersTurnIt = myHand->getRunningPlayerList()->begin();
44 	lastPlayersTurnIt = myHand->getRunningPlayerList()->begin();
45 
46 	PlayerListConstIterator it_c;
47 
48 	// determine bigBlindPosition
49 	for(it_c=myHand->getActivePlayerList()->begin(); it_c!=myHand->getActivePlayerList()->end(); ++it_c) {
50 		if((*it_c)->getMyButton() == BUTTON_BIG_BLIND) {
51 			bigBlindPositionId = (*it_c)->getMyUniqueID();
52 			break;
53 		}
54 	}
55 	if(it_c == myHand->getActivePlayerList()->end()) {
56 		throw LocalException(__FILE__, __LINE__, ERR_ACTIVE_PLAYER_NOT_FOUND);
57 	}
58 
59 	// determine smallBlindPosition
60 	for(it_c=myHand->getActivePlayerList()->begin(); it_c!=myHand->getActivePlayerList()->end(); ++it_c) {
61 		if((*it_c)->getMyButton() == BUTTON_SMALL_BLIND) {
62 			smallBlindPositionId = (*it_c)->getMyUniqueID();
63 			break;
64 		}
65 	}
66 	if(it_c == myHand->getActivePlayerList()->end()) {
67 		throw LocalException(__FILE__, __LINE__, ERR_ACTIVE_PLAYER_NOT_FOUND);
68 	}
69 
70 }
71 
72 
~LocalBeRo()73 LocalBeRo::~LocalBeRo()
74 {
75 }
76 
getHighestCardsValue() const77 int LocalBeRo::getHighestCardsValue() const
78 {
79 	LOG_ERROR(__FILE__ << " (" << __LINE__ << "): getHighestCardsValue() in wrong BeRo");
80 	return 0;
81 }
82 
nextPlayer()83 void LocalBeRo::nextPlayer()
84 {
85 
86 	PlayerListConstIterator currentPlayersTurnConstIt = myHand->getRunningPlayerIt(currentPlayersTurnId);
87 	if(currentPlayersTurnConstIt == myHand->getRunningPlayerList()->end()) {
88 		throw LocalException(__FILE__, __LINE__, ERR_RUNNING_PLAYER_NOT_FOUND);
89 	}
90 
91 	(*currentPlayersTurnConstIt)->action();
92 
93 }
94 
run()95 void LocalBeRo::run()
96 {
97 
98 	if(firstRunGui) {
99 		firstRunGui = false;
100 		myHand->setPreviousPlayerID(-1);
101 		myHand->getGuiInterface()->dealBeRoCards(myBeRoID);
102 	} else {
103 
104 		if(firstRun) {
105 
106 			firstRun = false;
107 
108 			if(!(myHand->getAllInCondition())) {
109 
110 				PlayerListIterator it_1, it_2;
111 
112 				if(myHand->getActivePlayerList()->size() > 2) {
113 
114 					// running player before smallBlind
115 					bool formerRunningPlayerFound = false;
116 
117 					it_1 = myHand->getActivePlayerIt(smallBlindPositionId);
118 					if(it_1 == myHand->getActivePlayerList()->end()) {
119 						throw LocalException(__FILE__, __LINE__, ERR_ACTIVE_PLAYER_NOT_FOUND);
120 					}
121 
122 					for(size_t i=0; i<myHand->getActivePlayerList()->size(); i++) {
123 
124 						if(it_1 == myHand->getActivePlayerList()->begin()) it_1 = myHand->getActivePlayerList()->end();
125 						--it_1;
126 
127 						it_2 = myHand->getRunningPlayerIt((*it_1)->getMyUniqueID());
128 						// running player found
129 						if(it_2 != myHand->getRunningPlayerList()->end()) {
130 							firstRoundLastPlayersTurnId = (*it_2)->getMyUniqueID();
131 							formerRunningPlayerFound = true;
132 							break;
133 						}
134 					}
135 					if(!formerRunningPlayerFound) {
136 						throw LocalException(__FILE__, __LINE__, ERR_FORMER_RUNNING_PLAYER_NOT_FOUND);
137 					}
138 				}
139 				// heads up: bigBlind begins -> dealer/smallBlind is running player before bigBlind
140 				else {
141 					firstRoundLastPlayersTurnId = smallBlindPositionId;
142 				}
143 				currentPlayersTurnId = firstRoundLastPlayersTurnId;
144 			}
145 		}
146 
147 		//log the turned cards
148 		if(!logBoardCardsDone) {
149 
150 			int tempBoardCardsArray[5];
151 
152 			myHand->getBoard()->getMyCards(tempBoardCardsArray);
153 
154 			switch(myBeRoID) {
155 			case GAME_STATE_FLOP:
156 				myHand->getGuiInterface()->logDealBoardCardsMsg(myBeRoID, tempBoardCardsArray[0], tempBoardCardsArray[1], tempBoardCardsArray[2]);
157 				break;
158 			case GAME_STATE_TURN:
159 				myHand->getGuiInterface()->logDealBoardCardsMsg(myBeRoID, tempBoardCardsArray[0], tempBoardCardsArray[1], tempBoardCardsArray[2], tempBoardCardsArray[3]);
160 				break;
161 			case GAME_STATE_RIVER:
162 				myHand->getGuiInterface()->logDealBoardCardsMsg(myBeRoID, tempBoardCardsArray[0], tempBoardCardsArray[1], tempBoardCardsArray[2], tempBoardCardsArray[3], tempBoardCardsArray[4]);
163 
164 				break;
165 			default: {
166 				LOG_ERROR(__FILE__ << " (" << __LINE__ << "): ERROR - wrong myBeRoID");
167 			}
168 			}
169 			if(myHand->getLog()) myHand->getLog()->logBoardCards(tempBoardCardsArray);
170 			logBoardCardsDone = true;
171 
172 		}
173 
174 		bool allHighestSet = true;
175 
176 		PlayerListIterator it_c;
177 
178 
179 		// check if all running players have same sets (else allHighestSet = false)
180 		for( it_c = myHand->getRunningPlayerList()->begin(); it_c != myHand->getRunningPlayerList()->end(); ++it_c) {
181 			if(highestSet != (*it_c)->getMySet()) {
182 				allHighestSet = false;
183 				break;
184 			}
185 		}
186 
187 		// prfen, ob aktuelle bero wirklich dran ist
188 		if(!firstRound && allHighestSet) {
189 
190 			// aktuelle bero nicht dran, weil alle Sets gleich sind
191 			//also gehe in naechste bero
192 			myHand->setCurrentRound(GameState(myBeRoID+1));
193 
194 			//Action loeschen und ActionButtons refresh
195 			for(it_c=myHand->getRunningPlayerList()->begin(); it_c!=myHand->getRunningPlayerList()->end(); ++it_c) {
196 				(*it_c)->setMyAction(PLAYER_ACTION_NONE);
197 			}
198 
199 			//Sets in den Pot verschieben und Sets = 0 und Pot-refresh
200 			myHand->getBoard()->collectSets();
201 			myHand->getBoard()->collectPot();
202 			myHand->getGuiInterface()->refreshPot();
203 
204 			myHand->getGuiInterface()->refreshSet();
205 			myHand->getGuiInterface()->refreshCash();
206 			for(int i=0; i<MAX_NUMBER_OF_PLAYERS; i++) {
207 				myHand->getGuiInterface()->refreshAction(i,PLAYER_ACTION_NONE);
208 			}
209 
210 			myHand->switchRounds();
211 		} else {
212 			// aktuelle bero ist wirklich dran
213 
214 			// determine next running player
215 			PlayerListConstIterator currentPlayersTurnIt = myHand->getRunningPlayerIt( currentPlayersTurnId );
216 			if(currentPlayersTurnIt == myHand->getRunningPlayerList()->end()) {
217 				throw LocalException(__FILE__, __LINE__, ERR_RUNNING_PLAYER_NOT_FOUND);
218 			}
219 
220 			++currentPlayersTurnIt;
221 			if(currentPlayersTurnIt == myHand->getRunningPlayerList()->end()) currentPlayersTurnIt = myHand->getRunningPlayerList()->begin();
222 
223 			currentPlayersTurnId = (*currentPlayersTurnIt)->getMyUniqueID();
224 
225 			//highlight active players groupbox and clear action
226 			myHand->getGuiInterface()->refreshGroupbox(currentPlayersTurnId,2);
227 			myHand->getGuiInterface()->refreshAction(currentPlayersTurnId,0);
228 
229 			currentPlayersTurnIt = myHand->getRunningPlayerIt( currentPlayersTurnId );
230 			if(currentPlayersTurnIt == myHand->getRunningPlayerList()->end()) {
231 				throw LocalException(__FILE__, __LINE__, ERR_RUNNING_PLAYER_NOT_FOUND);
232 			}
233 
234 			(*currentPlayersTurnIt)->setMyTurn(true);
235 
236 
237 			if( currentPlayersTurnId == firstRoundLastPlayersTurnId ) {
238 				firstRound = false;
239 			}
240 
241 			if( currentPlayersTurnId == 0) {
242 				// Wir sind dran
243 				myHand->getGuiInterface()->meInAction();
244 			} else {
245 
246 				//Gegner sind dran
247 				myHand->getGuiInterface()->beRoAnimation2(myBeRoID);
248 			}
249 
250 		}
251 	}
252 }
253