games-rs 0.5.0

Pre-implemented games written in rust.
Documentation
/// Checks if `top` can go on top of `bottom`
pub(crate) fn can_stack(
    bottom: Option<crate::solitaire::SolitaireCard>,
    top: crate::solitaire::SolitaireCard,
    foundation: bool,
) -> bool {
    // TODO: test this if statement, enough to eyeball for now
    match bottom {
        Some(bottom) => {
            if bottom.card.color() == top.card.color() {
                if foundation {
                    if bottom.card.eq_suite(top.card) {
                        match bottom.card.face() {
                            crate::cards::StandardCardFace::Ace => {
                                top.card.face() == crate::cards::StandardCardFace::Two
                            }
                            crate::cards::StandardCardFace::Two => {
                                top.card.face() == crate::cards::StandardCardFace::Three
                            }
                            crate::cards::StandardCardFace::Three => {
                                top.card.face() == crate::cards::StandardCardFace::Four
                            }
                            crate::cards::StandardCardFace::Four => {
                                top.card.face() == crate::cards::StandardCardFace::Five
                            }
                            crate::cards::StandardCardFace::Five => {
                                top.card.face() == crate::cards::StandardCardFace::Six
                            }
                            crate::cards::StandardCardFace::Six => {
                                top.card.face() == crate::cards::StandardCardFace::Seven
                            }
                            crate::cards::StandardCardFace::Seven => {
                                top.card.face() == crate::cards::StandardCardFace::Eight
                            }
                            crate::cards::StandardCardFace::Eight => {
                                top.card.face() == crate::cards::StandardCardFace::Nine
                            }
                            crate::cards::StandardCardFace::Nine => {
                                top.card.face() == crate::cards::StandardCardFace::Ten
                            }
                            crate::cards::StandardCardFace::Ten => {
                                top.card.face() == crate::cards::StandardCardFace::Jack
                            }
                            crate::cards::StandardCardFace::Jack => {
                                top.card.face() == crate::cards::StandardCardFace::Queen
                            }
                            crate::cards::StandardCardFace::Queen => {
                                top.card.face() == crate::cards::StandardCardFace::King
                            }
                            crate::cards::StandardCardFace::King => false,
                            crate::cards::StandardCardFace::Joker => unreachable!(),
                        }
                    } else {
                        false
                    }
                } else {
                    false
                }
            } else if !bottom.card.eq_suite(top.card) && !foundation {
                if top.is_facedown() {
                    false
                } else if bottom.is_facedown() {
                    top.card.face() == crate::cards::StandardCardFace::King
                } else {
                    match top.card.face() {
                        crate::cards::StandardCardFace::King => false,
                        crate::cards::StandardCardFace::Queen => {
                            bottom.card.face() == crate::cards::StandardCardFace::King
                        }
                        crate::cards::StandardCardFace::Jack => {
                            bottom.card.face() == crate::cards::StandardCardFace::Queen
                        }
                        crate::cards::StandardCardFace::Ten => {
                            bottom.card.face() == crate::cards::StandardCardFace::Joker
                        }
                        crate::cards::StandardCardFace::Nine => {
                            bottom.card.face() == crate::cards::StandardCardFace::Ten
                        }
                        crate::cards::StandardCardFace::Eight => {
                            bottom.card.face() == crate::cards::StandardCardFace::Nine
                        }
                        crate::cards::StandardCardFace::Seven => {
                            bottom.card.face() == crate::cards::StandardCardFace::Eight
                        }
                        crate::cards::StandardCardFace::Six => {
                            bottom.card.face() == crate::cards::StandardCardFace::Seven
                        }
                        crate::cards::StandardCardFace::Five => {
                            bottom.card.face() == crate::cards::StandardCardFace::Six
                        }
                        crate::cards::StandardCardFace::Four => {
                            bottom.card.face() == crate::cards::StandardCardFace::Five
                        }
                        crate::cards::StandardCardFace::Three => {
                            bottom.card.face() == crate::cards::StandardCardFace::Four
                        }
                        crate::cards::StandardCardFace::Two => {
                            bottom.card.face() == crate::cards::StandardCardFace::Three
                        }
                        crate::cards::StandardCardFace::Ace => {
                            bottom.card.face() == crate::cards::StandardCardFace::Two
                        }
                        crate::cards::StandardCardFace::Joker => unreachable!(),
                    }
                }
            } else {
                false
            }
        }
        None => match top.card.face() {
            crate::cards::StandardCardFace::Ace => foundation && top.is_faceup(),
            crate::cards::StandardCardFace::King => !foundation && top.is_faceup(),
            _ => false,
        },
    }
}
#[cfg(test)]
mod test {
    use crate::cards::{StandardCard, StandardCardFace};
    use crate::solitaire::SolitaireCard;
    use crate::solitaire::utils;
    #[test]
    fn stack_check_foundation() {
        let mut top = None;
        //
        for heart in &HEARTS {
            let card = SolitaireCard::new_up(*heart);
            if let Some(left) = top.replace(card) {
                assert!(utils::can_stack(Some(left), card, true))
            }
        }
        let mut top = None;
        for spade in &SPADES {
            let card = SolitaireCard::new_up(*spade);
            if let Some(left) = top.replace(card) {
                assert!(utils::can_stack(Some(left), card, true))
            }
        }
        let mut top = None;
        for club in &CLUBS {
            let card = SolitaireCard::new_up(*club);
            if let Some(left) = top.replace(card) {
                assert!(utils::can_stack(Some(left), card, true))
            }
        }
        let mut top = None;
        for diamond in &DIAMONDS {
            let card = SolitaireCard::new_up(*diamond);
            if let Some(left) = top.replace(card) {
                assert!(utils::can_stack(Some(left), card, true))
            }
        }
        let mut left = SolitaireCard::new_down(CLUBS[11]);
        let mut right = SolitaireCard::new_up(HEARTS[12]);
        // assert_ne!(left.card.suite_str(), right.card.suite_str());
        assert!(!utils::can_stack(Some(left), right, true));
        left.flip();
        assert!(!utils::can_stack(Some(left), right, true));
        left.flip();
        right.flip();
        assert!(!utils::can_stack(Some(left), right, true));
    }

