src/player.rs
changeset 4 a2f0cb2b5c13
child 5 0dd7f2c9fd81
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/player.rs	Tue Jan 31 23:25:50 2023 +0100
@@ -0,0 +1,196 @@
+/*** Player ****/
+
+use std::collections::VecDeque;
+use std::mem;
+
+use crate::deck::*;
+use crate::card::*;
+use crate::row::*;
+
+#[derive(Debug)]
+pub(crate) struct Player {
+    name: String,
+    hand: Deck,
+    pile: VecDeque<Card>,
+    game_point: i32,
+    total_point: i32,
+    rows_busted: i32,
+    wins: i32,
+}
+
+impl Player {
+    pub(crate) fn new(name: String)->Self {
+        debug!("Player {} created", name);
+        Player {
+            name,
+            hand: Deck::new_empty(),
+            pile: VecDeque::new(),
+            game_point: 0,
+            total_point: 0,
+            rows_busted: 0,
+            wins: 0,
+        }
+    }
+
+    // get one card from th 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
+    pub(crate) fn throw_card( &mut self )->Card {
+        if let Some(c) = self.hand.pop() {
+            trace!("Player {} throws a card {:?}", self.name, &c);
+            c
+        } else {
+            panic!("throw_card: Player {} has no card in hand!", self.name);
+        }
+    }
+
+    // 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;
+            self.pile.push_back(c);
+        }
+        self.rows_busted += 1;
+        trace!("Player {} got busted, count {}", self.name, &self.rows_busted);
+    }
+
+    pub fn get_name(&self) -> &String {
+        &self.name
+    }
+
+    // ask the player their score
+    pub(crate) fn get_points( &self ) -> i32 {
+        self.game_point
+    }
+
+    pub fn get_wins(&self) -> i32 {
+        self.wins
+    }
+
+    pub(crate) fn inc_wins( &mut self ) {
+        self.wins += 1;
+    }
+
+    pub fn get_total_points(&self) -> i32 {
+        self.total_point
+    }
+
+    pub fn get_rows_busted(&self) -> i32 {
+        self.rows_busted
+    }
+
+    // give back cards from the pile
+    pub(crate) fn get_pile( &mut self ) -> VecDeque<Card> {
+        trace!("Player {} gives back their pile", self.name);
+        mem::take( &mut self.pile )
+        // same effect:
+        // self.pile.drain(..).collect()
+
+        // very cumbersome manual fiddling (also reverted...)
+/*         let mut throw: Vec<Card> = Vec::new();
+        for _i in 0 .. self.pile.len() {
+            throw.push( self.pile.pop().unwrap() );
+        }
+        throw
+ */    
+    }
+
+    // I can do this just because I *throw away* c!
+    // doesn't work if I want to use it.
+/*     fn _gimme_pile(self)->Self {
+        for c in &self.pile {
+            println!("Throw {} ", c);
+        }
+        self
+    }
+ */
+    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());
+        }
+
+        if self.pile.len() > 0 {
+            panic!("Closing round when {} stil have pile with {} cards", self.name, self.pile.len());
+        }
+
+        trace!("Player {} closing round; points={} total so far {}", self.name, self.game_point, self.total_point);
+        self.total_point += self.game_point;
+        self.game_point = 0;
+    }
+
+    // card too small: pick a row to collect from the rows
+    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
+        let mut smallest = 999;
+        // how many rows have the same smallest score
+        let mut same_point = 0;
+        // the first smallest row_id
+        let mut smallest_rowid = 255;
+
+        for rowid in 0 .. rows.len() {
+            // DEBUG
+            // println!("pick_row_for_small_card: rowlen {}, rowid {}", rows.len(), rowid);
+            row_points.push( rows[rowid].sum() );
+
+            if row_points[rowid] < smallest {
+                // we have a new smallest row
+                smallest = row_points[rowid];
+                same_point = 0;
+                smallest_rowid = rowid;
+            
+            } else if row_points[rowid] == smallest {
+                // we have another row with same point as smallest
+                same_point += 1;
+            }
+        }
+
+        if same_point < 1 {
+            // we have one smallest row
+            smallest_rowid.try_into().unwrap()      // it's tiny, will fit into u8
+        
+        } else {
+            // bored, we pick the first now anyway
+            smallest_rowid.try_into().unwrap()
+        }
+        
+    }
+
+}
+
+/*** PlayerCard ****/
+#[derive(Debug)]
+pub(crate) struct PlayerCard {
+    pub player_id: i32,
+    pub card: Card,
+}
+
+impl PlayerCard {
+    fn _get_player(&self) -> i32 {
+        self.player_id
+    }
+}
+
+impl PartialEq for PlayerCard {
+    fn eq(&self, other: &Self) -> bool {
+        self.card == other.card
+    }
+}
+
+impl PartialOrd for PlayerCard {
+    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
+        match self.card.partial_cmp(&other.card) {
+            Some(core::cmp::Ordering::Equal) => {None}
+            ord => return ord,
+        }
+    }
+}
+
+