diff options
Diffstat (limited to 'src/Sequence')
| -rw-r--r-- | src/Sequence/Types.hs | 101 | ||||
| -rw-r--r-- | src/Sequence/Utils.hs | 46 |
2 files changed, 147 insertions, 0 deletions
diff --git a/src/Sequence/Types.hs b/src/Sequence/Types.hs new file mode 100644 index 0000000..afe1060 --- /dev/null +++ b/src/Sequence/Types.hs | |||
| @@ -0,0 +1,101 @@ | |||
| 1 | {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, TypeSynonymInstances, ViewPatterns, OverloadedStrings, TemplateHaskell, GeneralizedNewtypeDeriving #-} | ||
| 2 | |||
| 3 | module Sequence.Types | ||
| 4 | ( GameState(..), gEntities, gEntityNames | ||
| 5 | , Faction, faction, faction' | ||
| 6 | , SeqVal(..), seqVal | ||
| 7 | , Entity(..), eFaction, eSeqVal | ||
| 8 | , EntityName(..), entityName | ||
| 9 | , EntityIdentifier(..), entityId | ||
| 10 | , inhabitedFactions, priorityQueue | ||
| 11 | ) where | ||
| 12 | |||
| 13 | import Control.Lens | ||
| 14 | |||
| 15 | import System.Console.Shell | ||
| 16 | |||
| 17 | import Data.Default | ||
| 18 | import Data.CaseInsensitive (CI) | ||
| 19 | import qualified Data.CaseInsensitive as CI | ||
| 20 | |||
| 21 | import Data.Map.Strict (Map) | ||
| 22 | import qualified Data.Map.Strict as Map | ||
| 23 | |||
| 24 | import Data.Bimap (Bimap) | ||
| 25 | import qualified Data.Bimap as Bimap | ||
| 26 | |||
| 27 | import Data.List | ||
| 28 | import Data.Maybe | ||
| 29 | import Data.Tuple | ||
| 30 | import Data.Ord | ||
| 31 | |||
| 32 | |||
| 33 | newtype Faction = Faction { _lFaction :: Maybe (CI String) } | ||
| 34 | deriving (Show, Eq, Ord) | ||
| 35 | makeLenses ''Faction | ||
| 36 | |||
| 37 | instance Default Faction where | ||
| 38 | def = Faction Nothing | ||
| 39 | |||
| 40 | unaligned :: CI String | ||
| 41 | unaligned = "Unaligned" | ||
| 42 | |||
| 43 | faction :: Getter Faction (Maybe (CI String)) | ||
| 44 | faction = lFaction | ||
| 45 | |||
| 46 | faction' :: Lens' Faction String | ||
| 47 | faction' = lens (CI.original . fromMaybe unaligned . view faction) (\s a -> s { _lFaction = parseFaction a }) | ||
| 48 | where | ||
| 49 | parseFaction str@(CI.mk -> str') | ||
| 50 | | str' == unaligned = Nothing | ||
| 51 | | null str = Nothing | ||
| 52 | | otherwise = Just str' | ||
| 53 | |||
| 54 | |||
| 55 | newtype SeqVal = SeqVal { _seqVal :: Integer } | ||
| 56 | deriving (Show, Ord, Eq, Num, Integral, Enum, Real) | ||
| 57 | makeLenses ''SeqVal | ||
| 58 | |||
| 59 | |||
| 60 | data Entity = Entity | ||
| 61 | { _eFaction :: Faction | ||
| 62 | , _eSeqVal :: Maybe SeqVal | ||
| 63 | } | ||
| 64 | deriving (Show) | ||
| 65 | makeLenses ''Entity | ||
| 66 | |||
| 67 | instance Default Entity where | ||
| 68 | def = Entity | ||
| 69 | { _eFaction = def | ||
| 70 | , _eSeqVal = def | ||
| 71 | } | ||
| 72 | |||
| 73 | newtype EntityName = EntityName { _entityName :: CI String } | ||
| 74 | deriving (Show, Eq, Ord) | ||
| 75 | makeLenses ''EntityName | ||
| 76 | |||
| 77 | newtype EntityIdentifier = EntityIdentifier { _entityId :: Integer } | ||
| 78 | deriving (Show, Eq, Ord) | ||
| 79 | makeLenses ''EntityIdentifier | ||
| 80 | |||
| 81 | data GameState = GameState | ||
| 82 | { _gEntities :: Map EntityIdentifier Entity | ||
| 83 | , _gEntityNames :: Bimap EntityIdentifier EntityName | ||
| 84 | } | ||
| 85 | makeLenses ''GameState | ||
| 86 | |||
| 87 | instance Default GameState where | ||
| 88 | def = GameState | ||
| 89 | { _gEntities = def | ||
| 90 | , _gEntityNames = Bimap.empty | ||
| 91 | } | ||
| 92 | |||
| 93 | inhabitedFactions :: Getter GameState [Faction] | ||
| 94 | inhabitedFactions = to $ nub . sort . Map.elems . fmap (view eFaction) . view gEntities | ||
| 95 | |||
| 96 | priorityQueue :: Getter GameState [(SeqVal, EntityIdentifier)] | ||
| 97 | priorityQueue = to priorityQueue' | ||
| 98 | where | ||
| 99 | priorityQueue' (Map.toAscList . view gEntities -> entities) = sortBy (comparing $ Down . snd) . concat . map filter . map (over _1 $ view eSeqVal) . map swap $ entities | ||
| 100 | filter (Nothing, _) = mempty | ||
| 101 | filter (Just val, id) = pure (val, id) | ||
diff --git a/src/Sequence/Utils.hs b/src/Sequence/Utils.hs new file mode 100644 index 0000000..7d28b83 --- /dev/null +++ b/src/Sequence/Utils.hs | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | {-# LANGUAGE ViewPatterns, FlexibleContexts, MultiParamTypeClasses #-} | ||
| 2 | |||
| 3 | module Sequence.Utils | ||
| 4 | ( toName, fromName | ||
| 5 | ) where | ||
| 6 | |||
| 7 | import Sequence.Types | ||
| 8 | |||
| 9 | import Control.Monad.State.Strict | ||
| 10 | |||
| 11 | import Control.Lens | ||
| 12 | |||
| 13 | import Data.Bimap (Bimap) | ||
| 14 | import qualified Data.Bimap as Bimap | ||
| 15 | |||
| 16 | import Data.CaseInsensitive (CI) | ||
| 17 | import qualified Data.CaseInsensitive as CI | ||
| 18 | |||
| 19 | import Data.Map.Strict (Map) | ||
| 20 | import qualified Data.Map.Strict as Map | ||
| 21 | |||
| 22 | import Data.Function | ||
| 23 | import Data.Default | ||
| 24 | import Data.Maybe | ||
| 25 | import Text.Read | ||
| 26 | |||
| 27 | import Data.List | ||
| 28 | |||
| 29 | import System.Console.Shell | ||
| 30 | |||
| 31 | unaligned = view faction' def | ||
| 32 | |||
| 33 | toName :: MonadState GameState m => EntityIdentifier -> m String | ||
| 34 | toName id = fromMaybe (show $ id ^. entityId) . fmap (CI.original . view entityName) . Bimap.lookup id <$> use gEntityNames | ||
| 35 | |||
| 36 | fromName :: MonadState GameState m => String -> m (Maybe EntityIdentifier) | ||
| 37 | fromName (readMaybe -> n@(Just _)) = return $ EntityIdentifier <$> n | ||
| 38 | fromName (EntityName . CI.mk -> name) = Bimap.lookupR name <$> use gEntityNames | ||
| 39 | |||
| 40 | instance Completion EntityIdentifier GameState where | ||
| 41 | completableLabel _ = "<entity>" | ||
| 42 | complete _ st prefix = return . filter ((isPrefixOf `on` CI.foldCase) prefix) . map ((evalState ?? st) . toName) . Map.keys $ st ^. gEntities | ||
| 43 | |||
| 44 | instance Completion Faction GameState where | ||
| 45 | completableLabel _ = "<faction>" | ||
| 46 | complete _ st prefix = return . filter ((isPrefixOf `on` CI.foldCase) prefix) . nub . sort $ unaligned : map (view faction') (st ^. inhabitedFactions) | ||
