src/player.rs
changeset 5 0dd7f2c9fd81
parent 4 a2f0cb2b5c13
equal deleted inserted replaced
4:a2f0cb2b5c13 5:0dd7f2c9fd81
     1 /*** Player ****/
     1 /// This is the implementation of a Player.
     2 
     2 
     3 use std::collections::VecDeque;
     3 use std::collections::VecDeque;
       
     4 // We use this to move variables out of a Vec with ownership.
     4 use std::mem;
     5 use std::mem;
     5 
     6 
     6 use crate::deck::*;
     7 use crate::deck::*;
     7 use crate::card::*;
     8 use crate::card::*;
     8 use crate::row::*;
     9 use crate::row::*;
     9 
    10 
    10 #[derive(Debug)]
    11 #[derive(Debug)]
       
    12 /// A `Player` is a person in the game.
       
    13 /// # Structure members
       
    14 /// * `name` - the name of the Player
       
    15 /// * `hand` - the cards in the hand of Player, stored as a [`Deck`], so, for example, it could be shuffled or sorted.
       
    16 /// * `pile` - the pile of busted [`Row`] [`Card`]s, counted at the end of the round.
       
    17 /// * `game_point` - points in the current game round
       
    18 /// * `total_point` - points in all the games total
       
    19 /// * `rows_busted` - just counting how many rows the player have collected
       
    20 /// * `wins` - how many games have the Player won
    11 pub(crate) struct Player {
    21 pub(crate) struct Player {
    12     name: String,
    22     name: String,
    13     hand: Deck,
    23     hand: Deck,
    14     pile: VecDeque<Card>,
    24     pile: VecDeque<Card>,
    15     game_point: i32,
    25     game_point: i32,
    17     rows_busted: i32,
    27     rows_busted: i32,
    18     wins: i32,
    28     wins: i32,
    19 }
    29 }
    20 
    30 
    21 impl Player {
    31 impl Player {
       
    32     /// Creates a new [`Player`] with a given `name`.
    22     pub(crate) fn new(name: String)->Self {
    33     pub(crate) fn new(name: String)->Self {
    23         debug!("Player {} created", name);
    34         debug!("Player {} created", name);
    24         Player {
    35         Player {
    25             name,
    36             name,
    26             hand: Deck::new_empty(),
    37             hand: Deck::new_empty(),
    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,