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.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
     1
/*** Deck ****/
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
     2
use std::collections::VecDeque;
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
     3
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
     4
use rand::Rng;
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
     5
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
     6
use crate::card::Card;
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
     7
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
     8
#[derive(Debug)]
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
     9
pub(crate) struct Deck {
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    10
    content: VecDeque<Card>,
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    11
}
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    12
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    13
impl Deck {
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    14
    /// Creates an empty [`Deck`] of undefined size
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    15
    pub(crate) fn new_empty() -> Self {
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    16
        debug!("Empty deck generated");
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    17
        Deck {
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    18
            content: VecDeque::new(),
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    19
        }
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    20
    }
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    21
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    22
    /// Creates a new full [`Deck`] with 104 cards.
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    23
    pub(crate) fn new() -> Self {
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    24
        debug!("Full deck generated");
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    25
        let content = (1..=104).into_iter().map( |n| Card::new(n) ).collect();
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    26
        Deck {
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    27
            content,
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    28
        }
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    29
    }
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    30
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    31
    /// Shuffles this [`Deck`] (using its default method)
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    32
    pub(crate) fn shuffle( &mut self ) {
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    33
        let mut rng = rand::thread_rng();
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    34
        
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    35
        trace!("Deck before shuffle: len {}, {:?}", self.content.len(), self);
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    36
        debug!("Deck shuffled");
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    37
        // shufflers:
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    38
        // * naive: swap cards n times
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    39
        // * kgb: half the deck, take 1..4 cards sequentially from each
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    40
        // * grin: take 1..6 from front and put at bottom
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    41
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    42
        // naive shuffle: exchange random cards
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    43
        for _i in 1..=500 {
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    44
            let c1 = rng.gen_range(0 .. self.content.len());
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    45
            let c2 = rng.gen_range(0 .. self.content.len());
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    46
            if c1 != c2 {
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    47
                self.content.swap(c1, c2);
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    48
            }
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    49
        }
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    50
        trace!("Deck after shuffle: len {}, {:?}", self.content.len(), self);
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    51
    }
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    52
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    53
    /// Returns the top card of this [`Deck`].
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    54
    pub(crate) fn pop( &mut self ) -> Option<Card> {
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    55
        self.content.pop_front() 
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    56
    }
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    57
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    58
    /// Put a card into the bottom of the [`Deck`]
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    59
    pub(crate) fn push( &mut self, c: Card ) {
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    60
        self.content.push_back(c);
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    61
    }
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    62
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    63
    /// Push multiple cards to the bottom of the [`Deck`]
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    64
    pub(crate) fn push_cards( &mut self, cards: VecDeque<Card> ) {
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    65
        trace!("Collecting back, deck len is {}, cards {}", self.content.len(), cards.len());
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    66
        cards.into_iter().for_each( |card| self.push(card) );
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    67
        trace!("Deck len is {}", self.content.len());
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    68
    }
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    69
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    70
    /// Returns the length of this [`Deck`].
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    71
    pub(crate) fn len( &self ) -> usize {
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    72
        self.content.len()
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    73
    }
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    74
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    75
    fn _get_nth( &mut self, n: usize ) -> Card {
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    76
        if let Some(c) = self.content.remove(n) {
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    77
            c
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    78
        } else {
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    79
            panic!("get_nth: index {} out of bounds ({})!", n, self.content.len());
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    80
        }
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    81
    }
a2f0cb2b5c13 Split main into module files.
Peter Gervai <grin@grin.hu>
parents:
diff changeset
    82
}