--- 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<Card> ) {
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<Card> {
trace!("Player {} gives back their pile", self.name);
+ // Here we take the ownership of the `pile` VecDeque<Card> 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<Card> = Vec::new();
+ // very cumbersome manual fiddling (also in wrong/reverted order...)
+/* let mut throw: Vec<Card> = 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<Row>, 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<std::cmp::Ordering> {
match self.card.partial_cmp(&other.card) {