module KoiKoi where import CCard import Data.Bits (popCount, (.&.)) type Points = Int data Player = Player { hand :: Pack , captured :: Pack , scored :: [Yaku] } data State = State { players :: (Player, Player) , river :: Pack , deck :: [ Card ] , month :: Flower , turn :: Bool } data Yaku = Goko | Shiko | AmeShiko | Sanko | InoShikaCho | Tane | Akatan | Aotan | Tan | Kasu | TsukimiZake | HanamiZake yakus :: [ Pack -> Maybe (Yaku, Points) ] yakus = [ (\p -> lightsYaku (popCount p) (p `contains` RainMan)) . (lights .&.) , is inoshikacho InoShikaCho , moreThan 4 animals Tane , is poetry Akatan , is blue Aotan , moreThan 4 ribbons Tan , moreThan 9 plain Kasu , is (set [SakeCup, FullMoon]) TsukimiZake , is (set [SakeCup, CampCurtain]) HanamiZake ] where lightsYaku 5 _ = Just (Goko, 10) lightsYaku 4 hasRainMan = if hasRainMan then Just (AmeShiko, 7) else Just (Shiko, 8) lightsYaku n hasRainMan = if not hasRainMan && n > 2 then Just (Sanko, 8) else Nothing moreThan points set yaku = threshold yaku . (\x -> x - points) . popCount . (set .&.) threshold yaku n | n > 0 = Just (yaku, n) | otherwise = Nothing is set yaku pack = if set == pack then Just (yaku, 5) else Nothing