/*************************************************************************** * 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 "localriver.h" #include #include #include using namespace std; LocalRiver::LocalRiver(HandInterface* bR, int id, int qP, int dP, int sB) : RiverInterface(), myHand(bR), myID(id), actualQuantityPlayers(qP), dealerPosition(dP), smallBlindPosition(0), smallBlind(sB), highestSet(0), firstRiverRun(1), firstRiverRound(1), firstHeadsUpRiverRound(1), playersTurn(dP), highestCardsValue(0), logBoardCardsDone(0) { int i; //SmallBlind-Position ermitteln for(i=0; igetPlayerArray()[i]->getMyButton() == 2) smallBlindPosition = i; } } LocalRiver::~LocalRiver() { } void LocalRiver::riverRun() { int i; if (firstRiverRun) { myHand->getGuiInterface()->dealRiverCard(); firstRiverRun = 0; } else { //log the turned cards if(!logBoardCardsDone) { int tempBoardCardsArray[5]; myHand->getBoard()->getMyCards(tempBoardCardsArray); myHand->getGuiInterface()->logDealBoardCardsMsg(3, tempBoardCardsArray[0], tempBoardCardsArray[1], tempBoardCardsArray[2], tempBoardCardsArray[3], tempBoardCardsArray[4]); logBoardCardsDone = 1; } bool allHighestSet = 1; // prfe, ob alle Sets gleich sind ( falls nicht, dann allHighestSet = 0 ) for(i=0; igetPlayerArray()[i]->getMyActiveStatus() && myHand->getPlayerArray()[i]->getMyAction() != 1 && myHand->getPlayerArray()[i]->getMyAction() != 6) { // cout << "Spieler " << i << " Set " << myHand->getPlayerArray()[i]->getMySet() << endl; if(highestSet != myHand->getPlayerArray()[i]->getMySet()) { allHighestSet=0; } } } // cout << "allHighestSet " << allHighestSet << endl; // cout << "firstflopround " << firstRiverRound << endl; // prfen, ob River wirklich dran ist if(!firstRiverRound && allHighestSet) { // River nicht dran, weil alle Sets gleich sind //also gehe in Turn myHand->setActualRound(4); //Action lᅵchen und ActionButtons refresh for(i=0; igetPlayerArray()[i]->getMyAction() != 1 && myHand->getPlayerArray()[i]->getMyAction() != 6) myHand->getPlayerArray()[i]->setMyAction(0); } //Sets in den Pot verschieben und Sets = 0 und Pot-refresh myHand->getBoard()->collectSets(); myHand->getBoard()->collectPot(); myHand->getGuiInterface()->refreshPot(); myHand->getGuiInterface()->refreshSet(); myHand->getGuiInterface()->refreshCash(); for(i=0; igetGuiInterface()->refreshAction(i,0); } myHand->switchRounds(); } else { // River ist wirklich dran // Anzahl der effektiv gespielten Runden (des human player) erhöhen if(myHand->getPlayerArray()[0]->getMyActiveStatus() && myHand->getPlayerArray()[0]->getMyAction() != 1) { myHand->setBettingRoundsPlayed(3); } if( !(myHand->getActualQuantityPlayers() < 3 && firstHeadsUpRiverRound == 1) ) { // not first round in heads up (for headsup dealer is smallblind so it is dealers turn) // naechsten Spieler ermitteln do { playersTurn = (playersTurn+1)%(MAX_NUMBER_OF_PLAYERS); } while(!(myHand->getPlayerArray()[playersTurn]->getMyActiveStatus()) || (myHand->getPlayerArray()[playersTurn]->getMyAction())==1 || (myHand->getPlayerArray()[playersTurn]->getMyAction())==6); } else { firstHeadsUpRiverRound = 0; } //Spieler-Position vor SmallBlind-Position ermitteln int activePlayerBeforeSmallBlind = smallBlindPosition; do { activePlayerBeforeSmallBlind = (activePlayerBeforeSmallBlind + MAX_NUMBER_OF_PLAYERS - 1 ) % (MAX_NUMBER_OF_PLAYERS); } while(!(myHand->getPlayerArray()[activePlayerBeforeSmallBlind]->getMyActiveStatus()) || (myHand->getPlayerArray()[activePlayerBeforeSmallBlind]->getMyAction())==1 || (myHand->getPlayerArray()[activePlayerBeforeSmallBlind]->getMyAction())==6); myHand->getPlayerArray()[playersTurn]->setMyTurn(1); //highlight active players groupbox and clear action myHand->getGuiInterface()->refreshGroupbox(playersTurn,2); myHand->getGuiInterface()->refreshAction(playersTurn,0); // cout << "activePlayerBeforeSmallBlind " << activePlayerBeforeSmallBlind << endl; // cout << "playersTurn " << playersTurn << endl; // wenn wir letzter aktiver Spieler vor SmallBlind sind, dann flopFirstRound zuende if(myHand->getPlayerArray()[playersTurn]->getMyID() == activePlayerBeforeSmallBlind) { firstRiverRound = 0; } if(playersTurn == 0) { // Wir sind dran // cout << "actualRound " << myHand->getActualRound() << endl; // cout << "highestSet vor meInAction " << highestSet << endl; myHand->getGuiInterface()->meInAction(); } else { //Gegner sind dran myHand->getGuiInterface()->riverAnimation2(); } } } } void LocalRiver::postRiverRun() { int i; // für die Engine die durchschnittlichen Sets von Player 0 setzen --> UNUSED !!! // if(myID < 5) { // myHand->getPlayerArray()[0]->setMyAverageSets(((myHand->getPlayerArray()[0]->getMyAverageSets())*(myID-1))/myID + (myHand->getPlayerArray()[0]->getMyRoundStartCash()-myHand->getPlayerArray()[0]->getMyCash())/myID); // } else { // myHand->getPlayerArray()[0]->setMyAverageSets(((myHand->getPlayerArray()[0]->getMyAverageSets())*4)/5 + (myHand->getPlayerArray()[0]->getMyRoundStartCash()-myHand->getPlayerArray()[0]->getMyCash())/5); // } // cout << myHand->getPlayerArray()[0]->getMyAverageSets() << endl; //berechnen welcher Spieler gewonnen hat for(i=0; igetPlayerArray()[i]->getMyCardsValueInt() << endl; if(myHand->getPlayerArray()[i]->getMyActiveStatus() && myHand->getPlayerArray()[i]->getMyAction() != 1 && myHand->getPlayerArray()[i]->getMyCardsValueInt() > highestCardsValue ) { highestCardsValue = myHand->getPlayerArray()[i]->getMyCardsValueInt(); } } // Durchschnittsets des human player ermitteln myHand->getPlayerArray()[0]->setMyAverageSets(((myHand->getPlayerArray()[0]->getMyRoundStartCash())-(myHand->getPlayerArray()[0]->getMyCash()))/(myHand->getBettingRoundsPlayed()+1)); // cout << myHand->getPlayerArray()[0]->getMyAverageSets() << endl; // Aggressivität des human player ermitteln // anzahl der player die möglichkeit haben am pot teilzuhaben int potPlayers = 0; for(i=0; igetPlayerArray()[i]->getMyActiveStatus() && myHand->getPlayerArray()[i]->getMyAction() != 1) { potPlayers++; } } // prüfen ob nur noch der human player an der verteilung teilnimmt und myAggressive für human player setzen myHand->getPlayerArray()[0]->setMyAggressive(potPlayers == 1 && myHand->getPlayerArray()[0]->getMyActiveStatus() && myHand->getPlayerArray()[0]->getMyAction() != 1); // cout << "myAggressive: " << myHand->getPlayerArray()[0]->getMyAggressive() << endl; // Pot-Verteilung distributePot(); //Pot auf 0 setzen myHand->getBoard()->setPot(0); //starte die Animaionsreihe myHand->getGuiInterface()->postRiverRunAnimation1(); } void LocalRiver::nextPlayer2() { myHand->getPlayerArray()[playersTurn]->action(); } void LocalRiver::distributePot() { // int potCalcAllinArray[5][2]; // 0 -> ID , 1 -> AllInCash int i, j; //////////////////// // (1) EINLEITUNG // //////////////////// // die Potverteilung gliedert sich in mehrere Runden: // in der ersten Runden sucht sich der Winner der BettingRound seinen zustehenden Anteil am Pot raus. das kann alles oder nur ein Teil sein (z.b. wenn er mit wenig allin gegangen ist und der Rest weitergespielt hat) // in den darauffolgenden Verteilungsrunden suchen sich die jeweils nᅵhsten Winner aus dem noch brig gebliebenen Pot ihren zustehenden Anteil raus // die gesamte Potverteilung ist zuende, wenn der Pot leer ist und nichts mehr zu holen ist ///////////////////// // (2) HILFSMITTEL // ///////////////////// // winnersArray erstellen -> hier werden die winner der jeweiligen Potverteilungsrunden eingetragen int *winnersArray = new int[MAX_NUMBER_OF_PLAYERS]; // Anzahl der winner in einer Potverteilungsrunde int winnersCounter = 0; // dieses Array ermittelt wieviel jeder Spieler wᅵrend der gesamten BettingRound gesetzt hat int *roundSetArray = new int[MAX_NUMBER_OF_PLAYERS]; for(i=0; igetPlayerArray()[i]->getMyActiveStatus()) { roundSetArray[i] = myHand->getPlayerArray()[i]->getMyRoundStartCash()-myHand->getPlayerArray()[i]->getMyCash(); } } // hier steht der CardsValue der Spieler drin die an der Potverteilung teilnehmen (d.h. aktiv und nicht gefoldet), bei allen anderen steht ne 0 int *cardsValueArray = new int[MAX_NUMBER_OF_PLAYERS]; int playerWantsPotCounter = 0; for(i=0; igetPlayerArray()[i]->getMyActiveStatus() && myHand->getPlayerArray()[i]->getMyAction() != 1) { // nur bei den Spielen den Kartenwert eintragen, die an der Potverteilung teilnehmen cardsValueArray[i] = myHand->getPlayerArray()[i]->getMyCardsValueInt(); playerWantsPotCounter++; } } int winner; int highestCardsValueTemp; // fr SplitPotBerechnung; int winnersSets; int winnersMaxSet; int winnersPot; bool playerIsWinner; ////////////////////// // (3) DIE SCHLEIFE // ////////////////////// // Potverteilungsrunden -> solange noch was aus dem pot zu vergeben ist while(playerWantsPotCounter != 0 ) { // highestCardsValueTemp zu Beginn der aktuellen Potverteilungsrunde auf Null setzen highestCardsValueTemp = 0; // aktuellen highestCardsValueTemp berechnen, von denen die noch an der Potverteilung teilnehmen for(i=0; i highestCardsValueTemp ) { highestCardsValueTemp = myHand->getPlayerArray()[i]->getMyCardsValueInt(); } } // zu Beginn der Potverteilungsrunde die Anzahl der winner auf 0 setzen winnersCounter = 0; // Siegerposition und -anzahl von denen ermitteln, die noch an der Potverteilung teilnehmen for(i=0; i bekommt den gesamten Pot // if(myHand->getPlayerArray()[winner]->getMyAction() != 6) { // // myHand->getPlayerArray()[winner]->setMyCash(myHand->getPlayerArray()[winner]->getMyCash()+myHand->getBoard()->getPot()); // myHand->getBoard()->setPot(0); // playerWantsPotCounter = 1; // // } // Winner ist All In gegangen -> von denen die weniger gesetzt oder gefoldet hatten alles nehmen und von denen die mehr gesetzt hatten nur die eigenen Sets nehmen // else { // alle Spieler nacheinander durchgehen und prfen von wem man wieviel Geld aus dem Pot bekommt for(i=0; igetPlayerArray()[i]->getMyAction() == 1) { // diesen Teil aus dem Pot holen myHand->getPlayerArray()[winner]->setMyCash(myHand->getPlayerArray()[winner]->getMyCash()+roundSetArray[i]); // Pot dementsprechend verkleinern myHand->getBoard()->setPot(myHand->getBoard()->getPot() - roundSetArray[i]); // deren Sets auf Null seztzen -> in den nᅵhsten Potverteilungsrunden nimmt der Winner dann von diesen Spielern 0 Dollar aus dem Pot roundSetArray[i] = 0; } // nun nur von den Spielern holen, die noch an der Potverteilung teilnehmen und natrlich nicht von einem selber if(i != winner && cardsValueArray[i] != 0) { // zuerst alle rauspicken, die weniger oder das gleiche gesetzt hatten if(roundSetArray[winner] >= roundSetArray[i]) { // von denen alles holen myHand->getPlayerArray()[winner]->setMyCash(myHand->getPlayerArray()[winner]->getMyCash()+roundSetArray[i]); // Pot dementsprechend verkleinern myHand->getBoard()->setPot(myHand->getBoard()->getPot() - roundSetArray[i]); // diese Spieler dann von der weiteren Potverteilung ausschlieᅵn cardsValueArray[i] = 0; playerWantsPotCounter--; // deren Sets auf Null seztzen, da sie schon alles abgegeben haben roundSetArray[i] = 0; } // nun alle Spieler die mehr gesetzt hatten else { // den eigenen Setanteil aus dem Pot holen myHand->getPlayerArray()[winner]->setMyCash(myHand->getPlayerArray()[winner]->getMyCash()+roundSetArray[winner]); myHand->getBoard()->setPot(myHand->getBoard()->getPot() - roundSetArray[winner]); // den Set des Gegners um den bereits abgenommenen Setanteil verkleinern roundSetArray[i] = roundSetArray[i] - roundSetArray[winner]; // diese Spieler nehmen an der weiteren Potverteilung teil } } } // // } // zum Scluss noch eingenen Set wieder holen myHand->getPlayerArray()[winner]->setMyCash(myHand->getPlayerArray()[winner]->getMyCash()+roundSetArray[winner]); myHand->getBoard()->setPot(myHand->getBoard()->getPot() - roundSetArray[winner]); // nicht mehr an der weiteren Potverteilung teilnehmen, da man sich alles geholt hat was einem zusteht cardsValueArray[winner] = 0; playerWantsPotCounter--; // eigene Sets auf Null seztzen, da sie eben eingesammelt wurden roundSetArray[winner] = 0; } // ---------------------------------------------------------------------- // B) mehrere haben die aktuelle Potverteilungsrunde gewonnen -> SplitPot // ---------------------------------------------------------------------- else { // hierfr wird ein temporᅵer WinnersPot erstellt; dort flieᅵn erstmal alle zustehenden Anteile aus dem Pot rauf; am Ende wird dies auf die Winners verteilt winnersPot = 0; // hᅵhster Set aller Winner winnersMaxSet = 0; // den hᅵhsten Set aller Winner ermitteln for(i=0; i winnersMaxSet) winnersMaxSet = roundSetArray[i]; } // gesamtSet aller Winner winnersSets = 0; for(i=0; i Spieler i gehᅵt zu den Winnern } // zuerst prfen ob ein gefoldeter Spieler was gesetzt hatte if(!playerIsWinner && myHand->getPlayerArray()[i]->getMyAction() == 1) { // diesen Teil aus dem Pot holen und dem winnersPot geben winnersPot += roundSetArray[i]; // Pot dementsprechend verkleinern myHand->getBoard()->setPot(myHand->getBoard()->getPot() - roundSetArray[i]); // deren Sets auf Null seztzen -> in den nᅵhsten Potverteilungsrunden nehmen die Winner dann von diesen Spielern 0 Dollar aus dem Pot roundSetArray[i] = 0; } // nun nur von den Spielern holen, die noch an der Potverteilung teilnehmen und natrlich nicht zu den Winnern gehᅵen if(!playerIsWinner && cardsValueArray[i] != 0) { // zuerst alle rauspicken, die weniger oder das gleiche gesetzt hatten if(winnersMaxSet >= roundSetArray[i]) { // von denen alles holen winnersPot += roundSetArray[i]; // Pot dementsprechend verkleinern myHand->getBoard()->setPot(myHand->getBoard()->getPot() - roundSetArray[i]); // diese Spieler dann von der weiteren Potverteilung ausschlieᅵn cardsValueArray[i] = 0; playerWantsPotCounter--; // deren Sets auf Null seztzen, da sie schon alles abgegeben haben roundSetArray[i] = 0; } // nun alle Spieler die mehr gesetzt hatten else { // den eigenen Setanteil aus dem Pot holen winnersPot += winnersMaxSet; myHand->getBoard()->setPot(myHand->getBoard()->getPot() - winnersMaxSet); // den Set des Gegners um den bereits abgenommenen Setanteil verkleinern roundSetArray[i] = roundSetArray[i] - winnersMaxSet; // diese Spieler nehmen an der weiteren Potverteilung teil } } } // zum Schluss noch die eingenen Set aus dem Pot holen winnersPot += winnersSets; myHand->getBoard()->setPot(myHand->getBoard()->getPot() - winnersSets); // winnersPot verteilen (anteilmᅵig) for(i=0; igetPlayerArray()[winnersArray[i]]->setMyCash(myHand->getPlayerArray()[winnersArray[i]]->getMyCash()+((roundSetArray[winnersArray[i]]*winnersPot)/winnersSets)); } for(i=0; igetBoard()->getPot() != 0) cout << "!!! Pot: " << myHand->getBoard()->getPot() << endl; delete[] winnersArray; delete[] roundSetArray; delete[] cardsValueArray; }