NicolleLouis / balatro-hand-stats

Compute hand probability based on deck
MIT License
1 stars 0 forks source link

About Finding Best Discard #1

Closed Agoraaa closed 6 months ago

Agoraaa commented 6 months ago

Hi, I've tried to write an algorithm to find the best discard for getting straight before but failed. I want to ask if there is a solution to the problem I'll say, also you might be interested in implementing it in this repo.

I want to find the best discard for getting straight in a 8 hand size & 2 discard scenario. For first draw I just draw 8 cards. Then there'll be 219 possible discard combinations. Then I'll draw (at most) ${52-8 \choose 5} =1086008$ possible card combination for each hand. After that I'll have 1 discard remaining. Thankfully I don't need to iterate through every possible draw for every possible discard because I can count the outs and find the straight probability. For example, if I were calculating flush draw chance for spades with 3 spades in hand can be calculated with hypergeometric distribution with parameters $k=2,n=5,K=10,N=46$. Similar thing can be done with calculating Ace high, King high etc. straight chances independently. This is where my problem occurs, I can't simply add all straight chances to calculate the total straight chance because events are not independent. It's way easier to get a Q-high straight if you have a K-high one. I don't know how to approximate this value in a $O(1)$ manner. But if I could, calculating the best straight discard would require evaluating $219\cdot1086008\cdot13=3\cdot10^9$ possible situations which would take ~30 seconds in a single thread without optimizations. So it is in the doable territory. So my question is, is there an $O(1)$ formula for calculating straight chance?

NicolleLouis commented 6 months ago

Hey, thanks for your question.

I have a first questions: where is your 13 factor coming from in the situation computation? A proposition: 3e9 is indeed doable territorry (even if the current code is probably a bit too slow for that to be realistic) but double discard scenario is not imaginable for this scale.

So maybe: this computation could give you the best discard possible:

  1. Given a hand, generate the 219 potential dicards D.
  2. For each D, generate all the possible card draws (between 1086008 and 48).
  3. For each of this draw, compute a hand score representing the closeness to a straight (must not follow this kind of line, but can be a score close to the StraightEngineV3 which will be way faster).
  4. Compute the average of those scores.
  5. Return the best discard.

It's not perfect since you have to rely on a non exhaustive computation in the middle (because of multiple discard and the total number of cases with multiple decisions), but you will probably get quite a good result already

Agoraaa commented 6 months ago

13 should've been 8 my bad. Its the number of X-high straights.

My main goal was to get the optimal play to calculate the actual straight chance and observe data enough to develop some heuristics for discarding. Your idea sounds good and will probably result in better straight chances than the current one. Anyways, thanks for responding! You can close this if you want

NicolleLouis commented 6 months ago

I'll give it a try, not sure the code is fast enough currently to handle that in a reasonnable time currently. I'll try to increase it's efficiency to allow this kind of computations