I writing some specific poker equity calculator. Basically, equity calculator tells how much one hand is more profitable than other. I have written such calculator and it works, works fast, but there is a one not optimal place where a lot of time is spent and it definitely can be optimized. I am asking you about the advice how to optimize it.
Below is the simplified structure of poker equity calculator. For sample purpose, I have made it for the game when both Players hands contain one from 52 cards, 4 cards are on board(turn), one(river) board card left. Let say that player who's sum of the board and hand card is higher - wins.
#include "stdafx.h"
#include <vector>
#include <iostream>
#include <ctime>
#include <string>
using namespace std;
static const int card_count = 52;
// Checks that board contains the card. A lot of time spent here. Need to be optimized.
bool Contains(const std::vector<int>& board, int card)
{
for (int boardCard : board)
{
if (boardCard == card)
{
return true;
}
}
return false;
}
// Fake function that evaluates hand strength. This is just for example real evaluator is different. So no need to optimize this.
size_t GetHandStrength(const std::vector<int>& board, int card, int b)
{
size_t stren = 0;
for (int boardCard : board)
{
stren += boardCard;
}
return stren + card + b;
}
// Returns equity for the board
float GetEquity(const std::vector<int>& board)
{
float equity = 0;
for (int c1 = 0; c1 < card_count; c1++) // Player1 card
{
if (Contains(board, c1))
{
continue;
}
for (int c2 = 0; c2 < card_count; c2++) // Player2 card
{
if (c1 == c2 || Contains(board, c2))
{
continue;
}
size_t usedBoards = 0; // number of boards are possible for this players and board cards
float currentEquity = 0;
for (int b = 0; b < card_count; b++) // Iterating river board cards
{
if (Contains(board, b))
{
continue;
}
if (b == c1 || b == c2) // Check that there are no conflict with players cards
{
continue;
}
size_t p1stren = GetHandStrength(board, c1, b);
size_t p2stren = GetHandStrength(board, c2, b);
if (p1stren > p2stren)
{
currentEquity += 1.0;
}
else if (p1stren < p2stren)
{
currentEquity -= 1.0;
}
usedBoards++;
}
currentEquity /= usedBoards;
equity += currentEquity;
}
}
return equity;
}
int main()
{
clock_t begin = clock();
std::vector<int> board = { 0, 1, 2, 21 }; // Some turn random board (4 cards)
float equity = GetEquity(board);;
cout << "equity: " << equity << endl;
return 0;
}
When iterating over the hand and board cards I need to check that board doesn't already contains the card, so I need to iterate over the board cards again and again. This is done by the bool Contains(const std::vector<int>& board, int card)
also checks like if (b == c1 || b == c2)
What can you suggest to optimize this part?