src/player.rs
changeset 4 a2f0cb2b5c13
child 5 0dd7f2c9fd81
equal deleted inserted replaced
3:3d9dba5b16e0 4:a2f0cb2b5c13
       
     1 /*** Player ****/
       
     2 
       
     3 use std::collections::VecDeque;
       
     4 use std::mem;
       
     5 
       
     6 use crate::deck::*;
       
     7 use crate::card::*;
       
     8 use crate::row::*;
       
     9 
       
    10 #[derive(Debug)]
       
    11 pub(crate) struct Player {
       
    12     name: String,
       
    13     hand: Deck,
       
    14     pile: VecDeque<Card>,
       
    15     game_point: i32,
       
    16     total_point: i32,
       
    17     rows_busted: i32,
       
    18     wins: i32,
       
    19 }
       
    20 
       
    21 impl Player {
       
    22     pub(crate) fn new(name: String)->Self {
       
    23         debug!("Player {} created", name);
       
    24         Player {
       
    25             name,
       
    26             hand: Deck::new_empty(),
       
    27             pile: VecDeque::new(),
       
    28             game_point: 0,
       
    29             total_point: 0,
       
    30             rows_busted: 0,
       
    31             wins: 0,
       
    32         }
       
    33     }
       
    34 
       
    35     // get one card from th dealer
       
    36     pub(crate) fn get_card( &mut self, card: Card ) {
       
    37         trace!("Player {} got a card {:?}, cards before {}", self.name, &card, self.hand.len());
       
    38         self.hand.push(card);
       
    39     }
       
    40 
       
    41     // throw a card from hand to the table
       
    42     pub(crate) fn throw_card( &mut self )->Card {
       
    43         if let Some(c) = self.hand.pop() {
       
    44             trace!("Player {} throws a card {:?}", self.name, &c);
       
    45             c
       
    46         } else {
       
    47             panic!("throw_card: Player {} has no card in hand!", self.name);
       
    48         }
       
    49     }
       
    50 
       
    51     // get a busted row of cards
       
    52     pub(crate) fn give_pile( &mut self, cards: VecDeque<Card> ) {
       
    53         for c in cards.into_iter() {
       
    54             self.game_point += c.points as i32;
       
    55             self.pile.push_back(c);
       
    56         }
       
    57         self.rows_busted += 1;
       
    58         trace!("Player {} got busted, count {}", self.name, &self.rows_busted);
       
    59     }
       
    60 
       
    61     pub fn get_name(&self) -> &String {
       
    62         &self.name
       
    63     }
       
    64 
       
    65     // ask the player their score
       
    66     pub(crate) fn get_points( &self ) -> i32 {
       
    67         self.game_point
       
    68     }
       
    69 
       
    70     pub fn get_wins(&self) -> i32 {
       
    71         self.wins
       
    72     }
       
    73 
       
    74     pub(crate) fn inc_wins( &mut self ) {
       
    75         self.wins += 1;
       
    76     }
       
    77 
       
    78     pub fn get_total_points(&self) -> i32 {
       
    79         self.total_point
       
    80     }
       
    81 
       
    82     pub fn get_rows_busted(&self) -> i32 {
       
    83         self.rows_busted
       
    84     }
       
    85 
       
    86     // give back cards from the pile
       
    87     pub(crate) fn get_pile( &mut self ) -> VecDeque<Card> {
       
    88         trace!("Player {} gives back their pile", self.name);
       
    89         mem::take( &mut self.pile )
       
    90         // same effect:
       
    91         // self.pile.drain(..).collect()
       
    92 
       
    93         // very cumbersome manual fiddling (also reverted...)
       
    94 /*         let mut throw: Vec<Card> = Vec::new();
       
    95         for _i in 0 .. self.pile.len() {
       
    96             throw.push( self.pile.pop().unwrap() );
       
    97         }
       
    98         throw
       
    99  */    
       
   100     }
       
   101 
       
   102     // I can do this just because I *throw away* c!
       
   103     // doesn't work if I want to use it.
       
   104 /*     fn _gimme_pile(self)->Self {
       
   105         for c in &self.pile {
       
   106             println!("Throw {} ", c);
       
   107         }
       
   108         self
       
   109     }
       
   110  */
       
   111     pub(crate) fn close_round( &mut self ) {
       
   112         if self.hand.len() > 0 {
       
   113             panic!("Closing round when {} has {} cards in hand", self.name, self.hand.len());
       
   114         }
       
   115 
       
   116         if self.pile.len() > 0 {
       
   117             panic!("Closing round when {} stil have pile with {} cards", self.name, self.pile.len());
       
   118         }
       
   119 
       
   120         trace!("Player {} closing round; points={} total so far {}", self.name, self.game_point, self.total_point);
       
   121         self.total_point += self.game_point;
       
   122         self.game_point = 0;
       
   123     }
       
   124 
       
   125     // card too small: pick a row to collect from the rows
       
   126     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);
       
   128 
       
   129         // contains the summary point for each row
       
   130         let mut row_points = Vec::with_capacity(5);
       
   131         // the smallest row score
       
   132         let mut smallest = 999;
       
   133         // how many rows have the same smallest score
       
   134         let mut same_point = 0;
       
   135         // the first smallest row_id
       
   136         let mut smallest_rowid = 255;
       
   137 
       
   138         for rowid in 0 .. rows.len() {
       
   139             // DEBUG
       
   140             // println!("pick_row_for_small_card: rowlen {}, rowid {}", rows.len(), rowid);
       
   141             row_points.push( rows[rowid].sum() );
       
   142 
       
   143             if row_points[rowid] < smallest {
       
   144                 // we have a new smallest row
       
   145                 smallest = row_points[rowid];
       
   146                 same_point = 0;
       
   147                 smallest_rowid = rowid;
       
   148             
       
   149             } else if row_points[rowid] == smallest {
       
   150                 // we have another row with same point as smallest
       
   151                 same_point += 1;
       
   152             }
       
   153         }
       
   154 
       
   155         if same_point < 1 {
       
   156             // we have one smallest row
       
   157             smallest_rowid.try_into().unwrap()      // it's tiny, will fit into u8
       
   158         
       
   159         } else {
       
   160             // bored, we pick the first now anyway
       
   161             smallest_rowid.try_into().unwrap()
       
   162         }
       
   163         
       
   164     }
       
   165 
       
   166 }
       
   167 
       
   168 /*** PlayerCard ****/
       
   169 #[derive(Debug)]
       
   170 pub(crate) struct PlayerCard {
       
   171     pub player_id: i32,
       
   172     pub card: Card,
       
   173 }
       
   174 
       
   175 impl PlayerCard {
       
   176     fn _get_player(&self) -> i32 {
       
   177         self.player_id
       
   178     }
       
   179 }
       
   180 
       
   181 impl PartialEq for PlayerCard {
       
   182     fn eq(&self, other: &Self) -> bool {
       
   183         self.card == other.card
       
   184     }
       
   185 }
       
   186 
       
   187 impl PartialOrd for PlayerCard {
       
   188     fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
       
   189         match self.card.partial_cmp(&other.card) {
       
   190             Some(core::cmp::Ordering::Equal) => {None}
       
   191             ord => return ord,
       
   192         }
       
   193     }
       
   194 }
       
   195 
       
   196