summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Main.hs10
-rw-r--r--src/Sequence/Formula.hs26
-rw-r--r--src/Sequence/Utils.hs15
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
376printVal :: Completable (Formula Stats) -> Sh GameState ()
377printVal = 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
111evalFormula :: (MonadIO m, sInput :<: lInput) => [String] -> lInput -> FormulaM sInput a -> m (lInput, a) 112evalFormula :: (MonadIO m, sInput :<: lInput) => [String] -> lInput -> FormulaM sInput a -> m (lInput, a)
112evalFormula promptPref input = evalFormula' [] promptPref (input, Nothing) 113evalFormula = primEvalFormula $ liftIO . enact
114
115findDistribution :: (MonadIO m, sInput :<: lInput, Ord a) => [String] -> lInput -> FormulaM sInput a -> m (lInput, (Map a Rational))
116findDistribution = 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
124primEvalFormula :: (MonadIO m, sInput :<: lInput) => (EventM (Either (Question sInput) a) -> m (Either (Question sInput) r)) -> [String] -> lInput -> FormulaM sInput a -> m (lInput, r)
125primEvalFormula 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
121evalFormula' :: (MonadIO m, sInput :<: lInput, MonadState lInput m) => [String] -> FormulaM sInput a -> m a 134evalFormula' :: (MonadIO m, sInput :<: lInput, MonadState lInput m) => [String] -> FormulaM sInput a -> m a
122evalFormula' promptPref formula = uncurry (<$) . over _2 put . swap =<< flip (evalFormula promptPref) formula =<< get 135evalFormula' promptPref formula = uncurry (<$) . over _2 put . swap =<< flip (evalFormula promptPref) formula =<< get
123 136
137findDistribution' :: (MonadIO m, sInput :<: lInput, MonadState lInput m, Ord a) => [String] -> FormulaM sInput a -> m (Map a Rational)
138findDistribution' promptPref formula = uncurry (<$) . over _2 put . swap =<< flip (findDistribution promptPref) formula =<< get
139
124val :: Traversal' input (Formula input) -> [String] -> Bool -> Formula input 140val :: Traversal' input (Formula input) -> [String] -> Bool -> Formula input
125val answer prompt keepResult = do 141val 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
3module Sequence.Utils 3module 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
144instance 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
148instance 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
153statAccessors :: Map (CI String) (Stats -> Maybe (Formula Stats))
154statAccessors = [
155 ]