diff options
author | Gregor Kleen <gkleen@yggdrasil.li> | 2016-06-02 23:29:36 +0200 |
---|---|---|
committer | Gregor Kleen <gkleen@yggdrasil.li> | 2016-06-02 23:29:36 +0200 |
commit | 1b7f21ba636e4034f76495deafd0ac6ca9758a4e (patch) | |
tree | f8cdffa91a9c6643df51d851d367de0daafb6d5d /src/Sequence | |
parent | e4fe9710287960438856fa78b697ccae64b7e2eb (diff) | |
download | 2017-01-16_17:13:37-1b7f21ba636e4034f76495deafd0ac6ca9758a4e.tar 2017-01-16_17:13:37-1b7f21ba636e4034f76495deafd0ac6ca9758a4e.tar.gz 2017-01-16_17:13:37-1b7f21ba636e4034f76495deafd0ac6ca9758a4e.tar.bz2 2017-01-16_17:13:37-1b7f21ba636e4034f76495deafd0ac6ca9758a4e.tar.xz 2017-01-16_17:13:37-1b7f21ba636e4034f76495deafd0ac6ca9758a4e.zip |
rudimentary state
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) | ||