src/deck.rs
author Peter Gervai <grin@grin.hu>
Tue, 31 Jan 2023 23:25:50 +0100
changeset 4 a2f0cb2b5c13
child 5 0dd7f2c9fd81
permissions -rw-r--r--
Split main into module files.

/*** Deck ****/
use std::collections::VecDeque;

use rand::Rng;

use crate::card::Card;

#[derive(Debug)]
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 random cards
        for _i in 1..=500 {
            let c1 = rng.gen_range(0 .. self.content.len());
            let c2 = rng.gen_range(0 .. self.content.len());
            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()
    }

    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());
        }
    }
}