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::{fmt, panic}; |
6 use std::{collections::VecDeque, time::Instant, i64::MAX}; |
6 use std::{collections::VecDeque, time::Instant, cmp::Reverse}; |
7 use rand::Rng; |
7 use rand::Rng; |
8 use std::mem; |
8 use std::mem; |
9 |
9 |
10 extern crate pretty_env_logger; |
10 extern crate pretty_env_logger; |
11 #[macro_use] extern crate log; |
11 #[macro_use] extern crate log; |
150 |
150 |
151 fn len( &self ) -> usize { |
151 fn len( &self ) -> usize { |
152 self.content.len() |
152 self.content.len() |
153 } |
153 } |
154 |
154 |
155 fn get_nth( &mut self, n: usize ) -> Card { |
155 fn _get_nth( &mut self, n: usize ) -> Card { |
156 if let Some(c) = self.content.remove(n) { |
156 if let Some(c) = self.content.remove(n) { |
157 c |
157 c |
158 } else { |
158 } else { |
159 panic!("get_nth: index {} out of bounds ({})!", n, self.content.len()); |
159 panic!("get_nth: index {} out of bounds ({})!", n, self.content.len()); |
160 } |
160 } |
212 self.rows_busted += 1; |
212 self.rows_busted += 1; |
213 trace!("Player {} got busted, count {}", self.name, &self.rows_busted); |
213 trace!("Player {} got busted, count {}", self.name, &self.rows_busted); |
214 } |
214 } |
215 |
215 |
216 // ask the player their score |
216 // ask the player their score |
217 fn tell_points( self ) -> i32 { |
217 fn _tell_points( self ) -> i32 { |
218 self.game_point |
218 self.game_point |
219 } |
219 } |
220 |
220 |
221 fn inc_wins( &mut self ) { |
221 fn inc_wins( &mut self ) { |
222 self.wins += 1; |
222 self.wins += 1; |
264 // card too small: pick a row to collect from the rows |
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 { |
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); |
266 trace!("Player {} picking a row for small card, card {:?}, rows {:?}", self.name, playercard, rows); |
267 |
267 |
268 // contains the summary point for each row |
268 // contains the summary point for each row |
269 let mut row_points = Vec::new(); |
269 let mut row_points = Vec::with_capacity(5); |
270 // the smallest row score |
270 // the smallest row score |
271 let mut smallest = 999; |
271 let mut smallest = 999; |
272 // how many rows have the same smallest score |
272 // how many rows have the same smallest score |
273 let mut same_point = 0; |
273 let mut same_point = 0; |
274 // the first smallest row_id |
274 // the first smallest row_id |
313 impl Row { |
313 impl Row { |
314 const MAX_LEN: usize = 5; |
314 const MAX_LEN: usize = 5; |
315 |
315 |
316 fn new() -> Self { |
316 fn new() -> Self { |
317 Row { |
317 Row { |
318 cards: VecDeque::new(), |
318 cards: VecDeque::with_capacity(5), |
319 } |
319 } |
320 } |
320 } |
321 |
321 |
322 fn push_or_collect( &mut self, card: Card ) -> Option<VecDeque<Card>> { |
322 fn push_or_collect( &mut self, card: Card ) -> Option<VecDeque<Card>> { |
323 trace!("Called push_or_collect on row {:?}", &self); |
323 trace!("Called push_or_collect on row {:?}", &self); |
393 player_cards: VecDeque<PlayerCard>, // owned by a player |
393 player_cards: VecDeque<PlayerCard>, // owned by a player |
394 } |
394 } |
395 |
395 |
396 impl Table { |
396 impl Table { |
397 fn new(row_cards: VecDeque<Card>) -> Self { |
397 fn new(row_cards: VecDeque<Card>) -> Self { |
398 let mut rows = Vec::new(); |
398 let mut rows = Vec::with_capacity(5); |
399 for card in row_cards { |
399 for card in row_cards { |
400 // create a new row then put a card into it |
400 // create a new row then put a card into it |
401 let mut row = Row::new(); |
401 let mut row = Row::new(); |
402 if let Some(c) = row.push_or_collect(card) { |
402 if let Some(_c) = row.push_or_collect(card) { |
403 panic!("Freshly created row overflowed"); |
403 panic!("Freshly created row overflowed"); |
404 } |
404 } |
405 rows.push( row ); |
405 rows.push( row ); |
406 } |
406 } |
407 |
407 |
499 stats.shuffle_count += 1; |
499 stats.shuffle_count += 1; |
500 stats.game_count += 1; |
500 stats.game_count += 1; |
501 |
501 |
502 // dealing |
502 // dealing |
503 debug!("Dealing."); |
503 debug!("Dealing."); |
504 for i in 1..=10 { |
504 for _i in 1..=10 { |
505 for player in 0 .. player_count { |
505 for player in 0 .. player_count { |
506 players[player].get_card( deck.pop().expect("Deck is empty while dealing to players") ); |
506 players[player].get_card( deck.pop().expect("Deck is empty while dealing to players") ); |
507 } |
507 } |
508 } |
508 } |
509 |
509 |
510 // we need 5 crds from deck |
510 // we need 5 crds from deck |
511 debug!("Building the rows."); |
511 debug!("Building the rows."); |
512 let mut cards = VecDeque::new(); |
512 let mut cards = VecDeque::new(); |
513 for i in 1..=5 { |
513 (1..=5).for_each(|_| { |
514 cards.push_back( deck.pop().expect("deck empty before starting the game") ); |
514 cards.push_back( deck.pop().expect("deck empty before starting the game") ); |
515 } |
515 }); |
516 // println!("We push 5 cards to rows: {:?}\n", cards); |
516 // println!("We push 5 cards to rows: {:?}\n", cards); |
517 let mut table = Table::new(cards); |
517 let mut table = Table::new(cards); |
518 |
518 |
519 // DEBUG |
519 // DEBUG |
520 /* println!("Table: {:?}\n", table); |
520 /* println!("Table: {:?}\n", table); |
572 let cards = table.take_row(rowid); |
572 let cards = table.take_row(rowid); |
573 trace!("Took cards: {:?}", cards); |
573 trace!("Took cards: {:?}", cards); |
574 players[ player_id ].give_pile( cards ); |
574 players[ player_id ].give_pile( cards ); |
575 // put new card in the row |
575 // put new card in the row |
576 let overflow = table.put_card_into_row(smallest, rowid); |
576 let overflow = table.put_card_into_row(smallest, rowid); |
577 if let Some(c) = overflow { |
577 if let Some(_) = overflow { |
578 panic!("Player took whole row and it's already full"); |
578 panic!("Player took whole row and it's already full"); |
579 } |
579 } |
580 } |
580 } |
581 } |
581 } |
582 } |
582 } |
633 player.close_round(); |
633 player.close_round(); |
634 }); |
634 }); |
635 */ |
635 */ |
636 } |
636 } |
637 |
637 |
638 println!("Totals (game time {} µs, or {} s), {} games played ({} shuffles):", |
638 let elapsed_micro: f64 = stats.start_time.elapsed().as_micros() as f64; |
|
639 let game_rounds: f64 = GAME_ROUNDS.into(); |
|
640 |
|
641 let _res: f64 = stats.start_time.elapsed().as_micros() as f64 / <i32 as Into<f64>>::into(GAME_ROUNDS); |
|
642 |
|
643 println!("Totals (game time {} µs, or {} s; {} µs/game), {} games played ({} shuffles):", |
639 stats.start_time.elapsed().as_micros(), |
644 stats.start_time.elapsed().as_micros(), |
640 stats.start_time.elapsed().as_secs(), |
645 stats.start_time.elapsed().as_secs(), |
|
646 elapsed_micro / game_rounds, |
641 stats.game_count, |
647 stats.game_count, |
642 stats.shuffle_count, |
648 stats.shuffle_count, |
643 ); |
649 ); |
644 |
650 |
645 players.sort_by( |a, b| a.total_point.partial_cmp(&b.total_point).unwrap() ); |
651 // 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 |
|
653 players.sort_by_cached_key( |x| Reverse(x.wins) ); // DESC wins (caching is just for the show) |
646 |
654 |
647 for i in 0..players.len() { |
655 for i in 0..players.len() { |
648 let p = &players[i]; |
656 let p = &players[i]; |
649 println!("Player {} has wins {}, score {} (busted {} times)", p.name, p.wins, p.total_point, p.rows_busted); |
657 println!("Player {} has wins {}, score {} (busted {} times)", p.name, p.wins, p.total_point, p.rows_busted); |
650 } |
658 } |
651 } |
659 } |
652 |
660 |
653 #[cfg(test)] |
661 #[cfg(test)] |
654 mod tests { |
662 mod tests { |
655 use core::panic; |
663 // use core::panic; |
656 use std::collections::VecDeque; |
664 use std::collections::VecDeque; |
657 |
665 |
658 use rand::Rng; |
666 use rand::Rng; |
659 |
667 |
660 use crate::{Card, Player, Row, Table, PlayerCard}; |
668 use crate::{Card, Player, Row, Table, PlayerCard}; |
734 |
742 |
735 #[test] |
743 #[test] |
736 fn sort_cards() { |
744 fn sort_cards() { |
737 let mut cards: VecDeque<Card> = VecDeque::new(); |
745 let mut cards: VecDeque<Card> = VecDeque::new(); |
738 let mut rng = rand::thread_rng(); |
746 let mut rng = rand::thread_rng(); |
739 for i in 1..50 { |
747 for _ in 1..50 { |
740 let n = rng.gen_range(1..104); |
748 let n = rng.gen_range(1..104); |
741 cards.push_back( Card::new(n) ); |
749 cards.push_back( Card::new(n) ); |
742 } |
750 } |
743 cards.make_contiguous().sort(); |
751 cards.make_contiguous().sort(); |
744 |
752 |