diff -r a2f0cb2b5c13 -r 0dd7f2c9fd81 src/table.rs --- a/src/table.rs Tue Jan 31 23:25:50 2023 +0100 +++ b/src/table.rs Sat Feb 04 22:46:13 2023 +0100 @@ -1,4 +1,4 @@ -/*** Table ****/ +/// Implemantation of the playing Table. use std::collections::VecDeque; @@ -7,67 +7,94 @@ use crate::player::PlayerCard; #[derive(Debug)] +/// A playing Table, containing 5 [`Row`]s and some [`PlayerCard`]s. +/// A Table can do some useful function with its cards, like picking +/// closest row or moving cards. pub(crate) struct Table { rows: Vec, player_cards: VecDeque, // owned by a player } impl Table { + /// Creates a new `Table`, filling Rows from `row_cards`. pub(crate) fn new(row_cards: VecDeque) -> Self { + // We have exactly 5 Rows. let mut rows = Vec::with_capacity(5); for card in row_cards { // create a new row then put a card into it let mut row = Row::new(); - if let Some(_c) = row.push_or_collect(card) { + if let Some(_) = row.push_or_collect(card) { + // Row should have one card, so... mustn't happen. panic!("Freshly created row overflowed"); } + // Put the new row onto the Table. rows.push( row ); } + // And return the newly created Table. Table { rows, player_cards: VecDeque::new(), } } + /// Gets a [`Card`] from a [`Player`] and put it into the `player_cards` area, + /// remembering whose (`player_id`) card it was. pub(crate) fn lay_player_card( &mut self, card: Card, player_id: i32 ) { self.player_cards.push_back( PlayerCard { player_id, card } ); } + /// Sort the [`Card`]s thrown by the [`Player`]s, since we'd need + /// to get them ordered by value later. pub(crate) fn sort_cards( &mut self ) { + // Sorting a normal VecDeque is not possible since it may contain + // holes, so we need to de-hole it first, then it's sortable (through + // a returned pointer slice). self.player_cards.make_contiguous().sort_by( |a,b| b.card.cmp(&a.card) ); } + /// Returns true if we have unprocessed Player cards on the table. pub(crate) fn has_player_cards( &self ) -> bool { self.player_cards.len() > 0 } + /// Return the smallest player card on the table. + /// FIXME: shall check whether it's ordered. pub(crate) fn get_smallest_player_card( &mut self ) -> PlayerCard { - // FIXME: check! + // FIXME: check orderedness! + // FIXME: check asking when empty! self.player_cards.pop_back().expect("out of player cards on table") } + /// Return the row which is closest to the `pcard` arg, or None if + /// all Row tails are larger. pub(crate) fn get_closest_row( &self, pcard: &PlayerCard ) -> Option { // get the row id with last card closest smaller to players' - let row_heads = self.get_row_heads(); + let row_tails = self.get_row_tails(); let mut closest_val = None; - let mut diff = 127; - for i in 0..row_heads.len() { - if row_heads[i] < pcard.card.value && pcard.card.value - row_heads[i] < diff { - closest_val = Some(i); - diff = pcard.card.value - row_heads[i]; - // println!("DEBUG: pcard {}, row {}, head {}, diff {}, closest {:?}", pcard.card.value, i, row_heads[i], diff, closest_val); + let mut diff = 127; // larger than any + // Check all the row tail cards + for i in 0..row_tails.len() { + if row_tails[i] < pcard.card.value && pcard.card.value - row_tails[i] < diff { + // it is smaller than pcard and closer than the old closest one: match! + // Store the row index + closest_val = Some(i); + diff = pcard.card.value - row_tails[i]; + // debug!("DEBUG: pcard {}, row {}, head {}, diff {}, closest {:?}", pcard.card.value, i, row_heads[i], diff, closest_val); } } closest_val } + /// Put a [`Card`] into the `row_id` Row (tail). + /// Returns `None` if ok or `Some(cards)` when the Row is full. pub(crate) fn put_card_into_row( &mut self, pcard: PlayerCard, row_id: usize ) -> Option> { - self.rows[row_id as usize].push_or_collect(pcard.card) + // We actually ask the Row to do it properly. + self.rows[row_id].push_or_collect(pcard.card) } - pub(crate) fn get_row_heads( &self ) -> Vec { + pub(crate) fn get_row_tails( &self ) -> Vec { let mut heads: Vec = Vec::new(); for i in 0..self.rows.len() { heads.push( self.rows[i].last_card_value() ); @@ -92,6 +119,7 @@ cards } + /// Return a non-mutable borrow of the rows to look at pub fn peek_rows(&self) -> &Vec { &self.rows }