fix infinite check bug
[rofl0r-oopoker.git] / pokermath.h
blob0f1222e11259cb6c64116da7581d302960442653
1 /*
2 OOPoker
4 Copyright (c) 2010 Lode Vandevenne
5 All rights reserved.
7 This file is part of OOPoker.
9 OOPoker is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 OOPoker is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with OOPoker. If not, see <http://www.gnu.org/licenses/>.
23 #pragma once
26 This source file contains various more complex mathematical poker functions.
28 Check combination.h, statistics.h, info.h, util.h and game.h for a bit more poker math functions!
31 #include "card.h"
32 #include "combination.h"
34 double factorial(int i); //note: only works if result fits in double
35 double combination(int n, int p); //Binomial coefficient. Number of rows of p elements that can be made out of n elements, where order doesn't matter.
37 //starting hand analytics
38 bool isPair(const Card& card1, const Card& card2);
39 bool isSuited(const Card& card1, const Card& card2);
40 bool isConnector(const Card& card1, const Card& card2);
42 //pre-flop card rating: Group or EV
43 int getSklanskyMalmuthGroup(const Card& card1, const Card& card2); //gives a score (1-9) for starting hands, based on value and whether they're suited. Lower is better.
44 double getRealPlayStatisticsEV(const Card& card1, const Card& card2); //Card Expected Value statistics from http://www.pokerroom.com/
46 void splitIntoSuits(std::vector<Card>& spades
47 , std::vector<Card>& diamonds
48 , std::vector<Card>& hearts
49 , std::vector<Card>& clubs
50 , const std::vector<Card>& cards);
52 //does NOT reset the integers to 0 first, make sure you initialize them to 0!
53 void getAmountPerSuit(int& clubs, int& diamonds, int& hearts, int& spades, const std::vector<Card>& cards);
55 //this function is neither efficient, nor ever used by me so far. It's a naive combination checking function.
56 void getHighestNearFlush(std::vector<Card>& result, const std::vector<Card>& cards);
59 The getPotEquity returns a value in the range 0.0-1.0 representing roughly how much win chance you have to win the pot,
60 depending on your hand cards and the known cards on the table. The opponents hands and unknown table cards can be ANY cards.
61 More precicely, it returns the percentage of money you'd win from the pot when you would be in this situation (=
62 these hand cards, these known table cards, and this amount of opponents) lots and lots of times. Sometimes you'll win,
63 sometimes you'll lose, in the end after so many plays you'll win that percentage of the pot.
65 If you want win, tie and lose chance instead of equity, use the getWinChance... functions below instead.
67 Getting pot equity is a type of poker math function that takes a long time to calculate and can be implemented
68 in many different ways with many different strategies (a combination of exhaustive search, monte carlo statistical
69 simulation, lookup tables and combinatorics). This one from OOPoker is just one possible implementation, and may be
70 changed or improved over time to become more accurate and more efficient. Its speed, accuracy and randomness
71 might change in future implementations.
73 Some inspiration for writing this function was gotten from:
74 http://www.codingthewheel.com/archives/multiway-ranged-isometric-equity-calculation-in-poker-1
75 http://www.pokerstove.com/
77 Parameters:
78 holeCards: vector must have size 2, represents your two hand cards
79 boardCards: vector must have size 0, 3, 4 or 5 (pre-flop, flop, turn, river), represents the known board cards
80 numOpponents: number of active opponents
81 numSamples: used when this function will use many samples to simulate many possible hand combinations. The higher the value, the more accurate the result, but the slower the function. 50000 is a good value.
83 double getPotEquity(const std::vector<Card>& holeCards, const std::vector<Card>& boardCards, int numOpponents, int numSamples = 50000);
87 This calculates the win chance of multiple players, all of which have known cards. This is useful
88 at pre-flop, flop or turn. At river there is no unknown factor anymore (but the function will still
89 return the correct result).
91 Parameters:
92 win, tie and lose: this are std::vectors that will have the same size as the number of players and contain the chances of each player.
93 holeCards1, holeCards2: the hand cards of all players. The size of these vectors must be the same and indicates the amount of players.
94 boardCards: 0 to 5 cards on the table.
95 numSamples: used when this function will use many samples to simulate many possible hand combinations. The higher the value, the more accurate the result, but the slower the function. 50000 is a good value.
97 returns false if error happened (such as invalid parameters)
99 bool getWinChanceWithKnownHands(std::vector<double>& win, std::vector<double>& tie, std::vector<double>& lose
100 , const std::vector<Card>& holeCards1
101 , const std::vector<Card>& holeCards2
102 , const std::vector<Card>& boardCards
103 , int numSamples = 50000);
108 This function evaluates combinations of 7 cards fast. This can be used for fast simulation.
109 The values of the return value aren't specified, except this: the higher the return value,
110 the better the combination. If the values are equal, it's a tie.
111 The input is cards as integers, and the integers must be created using eval7_index.
112 The integers are always positive.
114 int eval7(const int* cards /*NOT card.getIndex()!!!*/);
115 int eval7_index(const Card& card);
116 ComboType eval7_category(int result); //converts result from eval to named combo type (without info about card values)
119 Similar to eval7 but for 5 cards. Note: integer values related to eval7 and evan7index are NOT
120 interchangeable with those of eval5!
122 int eval5(const int* cards /*NOT card.getIndex()!!!*/);
123 int eval5_index(const Card& card);
124 ComboType eval5_category(int result); //converts result from eval to named combo type (without info about card values)
127 Similar to eval5 and eval7, but for 6 cards, e.g. to calculate what combination you already have
128 after the turn before the river. This function is called "slow" because it uses 6 calls to eval5.
129 It's still a lot faster than the naive (but more convenient) implementation in combination.h
131 int eval6_slow(const int* cards /*NOT card.getIndex()!!!*/);
132 int eval6_index_slow(const Card& card);
133 ComboType eval6_category(int result); //converts result from eval to named combo type (without info about card values)
136 similar to eval5 and eval7, but meant for Omaha Hold'm.
137 This implementation is included just for future reference. It's slow and not needed since OOPoker is currently
138 exclusively Texas Hold'm.
139 It evaluates the best 5-card combination out of 9 cards, where 2 must come from the first 4, 3 must come from the last 5.
140 It's at least 60 times slower than eval7.
142 int eval4_2_5_3_slow(const int* cards);
143 int eval4_2_5_3_slow_index(const Card& card);
144 ComboType eval4_2_5_3_slow_category(int result); //converts result from eval to named combo type (without info about card values)
147 Get win chance functions for Texas Hold'm.
149 They return the chance to win, tie or lose, as values in range 0.0-1.0.
151 The functions against 1 use exhaustive search.
153 The functions against N opponents use monte carlo statistical analysis.
155 You're encouraged to write your own win chance or win equity functions (using the eval7
156 function or a faster one for the hand evaluations). Check for example articles like here:
160 void getWinChanceAgainst1AtFlop(double& win, double& tie, double& lose
161 , const Card& hand1, const Card& hand2
162 , const Card& table1, const Card& table2, const Card& table3);
164 void getWinChanceAgainst1AtTurn(double& win, double& tie, double& lose
165 , const Card& hand1, const Card& hand2
166 , const Card& table1, const Card& table2, const Card& table3, const Card& table4);
168 void getWinChanceAgainst1AtRiver(double& win, double& tie, double& lose
169 , const Card& hand1, const Card& hand2
170 , const Card& table1, const Card& table2, const Card& table3, const Card& table4, const Card& table5);
174 The functions below calculate the win chance given your cards against N players.
175 Unlike the "against1" functions above, the ones below don't calculate the exact solution.
176 They use monte-carlo integration instead: you can choose an amount of random samples.
178 The higher the numSamples parameter, the more precise the solution, but the more calculation
179 time is needed. Setting it lower makes your bot faster.
182 void getWinChanceAgainstNAtPreFlop(double& win, double& tie, double& lose
183 , const Card& hand1, const Card& hand2
184 , int numOpponents, int numSamples = 50000);
187 void getWinChanceAgainstNAtFlop(double& win, double& tie, double& lose
188 , const Card& hand1, const Card& hand2
189 , const Card& table1, const Card& table2, const Card& table3
190 , int numOpponents, int numSamples = 50000);
192 void getWinChanceAgainstNAtTurn(double& win, double& tie, double& lose
193 , const Card& hand1, const Card& hand2
194 , const Card& table1, const Card& table2, const Card& table3, const Card& table4
195 , int numOpponents, int numSamples = 50000);
197 void getWinChanceAgainstNAtRiver(double& win, double& tie, double& lose
198 , const Card& hand1, const Card& hand2
199 , const Card& table1, const Card& table2, const Card& table3, const Card& table4, const Card& table5
200 , int numOpponents, int numSamples = 50000);