deus-x-mackina / poker

A Rust crate for evaluating poker hands
MIT License
12 stars 5 forks source link

Ranking of the cards is insufficient #1

Closed alanmorgan closed 2 years ago

alanmorgan commented 2 years ago

When declaring a hand to be a flush, it's not enough to say that it's a J high flush. To determine which of two flushes is better, you might need all the cards (comparing J 10 7 4 3 to J 10 7 4 2, for example).

In general, the EvalClass needs to include information about all the cards in the hand, to be used in tie-breakers. This is even true for four of a kind, as in some poker games there are community cards and it is possible for multiple people to have four aces and for the winner to be determined by the other card.

deus-x-mackina commented 2 years ago

EvalClass is more of a utility enum than anything meant to help identify what sort of poker hand you have - in general, the name of the hand (i.e., "flush") and the high card are enough for most people. Eval, which is returned from Evaluator::evaluate contains much more detailed information about the hand in question, including kicker cards which you are referring to. Take, for example, the following snippet which you can run in v0.4.0:

use poker::{Card, cards, Evaluator};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Get cards.
    let better_flush: Vec<Card> = cards!("Jh Th 7h 4h 3h").try_collect()?;
    let worse_flush: Vec<Card> = cards!("Jc Tc 7c 4c 2c").try_collect()?;

    // Get `Eval` for each
    let e = Evaluator::new();
    let better_flush = e.evaluate(better_flush)?;
    let worse_flush = e.evaluate(worse_flush)?;

    // As you say, the `EvalClass` for each is identical:
    println!("{}", better_flush.class()); 
    // > Flush, jack-high
    println!("{}", worse_flush.class());
    // > Flush, jack-high

    // But, we can be sure they are not truly equal hands.
    println!("{}", better_flush > worse_flush);
    // > true

    Ok(())
}

I am now realizing, however, that hand comparison is not well documented or explained, besides the implementation of >, <, and = for Eval. I thought there was a is_better_than() type of function available, but this is only for PokerHandRank, which isn't part of the public API.

I will leave this issue open until I update the documentation with clarfiication and maybe even add extra functions to the Eval struct.

Thank you for weighing in!