diff --git a/src/card.rs b/src/card.rs index dd2fa5e..7be1603 100644 --- a/src/card.rs +++ b/src/card.rs @@ -5,7 +5,7 @@ use rand::distr::{Distribution, StandardUniform}; use rand::Rng; use std::fmt::{Display, Formatter}; -#[derive(Copy, Clone)] +#[derive(Copy, Clone, PartialEq)] pub struct Card { v: Vector4, } @@ -21,6 +21,11 @@ impl Card { ), } } + + pub fn is_set(a: Self, b: Self, c: Self) -> bool { + let (a, b, c) = (a.v, b.v, c.v); + a + b + c == Vector4::::zero() + } } impl Display for Card { @@ -72,6 +77,19 @@ impl CardSet { } } + pub fn contains_set(&self) -> bool { + for i in 0..(self.cards.len() - 2) { + for j in (i + 1)..(self.cards.len() - 1) { + for k in (j + 1)..(self.cards.len()) { + if Card::is_set(self.cards[i], self.cards[j], self.cards[k]) { + return true; + } + } + } + } + false + } + fn grid(&self) -> [[[[bool; 3]; 3]; 3]; 3] { let mut grid = [[[[false; 3]; 3]; 3]; 3]; for card in &self.cards { @@ -205,4 +223,55 @@ mod tests { } } } + + #[test] + fn set_stays_set() { + let mut rng = rng(); + let mut cards = CardSet::new(&[ + Card::new(0, 0, 0, 0), + Card::new(1, 1, 1, 1), + Card::new(2, 2, 2, 2), + ]); + assert!(cards.contains_set()); + + for _ in 0..1000 { + let mapping: CardMapping = rng.sample(StandardUniform); + cards = mapping.map(cards); + assert!(cards.contains_set()); + } + } + + #[test] + fn noset_stays_noset() { + let mut rng = rng(); + let mut cards = CardSet::new(&[ + Card::new(0, 0, 0, 1), + Card::new(0, 0, 1, 0), + Card::new(0, 0, 1, 2), + Card::new(0, 0, 2, 1), + Card::new(0, 1, 1, 1), + Card::new(0, 2, 0, 0), + Card::new(0, 2, 0, 2), + Card::new(0, 2, 2, 0), + Card::new(0, 2, 2, 2), + Card::new(1, 0, 1, 1), + Card::new(1, 2, 1, 1), + Card::new(2, 0, 0, 0), + Card::new(2, 0, 0, 2), + Card::new(2, 0, 2, 0), + Card::new(2, 0, 2, 2), + Card::new(2, 1, 1, 1), + Card::new(2, 2, 0, 1), + Card::new(2, 2, 1, 0), + Card::new(2, 2, 1, 2), + Card::new(2, 2, 2, 1), + ]); + assert!(!cards.contains_set()); + + for _ in 0..1000 { + let mapping: CardMapping = rng.sample(StandardUniform); + cards = mapping.map(cards); + assert!(!cards.contains_set()); + } + } }