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