Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exploitability Calculation - ICM #28

Closed
Barcode9 opened this issue Jun 9, 2023 · 4 comments
Closed

Exploitability Calculation - ICM #28

Barcode9 opened this issue Jun 9, 2023 · 4 comments

Comments

@Barcode9
Copy link

Barcode9 commented Jun 9, 2023

Hi,

first of all very nice and clean project, the GUI in the other project is very impressive.

I have been working on trying to implement custom ICM payouts, which seems easy enough if I just change the evaluate function to call my custom ICM function and then have amount_lose and amount_win be ICM values. In a first test, the convergence was starting and the results look promising.

Now the problem that I have is the exploitability calculation, as the solver will stop after much few iterations than with chipev and I can't seem to figure out how the computation works. It says:

/// Computes the expected values of the MES (Maximally Exploitative Strategy) of each player.
///
/// The bias, i.e., (starting pot) / 2, is already subtracted to increase the significant figures.
/// Therefore, the average of the return value corresponds to the exploitability value if not raked.
#[inline]
pub fn compute_mes_ev<T: Game>(game: &T) -> [f32; 2] {

But I can't find where this subtraction is happening. Admittedly I have never coded in Rust or C++ before so I apologize if I am missing something very obvious. How would I go to set the initial value for the exploitability?

@b-inary
Copy link
Owner

b-inary commented Jun 9, 2023

The subtraction is exactly what the evaluate function does, for example, see:

let pot = (self.tree_config.starting_pot + 2 * node.amount) as f64;
let half_pot = 0.5 * pot;
let rake = min(pot * self.tree_config.rake_rate, self.tree_config.rake_cap);
let amount_win = (half_pot - rake) / self.num_combinations;
let amount_lose = -half_pot / self.num_combinations;

So if you have already modified these amount_win and amount_lose properly, this should not be a problem. Rather, I suspect you need to modify the following conditional branch:

let mes_ev = compute_mes_ev(game);
if !game.is_raked() {
(mes_ev[0] + mes_ev[1]) * 0.5
} else {
let current_ev = compute_current_ev(game);
((mes_ev[0] - current_ev[0]) + (mes_ev[1] - current_ev[1])) * 0.5
}

Introducing ICM breaks the zero-sum property, so the if clause shortcut (L286) cannot be used. I am not confident, but I think the problem can be solved by simply using this else clause when calculating with the ICM.

@Barcode9
Copy link
Author

Thanks that seemed to have stopped the convergence to 0!

@nastynaz
Copy link

@Barcode9 did you manage to implement ICM calculations? I'm currently working on it but not sure how the payoffs should be adjusted. I'm a fairly experienced rust dev with an academic background in game theory, but I'm not so knowledgeable about the poker theory of ICM payoffs. If you want to work together / help me out let me know, I'd greatly appreciate it.

@Barcode9
Copy link
Author

Barcode9 commented Jul 22, 2024

Hi Naz,

Its been a while since I did this, I just wanted to see if I could implement ICM, the results looked reasonable so I figured it worked, but I didn't do extensive testing.

evaluation.txt

See the evaluation.rs file I changed. You also need to change what b-inary mentioned above.

I think I read in the ICM mapping from a HoldemResources Node Export like this:

So you have a stack -> utility mapping and then I just did linear interpolation if I didn't have the exact mapping.
state.json

Hope that helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants