packages feed

unscramble-0.2: Unscramble/Score.hs

module Unscramble.Score (
    ScoringSystem(..),
    score
) where

import Control.Lens
import qualified Data.HashMap as H
import Data.Maybe
import Unscramble.Types

score :: ScoringSystem -> [Coordinate] -> Search Int
score Boggle = scoreBoggle
score SWF = scoreSWF
score WordWars = scoreWordWars

scoreBoggle :: [Coordinate] -> Search Int
scoreBoggle xs = return $ case length xs of
    3 -> 1
    4 -> 1
    5 -> 2
    6 -> 3
    7 -> 5
    x | x >= 8 -> 11
    _ -> 0

scoreWordWars :: [Coordinate] -> Search Int
scoreWordWars xs = do
    g <- view (grid.coords)
    let lets = map (\x -> H.findWithDefault undefined x g) xs
    return . sum . map (\x -> fromMaybe 0 $ lookup x scores) $ lets
    where
        scores = [ ("a", 1), ("b", 4), ("c", 3), ("d", 2)
                 , ("e", 1), ("f", 2), ("g", 3), ("h", 3)
                 , ("i", 1), ("j", 6), ("k", 5), ("l", 2)
                 , ("m", 4), ("n", 2), ("o", 1), ("p", 4)
                 , ("qu", 8), ("r", 1), ("s", 1), ("t", 1)
                 , ("u", 3), ("v", 4), ("w", 4), ("x", 8)
                 , ("y", 2), ("z", 8) ]
        
scoreSWF :: [Coordinate] -> Search Int
scoreSWF cs = if length cs == 2
    then return 1
    else do
        (Multiplier dl dw tl tw) <- view mult
        (Grid _ gs) <- view grid
        let dwm = case dw of
                      Nothing -> id
                      Just r -> if r `elem` cs then (*2) else id
            twm = case tw of
                      Nothing -> id
                      Just r -> if r `elem` cs then (*3) else id
            scoreOf n = dlm . tlm $ baseScore n
                where
                    baseScore q = fromJust $ H.lookup q gs >>= (`lookup` scores)
                    dlm = if n `elem` dl then (*2) else id
                    tlm = if n `elem` tl then (*3) else id
                    
        return . (+ lengthBonus (length cs)) . dwm . twm . sum
               $ map scoreOf cs
    where
        scores = [ ("a", 1), ("b", 4), ("c", 4), ("d", 2)
                 , ("e", 1), ("f", 4), ("g", 3), ("h", 3)
                 , ("i", 1), ("j", 10), ("k", 5), ("l", 2)
                 , ("m", 4), ("n", 2), ("o", 1), ("p", 4)
                 , ("qu", 10), ("r", 1), ("s", 1), ("t", 1)
                 , ("u", 2), ("v", 5), ("w", 4), ("x", 8)
                 , ("y", 3), ("z", 10) ]
        lengthBonus 5 = 3
        lengthBonus 6 = 6
        lengthBonus 7 = 10
        lengthBonus 8 = 15
        lengthBonus 9 = 20
        lengthBonus x | x >= 10 = 25
        lengthBonus _ = 0