lib/CCard.hs

87 lines
2.1 KiB
Haskell

module CCard where
import Data.Word (Word64)
import Data.Bits (setBit, (.|.), (.&.), shift, xor, testBit)
import System.Random (randomRIO)
data Flower =
Pine
| Plum
| Cherry
| Wisteria
| Iris
| Peony
| BushClover
| SusukiGrass
| Chrysanthemum
| Maple
| Willow
| Paulownia
deriving (Eq, Ord, Enum, Show)
data Card =
Pine0 | Pine1 | PinePoetry | Crane
| Plum0 | Plum1 | PlumPoetry | BushWarbler
| Cherry0 | Cherry1 | CherryPoetry | CampCurtain
| Wisteria0 | Wisteria1 | WisteriaRed | Cuckoo
| Iris0 | Iris1 | IrisRed | EightPlankBridge
| Peony0 | Peony1 | PeonyBlue | Butterflies
| BushClover0 | BushClover1 | BushCloverRed | Boar
| SusukiGrass0 | SusukiGrass1 | Geese | FullMoon
| Chrysanthemum0 | Chrysanthemum1 | ChrysanthemumBlue | SakeCup
| Maple0 | Maple1 | MapleBlue | Deer
| Lightning | WillowRed | Swallow | RainMan
| Paulownia0 | Paulownia1 | Sand | Phoenix
deriving (Eq, Ord, Enum, Show)
type Pack = Word64
flower :: Card -> Flower
flower = toEnum . (`div` 4) . fromEnum
set :: [Card] -> Pack
set = foldl setBit 0 . map fromEnum
contains :: Pack -> Card -> Bool
contains pack = testBit pack . fromEnum
inoshikacho :: Pack
inoshikacho = set [Butterflies, Boar, Deer]
animals :: Pack
animals = set [BushWarbler, Cuckoo, EightPlankBridge, Geese, SakeCup, Swallow] .|. inoshikacho
blue :: Pack
blue = set [PeonyBlue, ChrysanthemumBlue, MapleBlue]
poetry :: Pack
poetry = set [PinePoetry, PlumPoetry, CherryPoetry]
ribbons = set [WisteriaRed, IrisRed, BushCloverRed, WillowRed] .|. blue .|. poetry
lights :: Pack
lights = set [Crane, CampCurtain, FullMoon, RainMan, Phoenix]
plain :: Pack
plain = pack `xor` (lights .|. ribbons .|. animals) .&. pack
pack :: Pack
pack = 1 `shift` (fromEnum Phoenix + 1) - 1
pair :: Card -> Card -> Bool
pair card1 card2 = flower card1 == flower card2
cards :: [Card]
cards = [Pine0 .. Phoenix]
shuffle :: [a] -> IO [a]
shuffle l =
aux (length l) l
where
aux n [] = return []
aux n (h:t) = do
cut <- randomRIO (0, n-1)
shuffled <- shuffle t
let (top, bottom) = splitAt cut shuffled
return $ top ++ h : bottom