    #[test]
    fn stack_check() {
        let mut left = SolitaireCard::new_down(CLUBS[11]);
        let right = SolitaireCard::new_up(HEARTS[12]);
        assert!(utils::can_stack(Some(left), right, false));
        assert!(!utils::can_stack(Some(right), left, false));
        left.flip();
        assert!(!utils::can_stack(Some(left), right, false));
        assert!(utils::can_stack(Some(right), left, false));
        left = SolitaireCard::new_down(DIAMONDS[11]);
        assert!(!utils::can_stack(Some(left), right, false));
        assert!(!utils::can_stack(Some(right), left, false));
        left.flip();
        assert!(!utils::can_stack(Some(left), right, false));
        assert!(!utils::can_stack(Some(right), left, false));
    }

    #[cfg(test)]
    const HEARTS: [StandardCard; 13] = [
        StandardCard::Hearts(StandardCardFace::Ace),
        StandardCard::Hearts(StandardCardFace::Two),
        StandardCard::Hearts(StandardCardFace::Three),
        StandardCard::Hearts(StandardCardFace::Four),
        StandardCard::Hearts(StandardCardFace::Five),
        StandardCard::Hearts(StandardCardFace::Six),
        StandardCard::Hearts(StandardCardFace::Seven),
        StandardCard::Hearts(StandardCardFace::Eight),
        StandardCard::Hearts(StandardCardFace::Nine),
        StandardCard::Hearts(StandardCardFace::Ten),
        StandardCard::Hearts(StandardCardFace::Jack),
        StandardCard::Hearts(StandardCardFace::Queen),
        StandardCard::Hearts(StandardCardFace::King),
    ];
    #[cfg(test)]
    const SPADES: [StandardCard; 13] = [
        StandardCard::Spades(StandardCardFace::Ace),
        StandardCard::Spades(StandardCardFace::Two),
        StandardCard::Spades(StandardCardFace::Three),
        StandardCard::Spades(StandardCardFace::Four),
        StandardCard::Spades(StandardCardFace::Five),
        StandardCard::Spades(StandardCardFace::Six),
        StandardCard::Spades(StandardCardFace::Seven),
        StandardCard::Spades(StandardCardFace::Eight),
        StandardCard::Spades(StandardCardFace::Nine),
        StandardCard::Spades(StandardCardFace::Ten),
        StandardCard::Spades(StandardCardFace::Jack),
        StandardCard::Spades(StandardCardFace::Queen),
        StandardCard::Spades(StandardCardFace::King),
    ];
    const CLUBS: [StandardCard; 13] = [
        StandardCard::Clubs(StandardCardFace::Ace),
        StandardCard::Clubs(StandardCardFace::Two),
        StandardCard::Clubs(StandardCardFace::Three),
        StandardCard::Clubs(StandardCardFace::Four),
        StandardCard::Clubs(StandardCardFace::Five),
        StandardCard::Clubs(StandardCardFace::Six),
        StandardCard::Clubs(StandardCardFace::Seven),
        StandardCard::Clubs(StandardCardFace::Eight),
        StandardCard::Clubs(StandardCardFace::Nine),
        StandardCard::Clubs(StandardCardFace::Ten),
        StandardCard::Clubs(StandardCardFace::Jack),
        StandardCard::Clubs(StandardCardFace::Queen),
        StandardCard::Clubs(StandardCardFace::King),
    ];
    const DIAMONDS: [StandardCard; 13] = [
        StandardCard::Diamonds(StandardCardFace::Ace),
        StandardCard::Diamonds(StandardCardFace::Two),
        StandardCard::Diamonds(StandardCardFace::Three),
        StandardCard::Diamonds(StandardCardFace::Four),
        StandardCard::Diamonds(StandardCardFace::Five),
        StandardCard::Diamonds(StandardCardFace::Six),
        StandardCard::Diamonds(StandardCardFace::Seven),
        StandardCard::Diamonds(StandardCardFace::Eight),
        StandardCard::Diamonds(StandardCardFace::Nine),
        StandardCard::Diamonds(StandardCardFace::Ten),
        StandardCard::Diamonds(StandardCardFace::Jack),
        StandardCard::Diamonds(StandardCardFace::Queen),
        StandardCard::Diamonds(StandardCardFace::King),
    ];
}