5
|
1 |
/// Implementation of a Row of Cards on the Table (max 5) |
4
|
2 |
|
5
|
3 |
// We use std::mem::take to do tricks with vector members and ownership. |
4
|
4 |
use std::{collections::VecDeque, mem}; |
|
5 |
|
|
6 |
use crate::card::Card; |
|
7 |
|
|
8 |
#[derive(Debug)] |
5
|
9 |
/// A `Row` of [`Card`]s, in a two-ended vector (`VecDeque`). |
|
10 |
/// A Row is smart and can do a few things on herself. |
4
|
11 |
pub(crate) struct Row { |
|
12 |
cards: VecDeque<Card>, |
|
13 |
} |
|
14 |
|
|
15 |
impl Row { |
5
|
16 |
/// The maximum length of a Row. More cards cause overflow and force collection. |
4
|
17 |
const MAX_LEN: usize = 5; |
|
18 |
|
5
|
19 |
/// Create a new [`Row`] with capacity of 5 [`Card`]s. |
4
|
20 |
pub(crate) fn new() -> Self { |
|
21 |
Row { |
|
22 |
cards: VecDeque::with_capacity(5), |
|
23 |
} |
|
24 |
} |
|
25 |
|
5
|
26 |
/// Push a [`Card`] to the end of the Row. |
|
27 |
/// If it would make Row over maximum length the function |
|
28 |
/// returns the content of the row, and then push the new |
|
29 |
/// Card as the new Row head. |
|
30 |
/// Otherwise return None. |
|
31 |
/// # Arguments |
|
32 |
/// - [`Card`] - the new card to put into the Row |
|
33 |
/// # Returns |
|
34 |
/// - `Option<VecDequeue<Card>>` - None or Some(cards) to be collected from Row |
4
|
35 |
pub(crate) fn push_or_collect( &mut self, card: Card ) -> Option<VecDeque<Card>> { |
|
36 |
trace!("Called push_or_collect on row {:?}", &self); |
|
37 |
if self.cards.len() < Self::MAX_LEN { |
|
38 |
trace!("Less than {} cards, putting at the end", Self::MAX_LEN); |
|
39 |
self.cards.push_back(card); |
|
40 |
None |
|
41 |
|
|
42 |
} else { |
|
43 |
trace!("Row is full, len {}, maxlen {}", self.cards.len(), Self::MAX_LEN); |
5
|
44 |
// Row overflow. We take out `cards` from `self` with its ownership and |
|
45 |
// leave the default (empty VecDeque) in its place, without disturbing |
|
46 |
// `self` ownership. |
4
|
47 |
let row_cards = mem::take( &mut self.cards ); |
5
|
48 |
// We put new card as new Row head. |
4
|
49 |
self.cards.push_back(card); |
|
50 |
if self.cards.len() != 1 { |
|
51 |
panic!("New row must have one card, not {}", self.cards.len()); |
|
52 |
} |
5
|
53 |
// Return the collected old Row content |
4
|
54 |
Some(row_cards) |
|
55 |
} |
|
56 |
} |
|
57 |
|
5
|
58 |
/// Take out all `cards` (and their ownership) and return them. |
4
|
59 |
pub(crate) fn take_row( &mut self ) -> VecDeque<Card> { |
|
60 |
// take cards and empty the row |
|
61 |
mem::take( &mut self.cards ) |
|
62 |
} |
|
63 |
|
5
|
64 |
/// Return the `value` of the last card in the Row. |
|
65 |
/// This is the largest value since the Row is always ordered. |
4
|
66 |
pub(crate) fn last_card_value(&self) -> i8 { |
|
67 |
// println!("last_card_value: cards {:?}, len {}", self.cards, self.cards.len()); |
|
68 |
self.cards.get( self.cards.len()-1 ).unwrap().value |
|
69 |
} |
|
70 |
|
|
71 |
// sum of row card points |
|
72 |
pub(crate) fn sum(&self) -> i32 { |
|
73 |
let mut sum: i32 = 0; |
|
74 |
self.cards.iter().for_each(|card| { |
|
75 |
sum += card.points as i32; |
|
76 |
}); |
|
77 |
sum |
|
78 |
} |
|
79 |
|
5
|
80 |
#[allow(dead_code)] |
|
81 |
/// We could use this, but... borrow checker, you know. Needs more love. |
|
82 |
/// I could have used `_len` to shut up the dead_code warning, so this is |
|
83 |
/// another example to do it the other way. |
4
|
84 |
pub fn len(&self) -> usize { |
|
85 |
self.cards.len() |
|
86 |
} |
|
87 |
} |