games-rs 0.5.0

Pre-implemented games written in rust.
Documentation
use games::{
    cards::{StandardCard, StandardCardFace},
    solitaire::{Area, Solitaire, SolitaireCard},
};

#[test]
fn waste() {
    // Waste should be empty
    assert!(Solitaire::new().waste.is_empty());
}

#[test]
fn tablue() {
    // Tablue
    let st = ::games::solitaire::Solitaire::new();
    {
        // Verify The Card Lengths
        {
            assert_eq!(1usize, st.tablue[0].len());
            assert_eq!(2usize, st.tablue[1].len());
            assert_eq!(3usize, st.tablue[2].len());
            assert_eq!(4usize, st.tablue[3].len());
            assert_eq!(5usize, st.tablue[4].len());
            assert_eq!(6usize, st.tablue[5].len());
            assert_eq!(7usize, st.tablue[6].len());
        }
        // Verify The Card states
        {
            // Verify every row only has one face up card
            assert_eq!(
                7u8,
                st.tablue
                    .iter()
                    .map(|i| i.iter().filter(|c| !c.is_facedown()).count() as u8)
                    .sum()
            );
            // Verify the row's face down count
            //
            // Row 1/7
            assert_eq!(
                0usize,
                st.tablue[0].iter().filter(|c| c.is_facedown()).count()
            );
            // Row 2/7
            assert_eq!(
                1usize,
                st.tablue[1].iter().filter(|c| c.is_facedown()).count()
            );
            // Row 3/7
            assert_eq!(
                2usize,
                st.tablue[2].iter().filter(|c| c.is_facedown()).count()
            );
            // Row 4/7
            assert_eq!(
                3usize,
                st.tablue[3].iter().filter(|c| c.is_facedown()).count()
            );
            // Row 5/7
            assert_eq!(
                4usize,
                st.tablue[4].iter().filter(|c| c.is_facedown()).count()
            );
            // Row 6/7
            assert_eq!(
                5usize,
                st.tablue[5].iter().filter(|c| c.is_facedown()).count()
            );
            // Row 7/7
            assert_eq!(
                6usize,
                st.tablue[6].iter().filter(|c| c.is_facedown()).count()
            );
        }
    }
    // Verify no jokers
    assert!(
        st.tablue[0]
            .iter()
            .any(|c| c.card().face() != ::games::cards::StandardCardFace::Joker)
    );
    assert!(
        st.tablue[1]
            .iter()
            .any(|c| c.card().face() != ::games::cards::StandardCardFace::Joker)
    );
    assert!(
        st.tablue[2]
            .iter()
            .any(|c| c.card().face() != ::games::cards::StandardCardFace::Joker)
    );
    assert!(
        st.tablue[3]
            .iter()
            .any(|c| c.card().face() != ::games::cards::StandardCardFace::Joker)
    );
    assert!(
        st.tablue[4]
            .iter()
            .any(|c| c.card().face() != ::games::cards::StandardCardFace::Joker)
    );
    assert!(
        st.tablue[5]
            .iter()
            .any(|c| c.card().face() != ::games::cards::StandardCardFace::Joker)
    );
    assert!(
        st.tablue[6]
            .iter()
            .any(|c| c.card().face() != ::games::cards::StandardCardFace::Joker)
    );
}

#[test]
fn foundation() {
    let st = Solitaire::new();
    // Verify foundation pile is empty
    assert!(st.foundation.iter().all(Vec::is_empty));
}

#[test]
fn stockpile() {
    let st = Solitaire::new();
    // Verify the stockpile size
    assert_eq!(24usize, st.stockpile.len());
    // Verify no joker
    assert!(
        !st.stockpile
            .into_iter()
            .any(|c| c.face() == ::games::cards::StandardCardFace::Joker)
    )
}

