diff -r a2f0cb2b5c13 -r 0dd7f2c9fd81 src/player.rs --- a/src/player.rs Tue Jan 31 23:25:50 2023 +0100 +++ b/src/player.rs Sat Feb 04 22:46:13 2023 +0100 @@ -1,6 +1,7 @@ -/*** Player ****/ +/// This is the implementation of a Player. use std::collections::VecDeque; +// We use this to move variables out of a Vec with ownership. use std::mem; use crate::deck::*; @@ -8,6 +9,15 @@ use crate::row::*; #[derive(Debug)] +/// A `Player` is a person in the game. +/// # Structure members +/// * `name` - the name of the Player +/// * `hand` - the cards in the hand of Player, stored as a [`Deck`], so, for example, it could be shuffled or sorted. +/// * `pile` - the pile of busted [`Row`] [`Card`]s, counted at the end of the round. +/// * `game_point` - points in the current game round +/// * `total_point` - points in all the games total +/// * `rows_busted` - just counting how many rows the player have collected +/// * `wins` - how many games have the Player won pub(crate) struct Player { name: String, hand: Deck, @@ -19,6 +29,7 @@ } impl Player { + /// Creates a new [`Player`] with a given `name`. pub(crate) fn new(name: String)->Self { debug!("Player {} created", name); Player { @@ -32,13 +43,13 @@ } } - // get one card from th dealer + /// get one card from the dealer pub(crate) fn get_card( &mut self, card: Card ) { trace!("Player {} got a card {:?}, cards before {}", self.name, &card, self.hand.len()); self.hand.push(card); } - // throw a card from hand to the table + /// throw a card from hand to the table pub(crate) fn throw_card( &mut self )->Card { if let Some(c) = self.hand.pop() { trace!("Player {} throws a card {:?}", self.name, &c); @@ -48,7 +59,7 @@ } } - // get a busted row of cards + /// get a busted row of cards pub(crate) fn give_pile( &mut self, cards: VecDeque ) { for c in cards.into_iter() { self.game_point += c.points as i32; @@ -58,40 +69,49 @@ trace!("Player {} got busted, count {}", self.name, &self.rows_busted); } + /// Get the name of the Player pub fn get_name(&self) -> &String { &self.name } - // ask the player their score + /// ask the player their score pub(crate) fn get_points( &self ) -> i32 { self.game_point } + /// Get the number of games won pub fn get_wins(&self) -> i32 { self.wins } + /// Player won this game, increment counter pub(crate) fn inc_wins( &mut self ) { self.wins += 1; } + /// Get total points of all games pub fn get_total_points(&self) -> i32 { self.total_point } + /// Get the number of total busted rows pub fn get_rows_busted(&self) -> i32 { self.rows_busted } - // give back cards from the pile + /// give back cards from the player's pile ino the Deck pub(crate) fn get_pile( &mut self ) -> VecDeque { trace!("Player {} gives back their pile", self.name); + // Here we take the ownership of the `pile` VecDeque structure, + // and replace it with "the default" (an empty VecDeque); we can + // return it now without taking a mutable borrow of `self`. mem::take( &mut self.pile ) - // same effect: + + // same effect (`drain()` also transfers ownership): // self.pile.drain(..).collect() - // very cumbersome manual fiddling (also reverted...) -/* let mut throw: Vec = Vec::new(); + // very cumbersome manual fiddling (also in wrong/reverted order...) +/* let mut throw: Vec = Vec::new(); for _i in 0 .. self.pile.len() { throw.push( self.pile.pop().unwrap() ); } @@ -100,7 +120,7 @@ } // I can do this just because I *throw away* c! - // doesn't work if I want to use it. + // Doesn't work if I want to use/return it. /* fn _gimme_pile(self)->Self { for c in &self.pile { println!("Throw {} ", c); @@ -108,6 +128,8 @@ self } */ + /// End of round, "close" the Player and verify that we did all right. + /// These ought to be `assert()` calls, but... same thing. pub(crate) fn close_round( &mut self ) { if self.hand.len() > 0 { panic!("Closing round when {} has {} cards in hand", self.name, self.hand.len()); @@ -122,22 +144,27 @@ self.game_point = 0; } - // card too small: pick a row to collect from the rows + /// Card too small: pick a row to collect from the rows. + /// It selects the first row with the lowest `points`. + /// + /// # Arguments + /// * `rows` - A `Vec`tor of [`Row`]s to pick from + /// * `playercard` - The actual card the player just thrown, which could be used in decision (but it isn't now) pub(crate) fn pick_row_for_small_card( &self, rows: &Vec, playercard: &Card ) -> usize { trace!("Player {} picking a row for small card, card {:?}, rows {:?}", self.name, playercard, rows); // contains the summary point for each row let mut row_points = Vec::with_capacity(5); - // the smallest row score + // the smallest row score (we start by something larger than anything possible) let mut smallest = 999; // how many rows have the same smallest score let mut same_point = 0; - // the first smallest row_id + // the first smallest row_id (start by larger than max) let mut smallest_rowid = 255; for rowid in 0 .. rows.len() { - // DEBUG - // println!("pick_row_for_small_card: rowlen {}, rowid {}", rows.len(), rowid); + // debug!("pick_row_for_small_card: rowlen {}, rowid {}", rows.len(), rowid); + // As Row to calculate the summary points for itself and store it in a Vec row_points.push( rows[rowid].sum() ); if row_points[rowid] < smallest { @@ -154,10 +181,11 @@ if same_point < 1 { // we have one smallest row - smallest_rowid.try_into().unwrap() // it's tiny, will fit into u8 + smallest_rowid.try_into().unwrap() // it's tiny, will fit into u8, so unwrap() is safe } else { - // bored, we pick the first now anyway + // bored, we pick the first now anyway; this could be smarter, but possibly + // it would require peeking at other rows and the thrown cards of others. smallest_rowid.try_into().unwrap() } @@ -165,7 +193,7 @@ } -/*** PlayerCard ****/ +/// `PlayerCard` is a [`Card`] associated with a Player. #[derive(Debug)] pub(crate) struct PlayerCard { pub player_id: i32, @@ -173,17 +201,20 @@ } impl PlayerCard { + /// It isn't used because I was tired fighting with the borrow checker ;-) fn _get_player(&self) -> i32 { self.player_id } } +/// We use this to sort the [`Card`]s, using its own knowledge about equality. impl PartialEq for PlayerCard { fn eq(&self, other: &Self) -> bool { self.card == other.card } } +/// We use this to sort the [`Card`]s, using its own knowledge about ordering. impl PartialOrd for PlayerCard { fn partial_cmp(&self, other: &Self) -> Option { match self.card.partial_cmp(&other.card) {