soliterm-model 0.1.0

Shared model types for soliterm
Documentation
use crate::card::Card;
use crate::card_sequence::CardSequence;
use crate::enums::EnumSequence as _;

pub(super) struct TableauSequence(!);

impl CardSequence for TableauSequence {
    fn accepts(current_card: Card, next_card: Card) -> bool {
        current_card.color() != next_card.color() && current_card.rank.follows(next_card.rank)
    }
}

#[cfg(test)]
mod test {
    use super::TableauSequence;
    use crate::card::{Card, Rank, Suit};
    use crate::card_sequence::CardSequence as _;

    mod tableau_sequence_accepts {
        use assert2::assert;
        use rstest::rstest;

        use super::*;

        #[rstest]
        #[case(Rank::Two, Rank::Ace)]
        #[case(Rank::Six, Rank::Five)]
        #[case(Rank::Jack, Rank::Ten)]
        #[case(Rank::King, Rank::Queen)]
        fn sequential_red_black(
            #[case] left_rank: Rank,
            #[case] right_rank: Rank,
            #[values(Suit::Hearts, Suit::Diamonds)] left_suit: Suit,
            #[values(Suit::Spades, Suit::Clubs)] right_suit: Suit,
        ) {
            let left_card = Card {
                rank: left_rank,
                suit: left_suit,
            };
            let right_card = Card {
                rank: right_rank,
                suit: right_suit,
            };

            assert!(TableauSequence::accepts(left_card, right_card) == true);
        }

        #[rstest]
        #[case(Rank::Two, Rank::Ace)]
        #[case(Rank::Six, Rank::Five)]
        #[case(Rank::Jack, Rank::Ten)]
        #[case(Rank::King, Rank::Queen)]
        fn sequential_black_red(
            #[case] left_rank: Rank,
            #[case] right_rank: Rank,
            #[values(Suit::Spades, Suit::Clubs)] left_suit: Suit,
            #[values(Suit::Hearts, Suit::Diamonds)] right_suit: Suit,
        ) {
            let left_card = Card {
                rank: left_rank,
                suit: left_suit,
            };
            let right_card = Card {
                rank: right_rank,
                suit: right_suit,
            };

            assert!(TableauSequence::accepts(left_card, right_card) == true);
        }

        #[rstest]
        #[case(Rank::Two, Rank::Ace)]
        #[case(Rank::Six, Rank::Five)]
        #[case(Rank::Jack, Rank::Ten)]
        #[case(Rank::King, Rank::Queen)]
        fn sequential_both_red(
            #[case] left_rank: Rank,
            #[case] right_rank: Rank,
            #[values(Suit::Hearts, Suit::Diamonds)] left_suit: Suit,
            #[values(Suit::Hearts, Suit::Diamonds)] right_suit: Suit,
        ) {
            let left_card = Card {
                rank: left_rank,
                suit: left_suit,
            };
            let right_card = Card {
                rank: right_rank,
                suit: right_suit,
            };

            assert!(TableauSequence::accepts(left_card, right_card) == false);
        }

        #[rstest]
        #[case(Rank::Two, Rank::Ace)]
        #[case(Rank::Six, Rank::Five)]
        #[case(Rank::Jack, Rank::Ten)]
        #[case(Rank::King, Rank::Queen)]
        fn sequential_both_black(
            #[case] left_rank: Rank,
            #[case] right_rank: Rank,
            #[values(Suit::Spades, Suit::Clubs)] left_suit: Suit,
            #[values(Suit::Spades, Suit::Clubs)] right_suit: Suit,
        ) {
            let left_card = Card {
                rank: left_rank,
                suit: left_suit,
            };
            let right_card = Card {
                rank: right_rank,
                suit: right_suit,
            };

            assert!(TableauSequence::accepts(left_card, right_card) == false);
        }

        #[rstest]
        #[case(Rank::Ace, Rank::Ace)]
        #[case(Rank::Ace, Rank::Two)]
        #[case(Rank::Ace, Rank::King)]
        #[case(Rank::Three, Rank::Ace)]
        #[case(Rank::Four, Rank::Four)]
        #[case(Rank::Four, Rank::Five)]
        #[case(Rank::Four, Rank::Six)]
        #[case(Rank::Six, Rank::Four)]
        #[case(Rank::King, Rank::King)]
        fn nonsequential_all_suits(
            #[case] left_rank: Rank,
            #[case] right_rank: Rank,
            #[values(Suit::Spades, Suit::Clubs, Suit::Hearts, Suit::Diamonds)] left_suit: Suit,
            #[values(Suit::Spades, Suit::Clubs, Suit::Hearts, Suit::Diamonds)] right_suit: Suit,
        ) {
            let left_card = Card {
                rank: left_rank,
                suit: left_suit,
            };
            let right_card = Card {
                rank: right_rank,
                suit: right_suit,
            };

            assert!(TableauSequence::accepts(left_card, right_card) == false);
        }
    }
}