#[test]
fn accurate_peek() {
    let mut s = Solitaire::new();
    // Draw metod
    for _ in 0..10 {
        s.peek()
            .and_then(|card| {
                s.stockpile
                    .draw()
                    .map_err(|_| games::solitaire::SolitaireError::OutOfRangeError)
                    .map(|card2| {
                        assert_eq!(card, card2);
                    })
            })
            .expect("There should be a positive result");
    }
    // Get card method
    for _ in 0..10 {
        s.peek()
            .and_then(|card| {
                s.draw_card().map(|card2| {
                    assert_eq!(card, card2);
                })
            })
            .expect("There should be a positive result")
    }
}

// ---- Tablue Movement ----
// Tablue -> Tablue
#[test]
fn tablue_to_tablue() {
    let mut s = Solitaire::new();
    s.tablue[1] = vec![SolitaireCard::new_up(StandardCard::Diamonds(
        StandardCardFace::King,
    ))];
    s.tablue[2] = vec![];
    s.move_to(
        Area::Tablue { row: 1, amount: 1 },
        Area::Tablue { row: 2, amount: 0 },
    )
    .unwrap();
}
// Tablue -> Foundation
#[test]
fn tablue_to_foundation() {
    let mut s = Solitaire::new();
    s.tablue[0] = vec![SolitaireCard::new_up(StandardCard::Hearts(
        StandardCardFace::Ace,
    ))];
    s.foundation[0] = vec![];
    s.move_to(
        Area::Tablue { row: 0, amount: 1 },
        Area::Foundation { row: 0 },
    )
    .expect("Expected move to be ok, but it failed");
    s.tablue[0] = vec![SolitaireCard::new_up(StandardCard::Spades(
        StandardCardFace::King,
    ))];
    s.move_to(
        Area::Tablue { row: 0, amount: 1 },
        Area::Foundation { row: 1 },
    )
    .expect_err("Expected an error, only ace can be on the bottom of the foundation pile");
}
// Tablue -> Waste (Illegal)
#[test]
fn tablue_to_waste() {
    let mut s = Solitaire::new();
    s.move_to(Area::Tablue { row: 3, amount: 1 }, Area::Waste)
        .expect_err("Expected error for illegal movement");
}
// Tablue -> Stockpile (Illegal)
#[test]
fn tablue_to_stockpile() {
    let mut s = Solitaire::new();
    s.move_to(Area::Tablue { row: 3, amount: 1 }, Area::Stockpile)
        .expect_err("Expected error for illegal movement");
}
// ----------------------------
// ---- Stockpile Movement ----
// Stockpile -> Waste
#[test]
fn stockpile_to_waste() {
    let mut s = Solitaire::new();
    s.move_to(Area::Stockpile, Area::Waste)
        .expect("Expect valid movement");
    s.stockpile.draw_rest();
    s.move_to(Area::Stockpile, Area::Waste)
        .expect_err("No cards in the stockpile to move");
}
// Stockpile -> Stockpile
#[test]
fn stockpile_to_stockpile() {
    let mut s = Solitaire::new();
    s.move_to(Area::Stockpile, Area::Stockpile)
        .expect_err("Illegal movement");
}
// Stockpile -> Foundation
#[test]
fn stockpile_to_foundation() {
    let mut s = Solitaire::new();
    s.stockpile = vec![StandardCard::Spades(StandardCardFace::Ace)]
        .into_iter()
        .collect();
    s.move_to(Area::Stockpile, Area::Foundation { row: 0 })
        .expect("Valid movement");
    s.stockpile = vec![StandardCard::Spades(StandardCardFace::King)]
        .into_iter()
        .collect();
    s.move_to(Area::Stockpile, Area::Foundation { row: 1 })
        .expect_err("Illegal movement");
}
// Stockpile -> Tablue
#[test]
fn stockpile_to_tablue() {
    let mut s = Solitaire::new();
    s.waste = vec![];
    s.stockpile = vec![StandardCard::Spades(StandardCardFace::King)]
        .into_iter()
        .collect();
    s.tablue[0] = vec![];
    s.move_to(Area::Stockpile, Area::Tablue { row: 0, amount: 1 })
        .expect("Valid movement");
    s.stockpile = vec![StandardCard::Spades(StandardCardFace::Ace)]
        .into_iter()
        .collect();
    s.tablue[0] = vec![];
    s.move_to(Area::Stockpile, Area::Tablue { row: 0, amount: 1 })
        .expect_err("Invalid movement");
}
// ----------------------------
// ---- Waste movement ----
// Waste -> Waste
#[test]
fn waste_to_waste() {
    Solitaire::new()
        .move_to(Area::Waste, Area::Waste)
        .expect_err("Illegal movement");
}
// Waste -> Stockpile
#[test]
fn waste_to_stockpile() {
    Solitaire::new()
        .move_to(Area::Waste, Area::Stockpile)
        .expect_err("Illegal movement");
}
// Waste -> Tablue
#[test]
fn waste_to_tablue() {
    let mut s = Solitaire::new();
    s.waste = vec![StandardCard::Spades(StandardCardFace::King)];
    s.tablue[0] = vec![];
    s.move_to(Area::Waste, Area::Tablue { row: 0, amount: 0 })
        .expect("Valid movement");
    s.waste = vec![StandardCard::Spades(StandardCardFace::Ace)];
    s.tablue[0] = vec![];
    s.move_to(Area::Waste, Area::Tablue { row: 0, amount: 0 })
        .expect_err("Invalid movement");
}
// Waste -> Foundation
#[test]
fn waste_to_foundation() {
    let mut s = Solitaire::new();
    s.waste = vec![StandardCard::Spades(StandardCardFace::Ace)];
    s.foundation[0] = vec![];
    s.move_to(Area::Waste, Area::Foundation { row: 0 })
        .expect("Valid movement");
    s.waste = vec![StandardCard::Spades(StandardCardFace::King)];
    s.foundation[0] = vec![];
    s.move_to(Area::Waste, Area::Foundation { row: 0 })
        .expect_err("Invalid movement");
}
// ----------------------------
// ---- Foundation Movement ----
// Foundation -> Waste
#[test]
fn foundation_to_waste() {
    let mut s = Solitaire::new();
    s.foundation[0] = vec![SolitaireCard::new_up(StandardCard::Spades(
        StandardCardFace::Ace,
    ))];
    s.move_to(Area::Foundation { row: 0 }, Area::Waste)
        .expect_err("Illegal movement");
}
// Foundation -> Stockpile
#[test]
fn foundation_to_stockpile() {
    let mut s = Solitaire::new();
    s.foundation[0] = vec![SolitaireCard::new_up(StandardCard::Spades(
        StandardCardFace::Ace,
    ))];
    s.move_to(Area::Foundation { row: 0 }, Area::Stockpile)
        .expect_err("Illegal movement");
}
// Foundation -> Tablue
#[test]
fn foundation_to_tablue() {
    let mut s = Solitaire::new();
    s.foundation[0] = vec![SolitaireCard::new_up(StandardCard::Spades(
        StandardCardFace::King,
    ))];
    s.tablue[0] = vec![];
    s.move_to(
        Area::Foundation { row: 0 },
        Area::Tablue { row: 0, amount: 0 },
    )
    .expect("legal movement");
    s.foundation[0] = vec![SolitaireCard::new_up(StandardCard::Spades(
        StandardCardFace::Ace,
    ))];
    s.tablue[0] = vec![];
    s.move_to(
        Area::Foundation { row: 0 },
        Area::Tablue { row: 0, amount: 0 },
    )
    .expect_err("Illegal movement");
}
// Foundation -> Foundation
#[test]
fn foundation_to_foundation() {
    let mut s = Solitaire::new();
    s.foundation[0] = vec![SolitaireCard::new_up(StandardCard::Spades(
        StandardCardFace::Ace,
    ))];
    s.move_to(Area::Foundation { row: 0 }, Area::Foundation { row: 1 })
        .expect_err("Illegal movement");
}