open_pql/functions/
five_card_hi_hand_number.rs

1use super::*;
2
3pub static HOLDEM_MAP_DATA: LazyLock<Vec<u8>> = LazyLock::new(|| {
4    include_bytes!(concat!(env!("OUT_DIR"), "/holdem-map-ranking-number.bin"))
5        .to_vec()
6});
7
8pub static SHORTDECK_MAP_DATA: LazyLock<Vec<u8>> = LazyLock::new(|| {
9    include_bytes!(concat!(
10        env!("OUT_DIR"),
11        "/shortdeck-map-ranking-number.bin"
12    ))
13    .to_vec()
14});
15
16pub static HOLDEM_MAP: LazyLock<FxHashMap<i16, u16>> = LazyLock::new(|| {
17    FxHashMap::<i16, u16>::read_from_buffer(&HOLDEM_MAP_DATA).unwrap()
18});
19
20pub static SHORTDECK_MAP: LazyLock<FxHashMap<i16, u16>> = LazyLock::new(|| {
21    FxHashMap::<i16, u16>::read_from_buffer(&SHORTDECK_MAP_DATA).unwrap()
22});
23
24const NUM_OF_DISTICNT_RANKINGS: PQLInteger = 7462;
25const NUM_OF_DISTICNT_RANKINGS_SHORT: PQLInteger = 840;
26
27/// Note:
28/// the number is for 5 card hand (the set of possible rankings on river may be smaller than this.)
29#[pqlfn(arg, rtn, eval)]
30pub fn five_card_hi_hand_number(
31    hand: &Hand,
32    street: PQLStreet,
33    (game, board): (PQLGame, Board),
34) -> PQLInteger {
35    let ranking = hi_rating(hand, street, (game, board));
36
37    match game {
38        PQLGame::Holdem | PQLGame::Omaha => {
39            NUM_OF_DISTICNT_RANKINGS
40                - PQLInteger::from(HOLDEM_MAP[&ranking.to_i16()])
41        }
42
43        PQLGame::ShortDeck => {
44            NUM_OF_DISTICNT_RANKINGS_SHORT
45                - PQLInteger::from(SHORTDECK_MAP[&ranking.to_i16()])
46        }
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53    use crate::*;
54
55    #[test]
56    fn test_five_card_hi_hand_number_holdem() {
57        fn flop(hand: &Hand, board: Board) -> PQLInteger {
58            five_card_hi_hand_number(
59                hand,
60                PQLStreet::Flop,
61                (PQLGame::Holdem, board),
62            )
63        }
64
65        assert_eq!(1, flop(&cards!["AsKs"], board!("QsJsTs 5d6c")));
66        assert_eq!(10, flop(&cards!["As2s"], board!("3s4s5s 5d6c")));
67
68        assert_eq!(11, flop(&cards!["AsAh"], board!("AdAcKs 5d6c")));
69        assert_eq!(166, flop(&cards!["2s2h"], board!("2d2c3s 5d6c")));
70
71        assert_eq!(167, flop(&cards!["AsAh"], board!("AdKcKs 5d6c")));
72        assert_eq!(322, flop(&cards!["2s2h"], board!("2d3c3s 5d6c")));
73
74        assert_eq!(323, flop(&cards!["AsKs"], board!("QsJs9s 5d6c")));
75        assert_eq!(1599, flop(&cards!["2s3s"], board!("4s5s7s 5d6c")));
76
77        assert_eq!(1600, flop(&cards!["AsKs"], board!("QsJsTh 5d6c")));
78        assert_eq!(1609, flop(&cards!["As2s"], board!("3s4s5h 5d6c")));
79
80        assert_eq!(1610, flop(&cards!["AsAh"], board!("AdKcQs 5d6c")));
81        assert_eq!(2467, flop(&cards!["2s2h"], board!("2d3c4s 5d6c")));
82
83        assert_eq!(2468, flop(&cards!["AsAh"], board!("KdKcQs 5d6c")));
84        assert_eq!(3325, flop(&cards!["2s2h"], board!("3d3c4s 5d6c")));
85
86        assert_eq!(3326, flop(&cards!["AsAh"], board!("KdQcJs 5d6c")));
87        assert_eq!(6185, flop(&cards!["2s2h"], board!("3d4c5s 5d6c")));
88
89        assert_eq!(6186, flop(&cards!["AsKh"], board!("QdJc9s 5d6c")));
90        assert_eq!(7462, flop(&cards!["2s3h"], board!("4d5c7s 5d6c")));
91    }
92
93    #[test]
94    fn test_five_card_hi_hand_number_shortdeck() {
95        fn flop(hand: &Hand, board: Board) -> PQLInteger {
96            five_card_hi_hand_number(
97                hand,
98                PQLStreet::Flop,
99                (PQLGame::ShortDeck, board),
100            )
101        }
102
103        assert_eq!(1, flop(&cards!["AsKs"], board!("QsJsTs 5d6c")));
104        assert_eq!(5, flop(&cards!["Ts9s"], board!("8s7sAs 5d6c")));
105
106        assert_eq!(6, flop(&cards!["AsAh"], board!("AdAcKs 5d6c")));
107        assert_eq!(61, flop(&cards!["7s7h"], board!("7d7c8s 5d6c")));
108
109        assert_eq!(62, flop(&cards!["AsKs"], board!("QsJs9s 5d6c")));
110        assert_eq!(112, flop(&cards!["QsTs"], board!("9s8s7s 5d6c")));
111
112        assert_eq!(113, flop(&cards!["AsAh"], board!("AdKcKs 5d6c")));
113        assert_eq!(168, flop(&cards!["7s7h"], board!("7d8c8s 5d6c")));
114
115        assert_eq!(169, flop(&cards!["AsKs"], board!("QsJsTh 5d6c")));
116        assert_eq!(173, flop(&cards!["Ts9s"], board!("8s7sAh 5d6c")));
117
118        assert_eq!(174, flop(&cards!["AsAh"], board!("AdKcQs 5d6c")));
119        assert_eq!(341, flop(&cards!["7s7h"], board!("7d8c9s 5d6c")));
120
121        assert_eq!(342, flop(&cards!["AsAh"], board!("KdKcQs 5d6c")));
122        assert_eq!(509, flop(&cards!["8s8h"], board!("7d7c9s 5d6c")));
123
124        assert_eq!(510, flop(&cards!["AsAh"], board!("KdQcJs 5d6c")));
125        assert_eq!(789, flop(&cards!["7s7h"], board!("8d9cTs 5d6c")));
126
127        assert_eq!(790, flop(&cards!["AsKh"], board!("QdJc9s 5d6c")));
128        assert_eq!(840, flop(&cards!["QsTh"], board!("9d8c7s 5d6c")));
129    }
130}