openpql_prelude/game/
street.rs1use super::{Board, Card64, CardCount, Display, FromStr, ParseError};
2
3#[derive(
4 Debug, Clone, PartialEq, Eq, Copy, PartialOrd, Ord, Default, Display,
5)]
6pub enum Street {
7 #[default]
8 Preflop = 0,
9 Flop,
10 Turn,
11 River,
12}
13
14impl Street {
15 #[allow(clippy::cast_possible_truncation)]
17 pub const fn board_card_count(self) -> CardCount {
18 (match self {
19 Self::Preflop => Board::N_PREFLOP,
20 Self::Flop => Board::N_FLOP,
21 Self::Turn => Board::N_TURN,
22 Self::River => Board::N_RIVER,
23 }) as CardCount
24 }
25}
26
27impl FromStr for Street {
28 type Err = ParseError;
29
30 fn from_str(s: &str) -> Result<Self, Self::Err> {
31 match s.to_ascii_lowercase().trim() {
32 "preflop" => Ok(Self::Preflop),
33 "flop" => Ok(Self::Flop),
34 "turn" => Ok(Self::Turn),
35 "river" => Ok(Self::River),
36
37 _ => Err(ParseError::InvalidStreet(s.into())),
38 }
39 }
40}
41
42impl From<(Board, Street)> for Card64 {
43 fn from((board, street): (Board, Street)) -> Self {
44 match street {
45 Street::Preflop => Self::EMPTY,
46 Street::Flop => board.to_c64_flop(),
47 Street::Turn => board.to_c64_flop() | board.to_c64_turn(),
48 Street::River => {
49 board.to_c64_flop() | board.to_c64_turn() | board.to_c64_river()
50 }
51 }
52 }
53}
54
55#[cfg(any(test, feature = "quickcheck"))]
56impl quickcheck::Arbitrary for Street {
57 #[cfg_attr(coverage_nightly, coverage(off))]
58 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
59 #[allow(unused)]
60 const fn completeness_check(e: Street) {
61 match e {
62 Street::Preflop
63 | Street::Flop
64 | Street::Turn
65 | Street::River => (),
66 }
67 }
68 *g.choose(&[Self::Preflop, Self::Flop, Self::Turn, Self::River])
69 .unwrap()
70 }
71}
72
73#[cfg(test)]
74#[cfg_attr(coverage_nightly, coverage(off))]
75pub mod tests {
76 use super::*;
77 use crate::*;
78
79 #[test]
80 fn test_to_card64_with_board() {
81 assert_eq!(
82 Card64::from((board!("As Kh Qd Jc Ts"), Street::Preflop)),
83 c64!("")
84 );
85
86 assert_eq!(
87 Card64::from((board!("As Kh Qd Jc Ts"), Street::Flop)),
88 c64!("As Kh Qd")
89 );
90
91 assert_eq!(
92 Card64::from((board!("As Kh Qd Jc Ts"), Street::Turn)),
93 c64!("As Kh Qd Jc")
94 );
95
96 assert_eq!(
97 Card64::from((board!("As Kh Qd Jc Ts"), Street::River)),
98 c64!("As Kh Qd Jc Ts")
99 );
100
101 assert_eq!(
102 Card64::from((board!("As Kh Qd"), Street::River)),
103 c64!("As Kh Qd")
104 );
105
106 assert!(Card64::from((board!(""), Street::River)).is_empty());
107 }
108
109 #[quickcheck]
110 fn test_n_board(street: Street) {
111 let n = match street {
112 Street::Preflop => 0,
113 Street::Flop => 3,
114 Street::Turn => 4,
115 Street::River => 5,
116 };
117
118 assert_eq!(street.board_card_count(), n);
119 }
120
121 #[test]
122 fn test_from_str() {
123 assert_eq!(Ok(Street::Preflop), "preFlop".parse());
124 assert_eq!(Ok(Street::Flop), "Flop".parse());
125 assert_eq!(Ok(Street::Turn), "tUrn".parse());
126 assert_eq!(Ok(Street::River), "riVer".parse());
127
128 assert_eq!(Ok(Street::Flop), " flop ".parse(), "should trim");
129
130 assert!("invalid".parse::<Street>().is_err());
131 }
132}