/// This is the implementation of a Deck of cards.
/// There are two basic kinds:
/// 1. The Game Deck, automatically generated 104 cards.
/// 2. Any Deck-type pile, like the hand of a Player.
/// Descks can be shuffled, cards pushed to bottom and
/// pulled from top. Maybe others, too.
///
use std::collections::VecDeque;
use rand::Rng;
/// We reference [`Card`]s
use crate::card::Card;
#[derive(Debug)]
/// A Deck is an ordered two-ended vector (`VecDeque`) of [`Card`]s.
pub(crate) struct Deck {
content: VecDeque<Card>,
}
impl Deck {
/// Creates an empty [`Deck`] of undefined size
pub(crate) fn new_empty() -> Self {
debug!("Empty deck generated");
Deck {
content: VecDeque::new(),
}
}
/// Creates a new full [`Deck`] with 104 cards.
pub(crate) fn new() -> Self {
debug!("Full deck generated");
let content = (1..=104).into_iter().map( |n| Card::new(n) ).collect();
Deck {
content,
}
}
/// Shuffles this [`Deck`] (using its default method)
pub(crate) fn shuffle( &mut self ) {
let mut rng = rand::thread_rng();
trace!("Deck before shuffle: len {}, {:?}", self.content.len(), self);
debug!("Deck shuffled");
// shufflers:
// * naive: swap cards n times
// * kgb: half the deck, take 1..4 cards sequentially from each
// * grin: take 1..6 from front and put at bottom
// naive shuffle: exchange <n> random cards
for _ in 1..=500 {
// Generate two random positions of cards in Deck
let c1 = rng.gen_range(0 .. self.content.len());
let c2 = rng.gen_range(0 .. self.content.len());
// If it's not the same card we swap them in the `content` vector.
// The `swap()` funtion handles ownership and does not angry
// the borrow checker.
if c1 != c2 {
self.content.swap(c1, c2);
}
}
trace!("Deck after shuffle: len {}, {:?}", self.content.len(), self);
}
/// Returns the top card of this [`Deck`].
pub(crate) fn pop( &mut self ) -> Option<Card> {
self.content.pop_front()
}
/// Put a card into the bottom of the [`Deck`]
pub(crate) fn push( &mut self, c: Card ) {
self.content.push_back(c);
}
/// Push multiple cards to the bottom of the [`Deck`]
pub(crate) fn push_cards( &mut self, cards: VecDeque<Card> ) {
trace!("Collecting back, deck len is {}, cards {}", self.content.len(), cards.len());
cards.into_iter().for_each( |card| self.push(card) );
trace!("Deck len is {}", self.content.len());
}
/// Returns the length of this [`Deck`].
pub(crate) fn len( &self ) -> usize {
self.content.len()
}
/// Take a card from inside of the Deck.
/// Using an illegal index will `panic!()`, so don't.
fn _get_nth( &mut self, n: usize ) -> Card {
if let Some(c) = self.content.remove(n) {
c
} else {
panic!("get_nth: index {} out of bounds ({})!", n, self.content.len());
}
}
}