--- /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,
+ }
+ }
+}
+
+