1#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)]
12pub enum Turn {
13 Terminal,
14 Chance,
15 Choice(usize),
16}
17
18impl Turn {
19 pub fn position(&self) -> usize {
21 match self {
22 Self::Choice(c) => *c,
23 _ => panic!("don't ask"),
24 }
25 }
26 pub fn is_choice(&self) -> bool {
28 matches!(self, Self::Choice(_))
29 }
30 pub fn is_chance(&self) -> bool {
32 matches!(self, Self::Chance)
33 }
34 pub fn is_terminal(&self) -> bool {
36 matches!(self, Self::Terminal)
37 }
38 pub fn display(&self) -> usize {
40 match self {
41 Self::Choice(c) => *c + 1,
42 _ => panic!("don't ask"),
43 }
44 }
45 pub fn label(&self) -> String {
47 format!("P{}", self.display())
48 }
49}
50
51impl rbp_core::Arbitrary for Turn {
52 fn random() -> Self {
53 Self::Choice(rand::random_range(0..rbp_core::N))
54 }
55}
56
57impl From<usize> for Turn {
58 fn from(player: usize) -> Self {
59 Self::Choice(player)
60 }
61}
62
63
64impl TryFrom<&str> for Turn {
65 type Error = anyhow::Error;
66 fn try_from(s: &str) -> Result<Self, Self::Error> {
67 match s {
68 "XX" => Ok(Self::Terminal),
69 "??" => Ok(Self::Chance),
70 turn => turn[1..]
71 .parse::<usize>()
72 .map(Self::Choice)
73 .map_err(|_| anyhow::anyhow!("invalid player turn")),
74 }
75 }
76}
77
78impl std::fmt::Display for Turn {
79 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80 match self {
81 Self::Choice(c) => write!(f, "P{}", c),
82 Self::Terminal => write!(f, "-"),
83 Self::Chance => write!(f, "?"),
84 }
85 }
86}
87
88#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
95pub enum PositionName {
96 BTN,
97 SB,
98 BB,
99 UTG(usize),
100 MP(usize),
101 HJ,
102 CO,
103}
104
105impl PositionName {
106 pub fn from_seat(seat: usize, dealer: usize, table: usize) -> Self {
108 let offset = (seat + table - dealer) % table;
109 match table {
110 2 => match offset {
111 0 => Self::BTN,
112 _ => Self::BB,
113 },
114 6 => match offset {
115 0 => Self::BTN,
116 1 => Self::SB,
117 2 => Self::BB,
118 3 => Self::UTG(0),
119 4 => Self::HJ,
120 _ => Self::CO,
121 },
122 _ => match offset {
123 0 => Self::BTN,
124 1 => Self::SB,
125 2 => Self::BB,
126 3 => Self::UTG(0),
127 4 => Self::UTG(1),
128 5 => Self::MP(0),
129 6 => Self::MP(1),
130 7 => Self::HJ,
131 _ => Self::CO,
132 },
133 }
134 }
135}
136
137impl std::fmt::Display for PositionName {
138 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
139 match self {
140 Self::BTN => write!(f, "BTN"),
141 Self::SB => write!(f, "SB"),
142 Self::BB => write!(f, "BB"),
143 Self::UTG(0) => write!(f, "UTG"),
144 Self::UTG(n) => write!(f, "UTG+{}", n),
145 Self::MP(0) => write!(f, "MP"),
146 Self::MP(n) => write!(f, "MP+{}", n),
147 Self::HJ => write!(f, "HJ"),
148 Self::CO => write!(f, "CO"),
149 }
150 }
151}