src/main.rs
changeset 4 a2f0cb2b5c13
parent 3 3d9dba5b16e0
child 5 0dd7f2c9fd81
equal deleted inserted replaced
3:3d9dba5b16e0 4:a2f0cb2b5c13
     1 // #[allow(dead_code, unused)]
     1 // #[allow(dead_code, unused)]
     2 // vigyazz6! autplayer
     2 // vigyazz6! autplayer
     3 //
     3 //
     4 
     4 
     5 use core::{fmt, panic};
     5 use core::panic;
     6 use std::{collections::VecDeque, time::Instant, cmp::Reverse};
     6 use std::{collections::VecDeque, time::Instant, cmp::Reverse};
     7 use rand::Rng;
     7 
     8 use std::mem;
     8 use crate::{deck::Deck, player::Player, table::Table};
       
     9 // use rand::Rng;
       
    10 // use std::mem;
       
    11 
       
    12 mod deck;
       
    13 mod table;
       
    14 mod player;
       
    15 mod card;
       
    16 mod row;
     9 
    17 
    10 extern crate pretty_env_logger;
    18 extern crate pretty_env_logger;
    11 #[macro_use] extern crate log;
    19 #[macro_use] extern crate log;
    12 
    20 
    13 const GAME_ROUNDS: i32 = 1_000_000;
    21 const GAME_ROUNDS: i32 = 100_000;
    14 
    22 
    15 fn main() {
    23 fn main() {
    16     // RUST_LOG=debug cargo run
    24     // RUST_LOG=debug cargo run
    17     pretty_env_logger::init();
    25     pretty_env_logger::init();
    18     info!("Program starting.");
    26     info!("Program starting.");
    19     game();
    27     game();
    20     info!("End of run.");
    28     info!("End of run.");
    21 }
    29 }
    22 
    30 
    23 /*** Card ****/
    31 // Card
    24 #[derive(Debug)]
    32 // Deck
    25 struct Card {
    33 // Player
    26     value: i8,
    34 // Row
    27     points: i8,
    35 
    28 }
       
    29 
       
    30 impl Card {
       
    31     fn new(value: i8)->Self {
       
    32 
       
    33         let mut points = 0;
       
    34         if value % 10 == 5 {
       
    35             // ends with 5 = 2 point
       
    36             points = 2;
       
    37             // println!("*5 add 1, val={}, pt={}", value, points);
       
    38         }
       
    39 
       
    40         if value % 10 == 0 {
       
    41             // ends with 0 = 3 point
       
    42             points = 3;
       
    43             // println!("*0 add 2, val={}, pt={}", value, points);
       
    44         }
       
    45 
       
    46         if value % 10 == value / 10 {
       
    47             // same numbers = 5 points (55=7)
       
    48             points += 5;
       
    49             // println!("NN add 5, val={}, pt={}", value, points);
       
    50         }
       
    51 
       
    52         if points == 0 {
       
    53             points = 1;
       
    54         }
       
    55 
       
    56         Card {
       
    57             value,
       
    58             points,
       
    59         }
       
    60     }
       
    61 }
       
    62 
       
    63 impl fmt::Display for Card {
       
    64     fn fmt( &self, f: &mut fmt::Formatter ) -> fmt::Result {
       
    65         write!(f, "(Card {}, points {})", self.value, self.points)
       
    66     }
       
    67 }
       
    68 
       
    69 impl PartialEq for Card {
       
    70     fn eq(&self, other: &Self) -> bool {
       
    71         self.value == other.value
       
    72     }
       
    73 }
       
    74 
       
    75 impl Eq for Card {} 
       
    76 
       
    77 impl PartialOrd for Card {
       
    78     fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
       
    79         match self.value.partial_cmp(&other.value) {
       
    80             Some(core::cmp::Ordering::Equal) => {None}
       
    81             ord => return ord,
       
    82         }
       
    83     }
       
    84 }
       
    85 
       
    86 impl Ord for Card {
       
    87     fn cmp(&self, other: &Self) -> std::cmp::Ordering {
       
    88         self.value.cmp(&other.value)
       
    89     }
       
    90 }
       
    91 
       
    92 /*** Deck ****/
       
    93 #[derive(Debug)]
       
    94 struct Deck {
       
    95     content: VecDeque<Card>,
       
    96 }
       
    97 
       
    98 impl Deck {
       
    99     fn new_empty() -> Self {
       
   100         debug!("Empty deck generated");
       
   101         Deck {
       
   102             content: VecDeque::new(),
       
   103         }
       
   104     }
       
   105 
       
   106     fn new() -> Self {
       
   107         debug!("Full deck generated");
       
   108         let content = (1..=104).into_iter().map( |n| Card::new(n) ).collect();
       
   109         Deck {
       
   110             content,
       
   111         }
       
   112     }
       
   113 
       
   114     fn shuffle( &mut self ) {
       
   115         let mut rng = rand::thread_rng();
       
   116         
       
   117         trace!("Deck before shuffle: len {}, {:?}", self.content.len(), self);
       
   118         debug!("Deck shuffled");
       
   119         // shufflers:
       
   120         // * naive: swap cards n times
       
   121         // * kgb: half the deck, take 1..4 cards sequentially from each
       
   122         // * grin: take 1..6 from front and put at bottom
       
   123 
       
   124         // naive shuffle: exchange random cards
       
   125         for _i in 1..=500 {
       
   126             let c1 = rng.gen_range(0 .. self.content.len());
       
   127             let c2 = rng.gen_range(0 .. self.content.len());
       
   128             if c1 != c2 {
       
   129                 self.content.swap(c1, c2);
       
   130             }
       
   131         }
       
   132         trace!("Deck after shuffle: len {}, {:?}", self.content.len(), self);
       
   133     }
       
   134 
       
   135     // get top card from deck
       
   136     fn pop( &mut self ) -> Option<Card> {
       
   137         self.content.pop_front() 
       
   138     }
       
   139 
       
   140     // put a card into the bottom of the deck
       
   141     fn push( &mut self, c: Card ) {
       
   142         self.content.push_back(c);
       
   143     }
       
   144 
       
   145     fn push_cards( &mut self, cards: VecDeque<Card> ) {
       
   146         trace!("Collecting back, deck len is {}, cards {}", self.content.len(), cards.len());
       
   147         cards.into_iter().for_each( |card| self.push(card) );
       
   148         trace!("Deck len is {}", self.content.len());
       
   149     }
       
   150 
       
   151     fn len( &self ) -> usize {
       
   152         self.content.len()
       
   153     }
       
   154 
       
   155     fn _get_nth( &mut self, n: usize ) -> Card {
       
   156         if let Some(c) = self.content.remove(n) {
       
   157             c
       
   158         } else {
       
   159             panic!("get_nth: index {} out of bounds ({})!", n, self.content.len());
       
   160         }
       
   161     }
       
   162 }
       
   163 
       
   164 /*** Player ****/
       
   165 #[derive(Debug)]
       
   166 struct Player {
       
   167     name: String,
       
   168     hand: Deck,
       
   169     pile: VecDeque<Card>,
       
   170     game_point: i32,
       
   171     total_point: i32,
       
   172     rows_busted: i32,
       
   173     wins: i32,
       
   174 }
       
   175 
       
   176 impl Player {
       
   177     fn new(name: String)->Self {
       
   178         debug!("Player {} created", name);
       
   179         Player {
       
   180             name,
       
   181             hand: Deck::new_empty(),
       
   182             pile: VecDeque::new(),
       
   183             game_point: 0,
       
   184             total_point: 0,
       
   185             rows_busted: 0,
       
   186             wins: 0,
       
   187         }
       
   188     }
       
   189 
       
   190     // get one card from th dealer
       
   191     fn get_card( &mut self, card: Card ) {
       
   192         trace!("Player {} got a card {:?}, cards before {}", self.name, &card, self.hand.len());
       
   193         self.hand.push(card);
       
   194     }
       
   195 
       
   196     // throw a card from hand to the table
       
   197     fn throw_card( &mut self )->Card {
       
   198         if let Some(c) = self.hand.pop() {
       
   199             trace!("Player {} throws a card {:?}", self.name, &c);
       
   200             c
       
   201         } else {
       
   202             panic!("throw_card: Player {} has no card in hand!", self.name);
       
   203         }
       
   204     }
       
   205 
       
   206     // get a busted row of cards
       
   207     fn give_pile( &mut self, cards: VecDeque<Card> ) {
       
   208         for c in cards.into_iter() {
       
   209             self.game_point += c.points as i32;
       
   210             self.pile.push_back(c);
       
   211         }
       
   212         self.rows_busted += 1;
       
   213         trace!("Player {} got busted, count {}", self.name, &self.rows_busted);
       
   214     }
       
   215 
       
   216     // ask the player their score
       
   217     fn _tell_points( self ) -> i32 {
       
   218         self.game_point
       
   219     }
       
   220 
       
   221     fn inc_wins( &mut self ) {
       
   222         self.wins += 1;
       
   223     }
       
   224 
       
   225     // give back cards from the pile
       
   226     fn get_pile( &mut self ) -> VecDeque<Card> {
       
   227         trace!("Player {} gives back their pile", self.name);
       
   228         mem::take( &mut self.pile )
       
   229         // same effect:
       
   230         // self.pile.drain(..).collect()
       
   231 
       
   232         // very cumbersome manual fiddling (also reverted...)
       
   233 /*         let mut throw: Vec<Card> = Vec::new();
       
   234         for _i in 0 .. self.pile.len() {
       
   235             throw.push( self.pile.pop().unwrap() );
       
   236         }
       
   237         throw
       
   238  */    
       
   239     }
       
   240 
       
   241     // I can do this just because I *throw away* c!
       
   242     // doesn't work if I want to use it.
       
   243 /*     fn _gimme_pile(self)->Self {
       
   244         for c in &self.pile {
       
   245             println!("Throw {} ", c);
       
   246         }
       
   247         self
       
   248     }
       
   249  */
       
   250     fn close_round( &mut self ) {
       
   251         if self.hand.len() > 0 {
       
   252             panic!("Closing round when {} has {} cards in hand", self.name, self.hand.len());
       
   253         }
       
   254 
       
   255         if self.pile.len() > 0 {
       
   256             panic!("Closing round when {} stil have pile with {} cards", self.name, self.pile.len());
       
   257         }
       
   258 
       
   259         trace!("Player {} closing round; points={} total so far {}", self.name, self.game_point, self.total_point);
       
   260         self.total_point += self.game_point;
       
   261         self.game_point = 0;
       
   262     }
       
   263 
       
   264     // card too small: pick a row to collect from the rows
       
   265     fn pick_row_for_small_card( &self, rows: &Vec<Row>, playercard: &Card ) -> usize {
       
   266         trace!("Player {} picking a row for small card, card {:?}, rows {:?}", self.name, playercard, rows);
       
   267 
       
   268         // contains the summary point for each row
       
   269         let mut row_points = Vec::with_capacity(5);
       
   270         // the smallest row score
       
   271         let mut smallest = 999;
       
   272         // how many rows have the same smallest score
       
   273         let mut same_point = 0;
       
   274         // the first smallest row_id
       
   275         let mut smallest_rowid = 255;
       
   276 
       
   277         for rowid in 0 .. rows.len() {
       
   278             // DEBUG
       
   279             // println!("pick_row_for_small_card: rowlen {}, rowid {}", rows.len(), rowid);
       
   280             row_points.push( rows[rowid].sum() );
       
   281 
       
   282             if row_points[rowid] < smallest {
       
   283                 // we have a new smallest row
       
   284                 smallest = row_points[rowid];
       
   285                 same_point = 0;
       
   286                 smallest_rowid = rowid;
       
   287             
       
   288             } else if row_points[rowid] == smallest {
       
   289                 // we have another row with same point as smallest
       
   290                 same_point += 1;
       
   291             }
       
   292         }
       
   293 
       
   294         if same_point < 1 {
       
   295             // we have one smallest row
       
   296             smallest_rowid.try_into().unwrap()      // it's tiny, will fit into u8
       
   297         
       
   298         } else {
       
   299             // bored, we pick the first now anyway
       
   300             smallest_rowid.try_into().unwrap()
       
   301         }
       
   302         
       
   303     }
       
   304 }
       
   305 
       
   306 /*** Row ****/
       
   307 // a row of cards on the table (max 5)
       
   308 #[derive(Debug)]
       
   309 struct Row {
       
   310     cards: VecDeque<Card>,
       
   311 }
       
   312 
       
   313 impl Row {
       
   314     const MAX_LEN: usize = 5;
       
   315 
       
   316     fn new() -> Self {
       
   317         Row {
       
   318             cards: VecDeque::with_capacity(5),
       
   319         }
       
   320     }
       
   321 
       
   322     fn push_or_collect( &mut self, card: Card ) -> Option<VecDeque<Card>> {
       
   323         trace!("Called push_or_collect on row {:?}", &self);
       
   324         if self.cards.len() < Self::MAX_LEN {
       
   325             trace!("Less than {} cards, putting at the end", Self::MAX_LEN);
       
   326             self.cards.push_back(card);
       
   327             None
       
   328 
       
   329         } else {
       
   330             trace!("Row is full, len {}, maxlen {}", self.cards.len(), Self::MAX_LEN);
       
   331             // row overflow
       
   332             let row_cards = mem::take( &mut self.cards );
       
   333             self.cards.push_back(card);
       
   334             if self.cards.len() != 1 {
       
   335                 panic!("New row must have one card, not {}", self.cards.len());
       
   336             }
       
   337             Some(row_cards)
       
   338         }
       
   339     }
       
   340 
       
   341     fn take_row( &mut self ) -> VecDeque<Card> {
       
   342         // take cards and empty the row
       
   343         mem::take( &mut self.cards )
       
   344     }
       
   345 
       
   346     fn last_card_value(&self) -> i8 {
       
   347         // println!("last_card_value: cards {:?}, len {}", self.cards, self.cards.len());
       
   348         self.cards.get( self.cards.len()-1 ).unwrap().value
       
   349     }
       
   350 
       
   351     // sum of row card points
       
   352     fn sum(&self) -> i32 {
       
   353         let mut sum: i32 = 0;
       
   354         self.cards.iter().for_each(|card| {
       
   355             sum += card.points as i32;
       
   356         });
       
   357         sum
       
   358     }
       
   359 }
       
   360 
       
   361 /*** PlayerCard ****/
       
   362 #[derive(Debug)]
       
   363 struct PlayerCard {
       
   364     player_id: i32,
       
   365     card: Card,
       
   366 }
       
   367 
       
   368 impl PlayerCard {
       
   369     fn _get_player(&self) -> i32 {
       
   370         self.player_id
       
   371     }
       
   372 }
       
   373 
       
   374 impl PartialEq for PlayerCard {
       
   375     fn eq(&self, other: &Self) -> bool {
       
   376         self.card == other.card
       
   377     }
       
   378 }
       
   379 
       
   380 impl PartialOrd for PlayerCard {
       
   381     fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
       
   382         match self.card.partial_cmp(&other.card) {
       
   383             Some(core::cmp::Ordering::Equal) => {None}
       
   384             ord => return ord,
       
   385         }
       
   386     }
       
   387 }
       
   388 
       
   389 /*** Table ****/
       
   390 #[derive(Debug)]
       
   391 struct Table {
       
   392     rows: Vec<Row>,
       
   393     player_cards: VecDeque<PlayerCard>, // owned by a player
       
   394 }
       
   395 
       
   396 impl Table {
       
   397     fn new(row_cards: VecDeque<Card>) -> Self {
       
   398         let mut rows = Vec::with_capacity(5);
       
   399         for card in row_cards {
       
   400             // create a new row then put a card into it
       
   401             let mut row = Row::new();
       
   402             if let Some(_c) = row.push_or_collect(card) {
       
   403                 panic!("Freshly created row overflowed");
       
   404             }
       
   405             rows.push( row );
       
   406         }
       
   407 
       
   408         Table {
       
   409             rows,
       
   410             player_cards: VecDeque::new(),
       
   411         }
       
   412     }
       
   413 
       
   414     fn lay_player_card( &mut self, card: Card, player_id: i32 ) {
       
   415         self.player_cards.push_back( PlayerCard { player_id, card } );
       
   416     }
       
   417 
       
   418     fn sort_cards( &mut self ) {
       
   419         self.player_cards.make_contiguous().sort_by( |a,b| b.card.cmp(&a.card) );
       
   420     }
       
   421 
       
   422     fn has_player_cards( &self ) -> bool {
       
   423         self.player_cards.len() > 0
       
   424     }
       
   425 
       
   426     fn get_smallest_player_card( &mut self ) -> PlayerCard {
       
   427         // FIXME: check!
       
   428         self.player_cards.pop_back().expect("out of player cards on table")
       
   429     }
       
   430 
       
   431     fn get_closest_row( &self, pcard: &PlayerCard ) -> Option<usize> {
       
   432         // get the row id with last card closest smaller to players'
       
   433         let row_heads = self.get_row_heads();
       
   434         let mut closest_val = None;
       
   435         let mut diff = 127;
       
   436         for i in 0..row_heads.len() {
       
   437             if row_heads[i] < pcard.card.value && pcard.card.value - row_heads[i] < diff {
       
   438                 closest_val = Some(i);
       
   439                 diff = pcard.card.value - row_heads[i];
       
   440                 // println!("DEBUG: pcard {}, row {}, head {}, diff {}, closest {:?}", pcard.card.value, i, row_heads[i], diff, closest_val);
       
   441             }
       
   442         }
       
   443 
       
   444         closest_val
       
   445     }
       
   446 
       
   447     fn put_card_into_row( &mut self, pcard: PlayerCard, row_id: usize ) -> Option<VecDeque<Card>> {
       
   448         self.rows[row_id as usize].push_or_collect(pcard.card)
       
   449     }
       
   450 
       
   451     fn get_row_heads( &self ) -> Vec<i8> {
       
   452         let mut heads: Vec<i8> = Vec::new();
       
   453         for i in 0..self.rows.len() {
       
   454             heads.push( self.rows[i].last_card_value() );
       
   455         }
       
   456         heads
       
   457     }
       
   458 
       
   459     // take a whole row and hand it over
       
   460     fn take_row( &mut self, row_id: usize ) -> VecDeque<Card> {
       
   461         self.rows[row_id].take_row()
       
   462     }
       
   463 
       
   464     // collect remaining cards in the rows at the end of round
       
   465     fn collect_rows( &mut self ) -> VecDeque<Card> {
       
   466         let mut cards = VecDeque::new();
       
   467         for row in 0..self.rows.len() {
       
   468             self.rows[row]
       
   469                 .take_row()
       
   470                 .into_iter()
       
   471                 .for_each(|card| cards.push_back(card));
       
   472         }
       
   473         cards
       
   474     }
       
   475 }
       
   476 
    36 
   477 
    37 
   478 /*** Game ****/
    38 /*** Game ****/
   479 
    39 
   480 struct GameStat {
    40 struct GameStat {
   554                         debug!("Putting down card into row {}", rowid);
   114                         debug!("Putting down card into row {}", rowid);
   555                         let player_id: usize = smallest.player_id.try_into().unwrap();
   115                         let player_id: usize = smallest.player_id.try_into().unwrap();
   556                         let overflow = table.put_card_into_row(smallest, rowid);
   116                         let overflow = table.put_card_into_row(smallest, rowid);
   557                         if let Some(cards) = overflow {
   117                         if let Some(cards) = overflow {
   558                             // row is full, got pile
   118                             // row is full, got pile
   559                             debug!("Row is busted, {} collects", players[player_id].name);
   119                             debug!("Row is busted, {} collects", players[player_id].get_name());
   560                             // player gets pile, card gets into row head
   120                             // player gets pile, card gets into row head
   561                             players[ player_id ].give_pile( cards );
   121                             players[ player_id ].give_pile( cards );
   562                         }
   122                         }
   563                     },
   123                     },
   564                     None => {
   124                     None => {
   565                         // card too small, need to pick row!
   125                         // card too small, need to pick row!
   566                         let player_id: usize = smallest.player_id.try_into().unwrap();
   126                         let player_id: usize = smallest.player_id.try_into().unwrap();
   567                         debug!("Too small from {}, picking row", players[player_id].name);
   127                         debug!("Too small from {}, picking row", players[player_id].get_name());
   568                         // pick any row to take
   128                         // pick any row to take
   569                         let rowid = players[ player_id ].pick_row_for_small_card(&table.rows, &smallest.card);
   129                         // let rowid = players[ player_id ].pick_row_for_small_card(&table.rows, &smallest.card);
       
   130                         let rowid = players[ player_id ].pick_row_for_small_card(table.peek_rows(), &smallest.card);
   570                         trace!("Picked row {}", rowid);
   131                         trace!("Picked row {}", rowid);
   571                         // take the row cards
   132                         // take the row cards
   572                         let cards = table.take_row(rowid);
   133                         let cards = table.take_row(rowid);
   573                         trace!("Took cards: {:?}", cards);
   134                         trace!("Took cards: {:?}", cards);
   574                         players[ player_id ].give_pile( cards );
   135                         players[ player_id ].give_pile( cards );
   588         debug!("End of round, counting and collecting back piles");
   149         debug!("End of round, counting and collecting back piles");
   589         let mut winners: Vec<usize> = Vec::new();
   150         let mut winners: Vec<usize> = Vec::new();
   590         let mut winscore: i32 = i32::MAX-1;
   151         let mut winscore: i32 = i32::MAX-1;
   591 
   152 
   592         for i in 0..player_count {
   153         for i in 0..player_count {
   593             info!("Player {} has {} points", players[i].name, players[i].game_point);
   154             info!("Player {} has {} points", players[i].get_name(), players[i].get_points());
   594 
   155 
   595             if players[i].game_point < winscore  {
   156             if players[i].get_points() < winscore  {
   596                 trace!("New winner {} with score {}", players[i].name, players[i].game_point);
   157                 trace!("New winner {} with score {}", players[i].get_name(), players[i].get_points());
   597                 winners.clear();
   158                 winners.clear();
   598                 winners.push(i);
   159                 winners.push(i);
   599                 winscore = players[i].game_point;
   160                 winscore = players[i].get_points();
   600             
   161             
   601             } else if players[i].game_point == winscore {
   162             } else if players[i].get_points() == winscore {
   602                 trace!("New co-winner {} with score {}", players[i].name, players[i].game_point);
   163                 trace!("New co-winner {} with score {}", players[i].get_name(), players[i].get_points());
   603                 winners.push(i);
   164                 winners.push(i);
   604             }
   165             }
   605             trace!("The list of winners is {:?}", winners);
   166             trace!("The list of winners is {:?}", winners);
   606 
   167 
   607             // get pile from player
   168             // get pile from player
   612             players[i].close_round();
   173             players[i].close_round();
   613         }
   174         }
   614 
   175 
   615         // collect cards from table
   176         // collect cards from table
   616         deck.push_cards( table.collect_rows() );
   177         deck.push_cards( table.collect_rows() );
   617         trace!("Shall have full deck now, len {}", deck.content.len());
   178         trace!("Shall have full deck now, len {}", deck.len());
   618 
   179 
   619         let mut finals = Vec::new();
   180         let mut finals = Vec::new();
   620         for i in winners.iter() {
   181         for i in winners.iter() {
   621             players[*i].inc_wins();
   182             players[*i].inc_wins();
   622         }
   183         }
   623 
   184 
   624         for i in winners {
   185         for i in winners {
   625             finals.push( &players[i].name );
   186             finals.push( players[i].get_name() );
   626         }
   187         }
   627         info!("The winner(s): {:?}", &finals);
   188         info!("The winner(s): {:?}", &finals);
   628 
   189 
   629 /*         players.iter().for_each(|player| {
   190 /*         players.iter().for_each(|player| {
   630             println!("Player {} has {} points", player.name, player.game_point);
   191             println!("Player {} has {} points", player.name, player.game_point);
   633             player.close_round();
   194             player.close_round();
   634         });
   195         });
   635  */
   196  */
   636     }
   197     }
   637 
   198 
       
   199     // do the type conversions _very_ visibly 
   638     let elapsed_micro: f64 = stats.start_time.elapsed().as_micros() as f64;
   200     let elapsed_micro: f64 = stats.start_time.elapsed().as_micros() as f64;
   639     let game_rounds: f64 = GAME_ROUNDS.into();
   201     let game_rounds: f64 = GAME_ROUNDS.into();
   640 
   202     // which is same as the slightly uglier
   641     let _res: f64 = stats.start_time.elapsed().as_micros() as f64 / <i32 as Into<f64>>::into(GAME_ROUNDS);
   203     let _res: f64 = stats.start_time.elapsed().as_micros() as f64 / <i32 as Into<f64>>::into(GAME_ROUNDS);
   642 
   204 
   643     println!("Totals (game time {} µs, or {} s; {} µs/game), {} games played ({} shuffles):", 
   205     println!("Totals (game time {} µs, or {} s; {} µs/game), {} games played ({} shuffles):", 
   644         stats.start_time.elapsed().as_micros(), 
   206         stats.start_time.elapsed().as_micros(), 
   645         stats.start_time.elapsed().as_secs(),
   207         stats.start_time.elapsed().as_secs(),
   648         stats.shuffle_count,
   210         stats.shuffle_count,
   649     );
   211     );
   650 
   212 
   651     // players.sort_by( |a, b| a.total_point.partial_cmp(&b.total_point).unwrap() );    // ASC points
   213     // players.sort_by( |a, b| a.total_point.partial_cmp(&b.total_point).unwrap() );    // ASC points
   652     // players.sort_by( |a, b| b.wins.partial_cmp(&a.wins).unwrap() );                  // DESC wins
   214     // players.sort_by( |a, b| b.wins.partial_cmp(&a.wins).unwrap() );                  // DESC wins
   653     players.sort_by_cached_key( |x| Reverse(x.wins) );                                  // DESC wins (caching is just for the show)
   215     players.sort_by_cached_key( |x| Reverse(x.get_wins()) );                                  // DESC wins (caching is just for the show)
   654 
   216 
   655     for i in 0..players.len() {
   217     for i in 0..players.len() {
   656         let p = &players[i];
   218         let p = &players[i];
   657         println!("Player {} has wins {}, score {} (busted {} times)", p.name, p.wins, p.total_point, p.rows_busted);
   219         println!("Player {} has wins {}, score {} (busted {} times)", 
       
   220             p.get_name(), 
       
   221             p.get_wins(), 
       
   222             p.get_total_points(), 
       
   223             p.get_rows_busted());
   658     }
   224     }
   659 }
   225 }
   660 
   226 
   661 #[cfg(test)]
   227 #[cfg(test)]
   662 mod tests {
   228 mod tests {
   663     // use core::panic;
       
   664     use std::collections::VecDeque;
   229     use std::collections::VecDeque;
   665 
       
   666     use rand::Rng;
   230     use rand::Rng;
   667 
   231 
   668     use crate::{Card, Player, Row, Table, PlayerCard};
   232     use crate::{card::Card, player::{Player, PlayerCard}, row::Row, table::Table};
   669 
   233 
   670     #[test]
   234     #[test]
   671     fn card_values() {
   235     fn card_values() {
   672         let card_values = vec![1,2,5,10,33,55,77];
   236         let card_values = vec![1,2,5,10,33,55,77];
   673         let card_points = vec![1,1,2,3, 5, 7, 5];
   237         let card_points = vec![1,1,2,3, 5, 7, 5];
   691             let c = Card::new(i);
   255             let c = Card::new(i);
   692             refpile.push_back(c);
   256             refpile.push_back(c);
   693         }
   257         }
   694         // give the pile to player
   258         // give the pile to player
   695         p.give_pile(pile);
   259         p.give_pile(pile);
   696         assert!( p.rows_busted == 1 );
   260         assert!( p.get_rows_busted() == 1 );
   697 
   261 
   698         // get back the pile from player
   262         // get back the pile from player
   699         // p = p.gimme_pile();
   263         // p = p.gimme_pile();
   700         let pile = p.get_pile();
   264         let pile = p.get_pile();
   701         
   265         
   708         for i in 4..=9 {
   272         for i in 4..=9 {
   709             let c = Card::new(i);
   273             let c = Card::new(i);
   710             pile.push_back(c);
   274             pile.push_back(c);
   711         }
   275         }
   712         p.give_pile(pile);
   276         p.give_pile(pile);
   713         assert!( p.rows_busted == 2 );
   277         assert!( p.get_rows_busted() == 2 );
   714     }
   278     }
   715 
   279 
   716     #[test]
   280     #[test]
   717     fn row_push() {
   281     fn row_push() {
   718         let mut row = Row::new();
   282         let mut row = Row::new();
   735             refcard.push_back(card);
   299             refcard.push_back(card);
   736 
   300 
   737             // check card value
   301             // check card value
   738             assert!( row.last_card_value() == cval, "Last card value mismatch: got {} vs expected {}", row.last_card_value(), cval );
   302             assert!( row.last_card_value() == cval, "Last card value mismatch: got {} vs expected {}", row.last_card_value(), cval );
   739         }
   303         }
   740         assert!( row.cards.len() == 2, "Row contains wrong amount of cards: {}", row.cards.len() );
   304         assert!( row.len() == 2, "Row contains wrong amount of cards: {}", row.len() );
   741     }
   305     }
   742 
   306 
   743     #[test]
   307     #[test]
   744     fn sort_cards() {
   308     fn sort_cards() {
   745         let mut cards: VecDeque<Card> = VecDeque::new();
   309         let mut cards: VecDeque<Card> = VecDeque::new();