module Set.Card
(
Card(..),
Color(..),
Count(..),
Shading(..),
Symbol(..),
allCards,
validSet,
solve
) where
import Data.List (tails)
import Set.Utils
data Color = Red | Purple | Green
deriving (Show, Eq, Ord)
data Count = One | Two | Three
deriving (Show, Eq, Ord)
data Shading = Open | Striped | Solid
deriving (Show, Eq, Ord)
data Symbol = Diamond | Squiggle | Oval
deriving (Show, Eq, Ord)
data Card = Card { color :: Color
, count :: Count
, shading :: Shading
, symbol :: Symbol
}
deriving (Show, Eq)
checkAttribute :: Eq a => [a] -> Bool
checkAttribute xs = all (uncurry (==)) combos
|| all (uncurry (/=)) combos
where
combos = chooseTwo xs
validSet :: Card -> Card -> Card -> Bool
validSet card1 card2 card3
= checkAttribute (map color cards)
&& checkAttribute (map count cards)
&& checkAttribute (map shading cards)
&& checkAttribute (map symbol cards)
where
cards = [card1, card2, card3]
allCards :: [Card]
allCards = [Card a b c d | a <- [Red, Purple, Green]
, b <- [One, Two, Three]
, c <- [Open, Striped, Solid]
, d <- [Diamond, Squiggle, Oval]]
solve :: [Card] -> [(Card,Card,Card)]
solve xs = [(a,b,c) | (a:as) <- tails xs
, (b:bs) <- tails as
, c <- bs
, validSet a b c]