module Wordify.Rules.Square (Square(Normal, DoubleLetter, TripleLetter, DoubleWord, TripleWord),
isOccupied, scoreWord, squareIfOccupied, putTileOn, tileIfOccupied) where
import Wordify.Rules.Tile
import Data.Sequence as Seq
import qualified Data.Foldable as F
import Data.Maybe
data Square = Normal (Maybe Tile)
| DoubleLetter (Maybe Tile)
| TripleLetter (Maybe Tile)
| DoubleWord (Maybe Tile)
| TripleWord (Maybe Tile) deriving (Show,Eq,Ord)
putTileOn :: Square -> Tile -> Square
putTileOn (Normal _) tile = Normal $ Just tile
putTileOn (DoubleLetter _) tile = DoubleLetter $ Just tile
putTileOn (TripleLetter _) tile = TripleLetter $ Just tile
putTileOn (DoubleWord _) tile = DoubleWord $ Just tile
putTileOn (TripleWord _) tile = TripleWord $ Just tile
scoreWord :: Seq Square -> Seq Square -> Int
scoreWord xs ys = addBonuses (addBonuses baseScore letterBonuses) wordBonuses
where
calcBaseScore = F.foldr (\square acc -> baseValue square + acc) 0
addBonuses = F.foldr applyWordBonus
baseScore = calcBaseScore xs + calcBaseScore ys
(wordBonuses, letterBonuses) = Seq.partition isWordBonus ys
applyWordBonus :: Square -> Int -> Int
applyWordBonus (Normal _ ) = (+0)
applyWordBonus (DoubleLetter (Just tile)) = (+ tileValue tile)
applyWordBonus (TripleLetter (Just tile)) = (+ tileValue tile * 2)
applyWordBonus (DoubleWord _) = (*2)
applyWordBonus (TripleWord _) = (*3)
applyWordBonus _ = (+0)
isWordBonus :: Square -> Bool
isWordBonus (DoubleWord _) = True
isWordBonus (TripleWord _) = True
isWordBonus _ = False
baseValue :: Square -> Int
baseValue sq = maybe 0 tileValue $ tileIfOccupied sq
squareIfOccupied :: Square -> Maybe Square
squareIfOccupied sq = tileIfOccupied sq >> Just sq
tileIfOccupied :: Square -> Maybe Tile
tileIfOccupied (Normal (Just tile)) = Just tile
tileIfOccupied (DoubleLetter (Just tile)) = Just tile
tileIfOccupied (TripleLetter (Just tile)) = Just tile
tileIfOccupied (DoubleWord (Just tile)) = Just tile
tileIfOccupied (TripleWord (Just tile)) = Just tile
tileIfOccupied _ = Nothing
isOccupied :: Square -> Bool
isOccupied = isJust . squareIfOccupied