1mod four_card_pegging;
2mod one_card_pegging;
3mod three_card_pegging;
4mod two_card_pegging;
5
6pub use self::four_card_pegging::FourCardPegging;
7pub use self::one_card_pegging::OneCardPegging;
8pub use self::three_card_pegging::ThreeCardPegging;
9pub use self::two_card_pegging::TwoCardPegging;
10
11use crate::card::Card;
12use crate::CribbageCoreError;
13
14#[derive(Default)]
15pub struct Pegger {
16 count: u8,
17 played_cards: Vec<Card>,
18}
19
20impl Pegger {
21 pub fn new() -> Pegger {
22 Pegger {
23 count: 0,
24 played_cards: Vec::new(),
25 }
26 }
27
28 fn is_run(cards: &[Card]) -> bool {
29 if cards.len() < 3 {
30 return false;
31 }
32
33 let mut sorted = cards.to_vec();
34 sorted.sort();
35
36 for i in 1..sorted.len() {
37 if sorted[i].rank().ordinal() != sorted[i - 1].rank().ordinal() + 1 {
38 return false;
39 }
40 }
41
42 true
43 }
44
45 pub fn count(&self) -> u8 {
46 self.count
47 }
48
49 pub fn play_card(&mut self, card: Card) -> Result<u8, CribbageCoreError> {
56 let new_count = self.count + card.rank().value();
57 if new_count > 31 {
58 return Err(CribbageCoreError::InvalidCard);
59 }
60
61 self.count = new_count;
62
63 let mut points = match self.count {
64 15 => 2,
65 31 => 1,
66 _ => 0,
67 };
68
69 let mut cards_with_same_rank = 0;
70 for played_card in self.played_cards.iter().rev() {
71 if played_card.rank() == card.rank() {
72 cards_with_same_rank += 1;
73 } else {
74 break;
75 }
76 }
77
78 self.played_cards.push(card);
79
80 points += match cards_with_same_rank {
81 1 => 2,
82 2 => 6,
83 3 => 12,
84 _ => 0,
85 };
86
87 for i in 0..self.played_cards.len() {
88 let card_slice = &self.played_cards[i..self.played_cards.len()];
89 if Pegger::is_run(card_slice) {
90 points += card_slice.len() as u8;
91 break;
92 }
93 }
94
95 Ok(points)
96 }
97
98 pub fn reset(&mut self) {
99 self.count = 0;
100 self.played_cards.clear();
101 }
102}
103
104#[cfg(test)]
105mod test {
106 use crate::card::{Card, Rank, Suit};
107 use crate::CribbageCoreError;
108 use crate::Pegger;
109
110 #[test]
111 fn test_is_run() {
112 assert_eq!(Pegger::is_run(&[]), false);
113 assert_eq!(Pegger::is_run(&[Card::new(Rank::Ace, Suit::Spades)]), false);
114 assert_eq!(
115 Pegger::is_run(&[
116 Card::new(Rank::Ace, Suit::Spades),
117 Card::new(Rank::Two, Suit::Spades)
118 ]),
119 false
120 );
121 assert_eq!(
122 Pegger::is_run(&[
123 Card::new(Rank::Ace, Suit::Spades),
124 Card::new(Rank::Two, Suit::Spades),
125 Card::new(Rank::Three, Suit::Spades)
126 ]),
127 true
128 );
129 assert_eq!(
130 Pegger::is_run(&[
131 Card::new(Rank::Ace, Suit::Spades),
132 Card::new(Rank::Two, Suit::Spades),
133 Card::new(Rank::Four, Suit::Spades)
134 ]),
135 false
136 );
137 assert_eq!(
138 Pegger::is_run(&[
139 Card::new(Rank::Two, Suit::Spades),
140 Card::new(Rank::Three, Suit::Spades),
141 Card::new(Rank::Ace, Suit::Spades)
142 ]),
143 true
144 );
145 assert_eq!(
146 Pegger::is_run(&[
147 Card::new(Rank::Ace, Suit::Hearts),
148 Card::new(Rank::Two, Suit::Clubs),
149 Card::new(Rank::Three, Suit::Diamonds),
150 Card::new(Rank::Four, Suit::Spades)
151 ]),
152 true
153 );
154 assert_eq!(
155 Pegger::is_run(&[
156 Card::new(Rank::Four, Suit::Hearts),
157 Card::new(Rank::Two, Suit::Clubs),
158 Card::new(Rank::Ace, Suit::Diamonds),
159 Card::new(Rank::Three, Suit::Spades)
160 ]),
161 true
162 );
163 assert_eq!(
164 Pegger::is_run(&[
165 Card::new(Rank::Ace, Suit::Spades),
166 Card::new(Rank::Two, Suit::Spades),
167 Card::new(Rank::Three, Suit::Spades),
168 Card::new(Rank::Five, Suit::Spades)
169 ]),
170 false
171 );
172 }
173
174 #[test]
175 fn test_play_card() {
176 let mut pegger = Pegger::new();
177 assert_eq!(
178 pegger
179 .play_card(Card::new(Rank::Ace, Suit::Spades))
180 .unwrap(),
181 0
182 );
183 assert_eq!(
184 pegger
185 .play_card(Card::new(Rank::Ace, Suit::Hearts))
186 .unwrap(),
187 2
188 );
189 assert_eq!(
190 pegger.play_card(Card::new(Rank::Ace, Suit::Clubs)).unwrap(),
191 6
192 );
193 assert_eq!(
194 pegger
195 .play_card(Card::new(Rank::Ace, Suit::Diamonds))
196 .unwrap(),
197 12
198 );
199 assert_eq!(
200 pegger.play_card(Card::new(Rank::Two, Suit::Clubs)).unwrap(),
201 0
202 );
203 assert_eq!(
204 pegger
205 .play_card(Card::new(Rank::Three, Suit::Spades))
206 .unwrap(),
207 3
208 );
209 assert_eq!(
210 pegger
211 .play_card(Card::new(Rank::Four, Suit::Diamonds))
212 .unwrap(),
213 4
214 );
215 assert_eq!(
216 pegger
217 .play_card(Card::new(Rank::Two, Suit::Hearts))
218 .unwrap(),
219 5
220 );
221 assert_eq!(
222 pegger
223 .play_card(Card::new(Rank::Eight, Suit::Clubs))
224 .unwrap(),
225 0
226 );
227 assert_eq!(
228 pegger
229 .play_card(Card::new(Rank::Eight, Suit::Spades))
230 .unwrap(),
231 3
232 );
233 pegger.reset();
234
235 assert_eq!(
236 pegger
237 .play_card(Card::new(Rank::Ten, Suit::Spades))
238 .unwrap(),
239 0
240 );
241 assert_eq!(
242 pegger
243 .play_card(Card::new(Rank::Five, Suit::Spades))
244 .unwrap(),
245 2
246 );
247 assert_eq!(
248 pegger.play_card(Card::new(Rank::Ten, Suit::Clubs)).unwrap(),
249 0
250 );
251 assert_eq!(
252 pegger
253 .play_card(Card::new(Rank::Five, Suit::Diamonds))
254 .unwrap(),
255 0
256 );
257 assert_eq!(
258 pegger
259 .play_card(Card::new(Rank::Ace, Suit::Hearts))
260 .unwrap(),
261 1
262 );
263 assert_eq!(
264 pegger.play_card(Card::new(Rank::Ace, Suit::Spades)),
265 Err(CribbageCoreError::InvalidCard)
266 );
267 }
268}