30 rows_busted: 0, |
41 rows_busted: 0, |
31 wins: 0, |
42 wins: 0, |
32 } |
43 } |
33 } |
44 } |
34 |
45 |
35 // get one card from th dealer |
46 /// get one card from the dealer |
36 pub(crate) fn get_card( &mut self, card: Card ) { |
47 pub(crate) fn get_card( &mut self, card: Card ) { |
37 trace!("Player {} got a card {:?}, cards before {}", self.name, &card, self.hand.len()); |
48 trace!("Player {} got a card {:?}, cards before {}", self.name, &card, self.hand.len()); |
38 self.hand.push(card); |
49 self.hand.push(card); |
39 } |
50 } |
40 |
51 |
41 // throw a card from hand to the table |
52 /// throw a card from hand to the table |
42 pub(crate) fn throw_card( &mut self )->Card { |
53 pub(crate) fn throw_card( &mut self )->Card { |
43 if let Some(c) = self.hand.pop() { |
54 if let Some(c) = self.hand.pop() { |
44 trace!("Player {} throws a card {:?}", self.name, &c); |
55 trace!("Player {} throws a card {:?}", self.name, &c); |
45 c |
56 c |
46 } else { |
57 } else { |
47 panic!("throw_card: Player {} has no card in hand!", self.name); |
58 panic!("throw_card: Player {} has no card in hand!", self.name); |
48 } |
59 } |
49 } |
60 } |
50 |
61 |
51 // get a busted row of cards |
62 /// get a busted row of cards |
52 pub(crate) fn give_pile( &mut self, cards: VecDeque<Card> ) { |
63 pub(crate) fn give_pile( &mut self, cards: VecDeque<Card> ) { |
53 for c in cards.into_iter() { |
64 for c in cards.into_iter() { |
54 self.game_point += c.points as i32; |
65 self.game_point += c.points as i32; |
55 self.pile.push_back(c); |
66 self.pile.push_back(c); |
56 } |
67 } |
57 self.rows_busted += 1; |
68 self.rows_busted += 1; |
58 trace!("Player {} got busted, count {}", self.name, &self.rows_busted); |
69 trace!("Player {} got busted, count {}", self.name, &self.rows_busted); |
59 } |
70 } |
60 |
71 |
|
72 /// Get the name of the Player |
61 pub fn get_name(&self) -> &String { |
73 pub fn get_name(&self) -> &String { |
62 &self.name |
74 &self.name |
63 } |
75 } |
64 |
76 |
65 // ask the player their score |
77 /// ask the player their score |
66 pub(crate) fn get_points( &self ) -> i32 { |
78 pub(crate) fn get_points( &self ) -> i32 { |
67 self.game_point |
79 self.game_point |
68 } |
80 } |
69 |
81 |
|
82 /// Get the number of games won |
70 pub fn get_wins(&self) -> i32 { |
83 pub fn get_wins(&self) -> i32 { |
71 self.wins |
84 self.wins |
72 } |
85 } |
73 |
86 |
|
87 /// Player won this game, increment counter |
74 pub(crate) fn inc_wins( &mut self ) { |
88 pub(crate) fn inc_wins( &mut self ) { |
75 self.wins += 1; |
89 self.wins += 1; |
76 } |
90 } |
77 |
91 |
|
92 /// Get total points of all games |
78 pub fn get_total_points(&self) -> i32 { |
93 pub fn get_total_points(&self) -> i32 { |
79 self.total_point |
94 self.total_point |
80 } |
95 } |
81 |
96 |
|
97 /// Get the number of total busted rows |
82 pub fn get_rows_busted(&self) -> i32 { |
98 pub fn get_rows_busted(&self) -> i32 { |
83 self.rows_busted |
99 self.rows_busted |
84 } |
100 } |
85 |
101 |
86 // give back cards from the pile |
102 /// give back cards from the player's pile ino the Deck |
87 pub(crate) fn get_pile( &mut self ) -> VecDeque<Card> { |
103 pub(crate) fn get_pile( &mut self ) -> VecDeque<Card> { |
88 trace!("Player {} gives back their pile", self.name); |
104 trace!("Player {} gives back their pile", self.name); |
|
105 // Here we take the ownership of the `pile` VecDeque<Card> structure, |
|
106 // and replace it with "the default" (an empty VecDeque); we can |
|
107 // return it now without taking a mutable borrow of `self`. |
89 mem::take( &mut self.pile ) |
108 mem::take( &mut self.pile ) |
90 // same effect: |
109 |
|
110 // same effect (`drain()` also transfers ownership): |
91 // self.pile.drain(..).collect() |
111 // self.pile.drain(..).collect() |
92 |
112 |
93 // very cumbersome manual fiddling (also reverted...) |
113 // very cumbersome manual fiddling (also in wrong/reverted order...) |
94 /* let mut throw: Vec<Card> = Vec::new(); |
114 /* let mut throw: Vec<Card> = Vec::new(); |
95 for _i in 0 .. self.pile.len() { |
115 for _i in 0 .. self.pile.len() { |
96 throw.push( self.pile.pop().unwrap() ); |
116 throw.push( self.pile.pop().unwrap() ); |
97 } |
117 } |
98 throw |
118 throw |
99 */ |
119 */ |
100 } |
120 } |
101 |
121 |
102 // I can do this just because I *throw away* c! |
122 // I can do this just because I *throw away* c! |
103 // doesn't work if I want to use it. |
123 // Doesn't work if I want to use/return it. |
104 /* fn _gimme_pile(self)->Self { |
124 /* fn _gimme_pile(self)->Self { |
105 for c in &self.pile { |
125 for c in &self.pile { |
106 println!("Throw {} ", c); |
126 println!("Throw {} ", c); |
107 } |
127 } |
108 self |
128 self |
109 } |
129 } |
110 */ |
130 */ |
|
131 /// End of round, "close" the Player and verify that we did all right. |
|
132 /// These ought to be `assert()` calls, but... same thing. |
111 pub(crate) fn close_round( &mut self ) { |
133 pub(crate) fn close_round( &mut self ) { |
112 if self.hand.len() > 0 { |
134 if self.hand.len() > 0 { |
113 panic!("Closing round when {} has {} cards in hand", self.name, self.hand.len()); |
135 panic!("Closing round when {} has {} cards in hand", self.name, self.hand.len()); |
114 } |
136 } |
115 |
137 |
120 trace!("Player {} closing round; points={} total so far {}", self.name, self.game_point, self.total_point); |
142 trace!("Player {} closing round; points={} total so far {}", self.name, self.game_point, self.total_point); |
121 self.total_point += self.game_point; |
143 self.total_point += self.game_point; |
122 self.game_point = 0; |
144 self.game_point = 0; |
123 } |
145 } |
124 |
146 |
125 // card too small: pick a row to collect from the rows |
147 /// Card too small: pick a row to collect from the rows. |
|
148 /// It selects the first row with the lowest `points`. |
|
149 /// |
|
150 /// # Arguments |
|
151 /// * `rows` - A `Vec`tor of [`Row`]s to pick from |
|
152 /// * `playercard` - The actual card the player just thrown, which could be used in decision (but it isn't now) |
126 pub(crate) fn pick_row_for_small_card( &self, rows: &Vec<Row>, playercard: &Card ) -> usize { |
153 pub(crate) fn pick_row_for_small_card( &self, rows: &Vec<Row>, playercard: &Card ) -> usize { |
127 trace!("Player {} picking a row for small card, card {:?}, rows {:?}", self.name, playercard, rows); |
154 trace!("Player {} picking a row for small card, card {:?}, rows {:?}", self.name, playercard, rows); |
128 |
155 |
129 // contains the summary point for each row |
156 // contains the summary point for each row |
130 let mut row_points = Vec::with_capacity(5); |
157 let mut row_points = Vec::with_capacity(5); |
131 // the smallest row score |
158 // the smallest row score (we start by something larger than anything possible) |
132 let mut smallest = 999; |
159 let mut smallest = 999; |
133 // how many rows have the same smallest score |
160 // how many rows have the same smallest score |
134 let mut same_point = 0; |
161 let mut same_point = 0; |
135 // the first smallest row_id |
162 // the first smallest row_id (start by larger than max) |
136 let mut smallest_rowid = 255; |
163 let mut smallest_rowid = 255; |
137 |
164 |
138 for rowid in 0 .. rows.len() { |
165 for rowid in 0 .. rows.len() { |
139 // DEBUG |
166 // debug!("pick_row_for_small_card: rowlen {}, rowid {}", rows.len(), rowid); |
140 // println!("pick_row_for_small_card: rowlen {}, rowid {}", rows.len(), rowid); |
167 // As Row to calculate the summary points for itself and store it in a Vec |
141 row_points.push( rows[rowid].sum() ); |
168 row_points.push( rows[rowid].sum() ); |
142 |
169 |
143 if row_points[rowid] < smallest { |
170 if row_points[rowid] < smallest { |
144 // we have a new smallest row |
171 // we have a new smallest row |
145 smallest = row_points[rowid]; |
172 smallest = row_points[rowid]; |
152 } |
179 } |
153 } |
180 } |
154 |
181 |
155 if same_point < 1 { |
182 if same_point < 1 { |
156 // we have one smallest row |
183 // we have one smallest row |
157 smallest_rowid.try_into().unwrap() // it's tiny, will fit into u8 |
184 smallest_rowid.try_into().unwrap() // it's tiny, will fit into u8, so unwrap() is safe |
158 |
185 |
159 } else { |
186 } else { |
160 // bored, we pick the first now anyway |
187 // bored, we pick the first now anyway; this could be smarter, but possibly |
|
188 // it would require peeking at other rows and the thrown cards of others. |
161 smallest_rowid.try_into().unwrap() |
189 smallest_rowid.try_into().unwrap() |
162 } |
190 } |
163 |
191 |
164 } |
192 } |
165 |
193 |
166 } |
194 } |
167 |
195 |
168 /*** PlayerCard ****/ |
196 /// `PlayerCard` is a [`Card`] associated with a Player. |
169 #[derive(Debug)] |
197 #[derive(Debug)] |
170 pub(crate) struct PlayerCard { |
198 pub(crate) struct PlayerCard { |
171 pub player_id: i32, |
199 pub player_id: i32, |
172 pub card: Card, |
200 pub card: Card, |
173 } |
201 } |
174 |
202 |
175 impl PlayerCard { |
203 impl PlayerCard { |
|
204 /// It isn't used because I was tired fighting with the borrow checker ;-) |
176 fn _get_player(&self) -> i32 { |
205 fn _get_player(&self) -> i32 { |
177 self.player_id |
206 self.player_id |
178 } |
207 } |
179 } |
208 } |
180 |
209 |
|
210 /// We use this to sort the [`Card`]s, using its own knowledge about equality. |
181 impl PartialEq for PlayerCard { |
211 impl PartialEq for PlayerCard { |
182 fn eq(&self, other: &Self) -> bool { |
212 fn eq(&self, other: &Self) -> bool { |
183 self.card == other.card |
213 self.card == other.card |
184 } |
214 } |
185 } |
215 } |
186 |
216 |
|
217 /// We use this to sort the [`Card`]s, using its own knowledge about ordering. |
187 impl PartialOrd for PlayerCard { |
218 impl PartialOrd for PlayerCard { |
188 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { |
219 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { |
189 match self.card.partial_cmp(&other.card) { |
220 match self.card.partial_cmp(&other.card) { |
190 Some(core::cmp::Ordering::Equal) => {None} |
221 Some(core::cmp::Ordering::Equal) => {None} |
191 ord => return ord, |
222 ord => return ord, |