diff options
-rw-r--r-- | src/Main.hs | 10 | ||||
-rw-r--r-- | src/Sequence/Formula.hs | 26 | ||||
-rw-r--r-- | src/Sequence/Utils.hs | 15 |
3 files changed, 43 insertions, 8 deletions
diff --git a/src/Main.hs b/src/Main.hs index 636e5ea..eeed4d9 100644 --- a/src/Main.hs +++ b/src/Main.hs | |||
@@ -99,8 +99,9 @@ main = do | |||
99 | , cmd "hit" takeHit "Damage the focused entity" | 99 | , cmd "hit" takeHit "Damage the focused entity" |
100 | , cmd "fatigue" takeFatigue "Inflict fatigue damage upon the focused entity" | 100 | , cmd "fatigue" takeFatigue "Inflict fatigue damage upon the focused entity" |
101 | , cmd "log" dumpLog "Print the combat log" | 101 | , cmd "log" dumpLog "Print the combat log" |
102 | , cmd "val" printVal "Find the distribution of a specific value of the current entities" | ||
102 | ] | 103 | ] |
103 | , wordBreakChars = wordBreakChars initialShellDescription \\ [',', '*'] | 104 | , wordBreakChars = wordBreakChars initialShellDescription \\ [','] |
104 | } | 105 | } |
105 | void $ runShell description haskelineBackend (def :: GameState) | 106 | void $ runShell description haskelineBackend (def :: GameState) |
106 | 107 | ||
@@ -336,7 +337,7 @@ doShock dmg efLens = withFocus $ \focusId -> do | |||
336 | then guard $ dmg >= reBar | 337 | then guard $ dmg >= reBar |
337 | else guard $ val >= bar | 338 | else guard $ val >= bar |
338 | lStats . efLens . seApplied .= True | 339 | lStats . efLens . seApplied .= True |
339 | (CI.original -> effectName, effect) <- view _Effect <$> (evalF . table $ cripple ^. seEffect) | 340 | Effect (CI.original -> effectName) effect <- evalF . table $ cripple ^. seEffect |
340 | lStats <~ (MaybeT . fmap join . runMaybeT $ evalF effect) | 341 | lStats <~ (MaybeT . fmap join . runMaybeT $ evalF effect) |
341 | lift $ shellPutStrLn effectName | 342 | lift $ shellPutStrLn effectName |
342 | lift . addNote $ "Effect: " ++ effectName | 343 | lift . addNote $ "Effect: " ++ effectName |
@@ -371,3 +372,8 @@ dumpLog = use gLog >>= mapMOf (each . _1) toName >>= shellPutStrLn . toTable | |||
371 | where | 372 | where |
372 | toTable :: Seq (String, String) -> String | 373 | toTable :: Seq (String, String) -> String |
373 | toTable (map (rowG . toListOf both) . toList -> table) = layoutTableToString table (Just (["Entity", "String"], [def, def])) [def, def] unicodeBoldHeaderS | 374 | toTable (map (rowG . toListOf both) . toList -> table) = layoutTableToString table (Just (["Entity", "String"], [def, def])) [def, def] unicodeBoldHeaderS |
375 | |||
376 | printVal :: Completable (Formula Stats) -> Sh GameState () | ||
377 | printVal = withArg $ \formula -> withFocus $ \focusId -> do | ||
378 | name <- toName focusId | ||
379 | shellPutStrLn . show =<< focusState (gEntities . ix focusId . eStats) (findDistribution' [name] formula) | ||
diff --git a/src/Sequence/Formula.hs b/src/Sequence/Formula.hs index a3675c6..2ac1210 100644 --- a/src/Sequence/Formula.hs +++ b/src/Sequence/Formula.hs | |||
@@ -4,6 +4,7 @@ module Sequence.Formula | |||
4 | ( FormulaM, Formula, quot' | 4 | ( FormulaM, Formula, quot' |
5 | , (:<:)(..), Context(..), ctx | 5 | , (:<:)(..), Context(..), ctx |
6 | , evalFormula, evalFormula' | 6 | , evalFormula, evalFormula' |
7 | , findDistribution, findDistribution' | ||
7 | , val | 8 | , val |
8 | , d, z | 9 | , d, z |
9 | , Table, table | 10 | , Table, table |
@@ -109,18 +110,33 @@ askQuestion promptPref input q@(Question{..}) = flip (if keepResult then set $ _ | |||
109 | sep = "»" | 110 | sep = "»" |
110 | 111 | ||
111 | evalFormula :: (MonadIO m, sInput :<: lInput) => [String] -> lInput -> FormulaM sInput a -> m (lInput, a) | 112 | evalFormula :: (MonadIO m, sInput :<: lInput) => [String] -> lInput -> FormulaM sInput a -> m (lInput, a) |
112 | evalFormula promptPref input = evalFormula' [] promptPref (input, Nothing) | 113 | evalFormula = primEvalFormula $ liftIO . enact |
114 | |||
115 | findDistribution :: (MonadIO m, sInput :<: lInput, Ord a) => [String] -> lInput -> FormulaM sInput a -> m (lInput, (Map a Rational)) | ||
116 | findDistribution = primEvalFormula $ return . fmap Map.fromList . seqEither . outcomes | ||
113 | where | 117 | where |
114 | evalFormula' :: (MonadIO m, sInput :<: lInput) => [lInput -> lInput] -> [String] -> (lInput, Maybe (Formula sInput)) -> FormulaM sInput a -> m (lInput, a) | 118 | seqEither :: [(Either q a, Rational)] -> Either q [(a, Rational)] |
115 | evalFormula' finalChanges promptPref (input, fSt) formula = do | 119 | seqEither = mapM seqEither' |
116 | result <- liftIO . enact . runExceptT . (runReaderT ?? (Context input fSt)) . (evalStateT ?? Set.empty) $ formula | 120 | |
121 | seqEither' (Left a, _) = Left a | ||
122 | seqEither' (Right b, c) = Right (b, c) | ||
123 | |||
124 | primEvalFormula :: (MonadIO m, sInput :<: lInput) => (EventM (Either (Question sInput) a) -> m (Either (Question sInput) r)) -> [String] -> lInput -> FormulaM sInput a -> m (lInput, r) | ||
125 | primEvalFormula fromOutcomes promptPref input = evalFormula' fromOutcomes [] promptPref (input, Nothing) | ||
126 | where | ||
127 | evalFormula' :: (MonadIO m, sInput :<: lInput) => (EventM (Either (Question sInput) a) -> m (Either (Question sInput) r)) -> [lInput -> lInput] -> [String] -> (lInput, Maybe (Formula sInput)) -> FormulaM sInput a -> m (lInput, r) | ||
128 | evalFormula' fromOutcomes finalChanges promptPref (input, fSt) formula = do | ||
129 | result <- fromOutcomes . runExceptT . (runReaderT ?? (Context input fSt)) . (evalStateT ?? Set.empty) $ formula | ||
117 | case result of | 130 | case result of |
118 | Left q@(Question{..}) -> askQuestion promptPref (input, fSt) q >>= flip (flip evalFormula' promptPref $ set (ctx' . answer) (throwError q) : finalChanges) formula | 131 | Left q@(Question{..}) -> askQuestion promptPref (input, fSt) q >>= flip (flip (evalFormula' fromOutcomes) promptPref $ set (ctx' . answer) (throwError q) : finalChanges) formula |
119 | Right result -> return (foldr ($) input finalChanges, result) | 132 | Right result -> return (foldr ($) input finalChanges, result) |
120 | 133 | ||
121 | evalFormula' :: (MonadIO m, sInput :<: lInput, MonadState lInput m) => [String] -> FormulaM sInput a -> m a | 134 | evalFormula' :: (MonadIO m, sInput :<: lInput, MonadState lInput m) => [String] -> FormulaM sInput a -> m a |
122 | evalFormula' promptPref formula = uncurry (<$) . over _2 put . swap =<< flip (evalFormula promptPref) formula =<< get | 135 | evalFormula' promptPref formula = uncurry (<$) . over _2 put . swap =<< flip (evalFormula promptPref) formula =<< get |
123 | 136 | ||
137 | findDistribution' :: (MonadIO m, sInput :<: lInput, MonadState lInput m, Ord a) => [String] -> FormulaM sInput a -> m (Map a Rational) | ||
138 | findDistribution' promptPref formula = uncurry (<$) . over _2 put . swap =<< flip (findDistribution promptPref) formula =<< get | ||
139 | |||
124 | val :: Traversal' input (Formula input) -> [String] -> Bool -> Formula input | 140 | val :: Traversal' input (Formula input) -> [String] -> Bool -> Formula input |
125 | val answer prompt keepResult = do | 141 | val answer prompt keepResult = do |
126 | gets (Set.member prompt) >>= bool (modify $ Set.insert prompt) (modify (Set.delete prompt) >> throwError Question{..}) | 142 | gets (Set.member prompt) >>= bool (modify $ Set.insert prompt) (modify (Set.delete prompt) >> throwError Question{..}) |
diff --git a/src/Sequence/Utils.hs b/src/Sequence/Utils.hs index 929189e..ba6ce95 100644 --- a/src/Sequence/Utils.hs +++ b/src/Sequence/Utils.hs | |||
@@ -1,4 +1,4 @@ | |||
1 | {-# LANGUAGE ViewPatterns, FlexibleContexts, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, UndecidableInstances, OverloadedStrings, RankNTypes #-} | 1 | {-# LANGUAGE ViewPatterns, FlexibleContexts, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, UndecidableInstances, OverloadedStrings, OverloadedLists, RankNTypes #-} |
2 | 2 | ||
3 | module Sequence.Utils | 3 | module Sequence.Utils |
4 | ( withArg, withFocus, withFocus' | 4 | ( withArg, withFocus, withFocus' |
@@ -140,3 +140,16 @@ instance Argument DamageType GameState where | |||
140 | arg (CI.mk -> word) = return $ Map.lookup word types | 140 | arg (CI.mk -> word) = return $ Map.lookup word types |
141 | where | 141 | where |
142 | types = Map.fromList [(CI.mk $ show dType, dType) | dType <- [minBound .. maxBound]] | 142 | types = Map.fromList [(CI.mk $ show dType, dType) | dType <- [minBound .. maxBound]] |
143 | |||
144 | instance Completion (Formula Stats) GameState where | ||
145 | completableLabel _ = "<value>" | ||
146 | complete _ st (CI.foldCase -> prefix) = return . map CI.original . filter ((prefix `isPrefixOf`) . CI.foldedCase) . Map.keys $ Map.filter (isJust . (\a -> preview (gFocus' . eStats . folding a) st)) statAccessors | ||
147 | |||
148 | instance Argument (Formula Stats) GameState where | ||
149 | arg (CI.mk -> name) = runMaybeT $ do | ||
150 | accessor <- MaybeT . return $ Map.lookup name statAccessors | ||
151 | MaybeT . preuse $ gFocus' . eStats . folding accessor | ||
152 | |||
153 | statAccessors :: Map (CI String) (Stats -> Maybe (Formula Stats)) | ||
154 | statAccessors = [ | ||
155 | ] | ||