Skip to content

Commit

Permalink
Capability exercise cost
Browse files Browse the repository at this point in the history
  • Loading branch information
kostmo committed Feb 29, 2024
1 parent 0d65a04 commit 01ac86a
Show file tree
Hide file tree
Showing 29 changed files with 524 additions and 111 deletions.
3 changes: 1 addition & 2 deletions app/doc/Swarm/Doc/Schema/Render.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import Swarm.Doc.Schema.Arrangement
import Swarm.Doc.Schema.Parse
import Swarm.Doc.Schema.Refined
import Swarm.Doc.Schema.SchemaType
import Swarm.Doc.Util
import Swarm.Doc.Wiki.Util
import Swarm.Util (applyWhen, brackets, quote, showT)
import System.Directory (listDirectory)
Expand Down Expand Up @@ -77,7 +76,7 @@ makePandocTable titleMap (SchemaData _ (ToplevelSchema theTitle theDescription _
ItemList xs ->
makePropsTable False listColumnHeadings titleMap
. M.fromList
$ zip (map tshow [0 :: Int ..]) xs
$ zip (map showT [0 :: Int ..]) xs

mkTable x = doc $ case x of
ObjectProperties props -> makePropsTable True propertyColumnHeadings titleMap props
Expand Down
27 changes: 14 additions & 13 deletions app/doc/Swarm/Doc/Wiki/Cheatsheet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,19 @@ module Swarm.Doc.Wiki.Cheatsheet (
import Control.Effect.Lift
import Control.Lens (view, (^.))
import Control.Lens.Combinators (to)
import Data.Set qualified as S
import Data.Foldable (find, toList)
import Data.List (transpose)
import Data.Map.Lazy qualified as Map
import Data.Maybe (fromMaybe, isJust)
import Data.Set qualified as Set
import Data.Maybe (isJust)
import Data.Text (Text)
import Data.Text qualified as T
import Data.Text.IO qualified as T
import Swarm.Doc.Schema.Render
import Swarm.Doc.Util
import Swarm.Doc.Wiki.Matrix
import Swarm.Doc.Wiki.Util
import Swarm.Game.Device qualified as D
import Swarm.Game.Display (displayChar)
import Swarm.Game.Entity (Entity, EntityMap (entitiesByName), entityDisplay, entityName, loadEntities)
import Swarm.Game.Entity qualified as E
Expand All @@ -38,7 +39,7 @@ import Swarm.Language.Syntax (Const (..))
import Swarm.Language.Syntax qualified as Syntax
import Swarm.Language.Text.Markdown as Markdown (docToMark)
import Swarm.Language.Typecheck (inferConst)
import Swarm.Util (listEnums)
import Swarm.Util (listEnums, showT)
import Swarm.Util.Effect (simpleErrorHandle)

-- * Types
Expand Down Expand Up @@ -106,7 +107,7 @@ commandToList :: Const -> [Text]
commandToList c =
map
escapeTable
[ addLink ("#" <> tshow c) . codeQuote $ constSyntax c
[ addLink ("#" <> showT c) . codeQuote $ constSyntax c
, codeQuote . prettyTextLine $ inferConst c
, maybe "" Capability.capabilityName $ Capability.constCaps c
, Syntax.briefDoc . Syntax.constDoc $ Syntax.constInfo c
Expand Down Expand Up @@ -168,13 +169,13 @@ capabilityRow PageAddress {..} em cap =
linkCommand c =
( if T.null commandsAddress
then id
else addLink (commandsAddress <> "#" <> tshow c)
else addLink (commandsAddress <> "#" <> showT c)
)
. codeQuote
$ constSyntax c

cs = [c | c <- Syntax.allConst, let mcap = Capability.constCaps c, isJust $ find (== cap) mcap]
es = fromMaybe [] $ E.entitiesByCap em Map.!? cap
es = E.devicesForCap cap em

capabilityTable :: PageAddress -> EntityMap -> [Capability] -> Text
capabilityTable a em cs = T.unlines $ header <> map (listToRow mw) capabilityRows
Expand All @@ -197,8 +198,8 @@ entityToList e =
escapeTable
[ codeQuote . T.singleton $ e ^. entityDisplay . to displayChar
, addLink ("#" <> linkID) $ view entityName e
, T.intercalate ", " $ Capability.capabilityName <$> Set.toList (view E.entityCapabilities e)
, T.intercalate ", " . map tshow . filter (/= E.Pickable) $ toList props
, T.intercalate ", " $ Capability.capabilityName <$> Map.keys (D.getMap $ view E.entityCapabilities e)
, T.intercalate ", " . map showT . filter (/= E.Pickable) $ toList props
, if E.Pickable `elem` props
then ":heavy_check_mark:"
else ":negative_squared_cross_mark:"
Expand All @@ -221,13 +222,13 @@ entityToSection e =
, ""
, " - Char: " <> (codeQuote . T.singleton $ e ^. entityDisplay . to displayChar)
]
<> [" - Properties: " <> T.intercalate ", " (map tshow $ toList props) | not $ null props]
<> [" - Properties: " <> T.intercalate ", " (map showT $ toList props) | not $ null props]
<> [" - Capabilities: " <> T.intercalate ", " (Capability.capabilityName <$> caps) | not $ null caps]
<> ["\n"]
<> [Markdown.docToMark $ view E.entityDescription e]
where
props = view E.entityProperties e
caps = Set.toList $ view E.entityCapabilities e
caps = S.toList $ D.getCapabilitySet $ view E.entityCapabilities e

entitiesPage :: PageAddress -> [Entity] -> Text
entitiesPage _a es =
Expand All @@ -251,11 +252,11 @@ recipeRow PageAddress {..} r =
[ T.intercalate ", " (map formatCE $ view recipeInputs r)
, T.intercalate ", " (map formatCE $ view recipeOutputs r)
, T.intercalate ", " (map formatCE $ view recipeCatalysts r)
, tshow $ view recipeTime r
, tshow $ view recipeWeight r
, showT $ view recipeTime r
, showT $ view recipeWeight r
]
where
formatCE (c, e) = T.unwords [tshow c, linkEntity $ view entityName e]
formatCE (c, e) = T.unwords [showT c, linkEntity $ view entityName e]
linkEntity t =
if T.null entityAddress
then t
Expand Down
1 change: 1 addition & 0 deletions data/scenarios/Testing/00-ORDER.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,4 @@ Achievements
1634-message-colors.yaml
1681-pushable-entity.yaml
1747-volume-command.yaml
1777-capability-cost.yaml
86 changes: 86 additions & 0 deletions data/scenarios/Testing/1777-capability-cost.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
version: 1
name: Capability cost
description: |
Consume inventory by exercising device capabilities
creative: false
seed: 0
objectives:
- goal:
- |
Eliminate the `packing peanut`{=entity}s
condition: |
judge <- robotnamed "judge";
as judge {
dist <- sniff "packing peanut";
return $ dist < 0;
}
solution: |
move;
turn right;
move;
place "packing peanut";
ignite down;
move;
move;
ignite forward;
robots:
- name: base
dir: east
devices:
- treads
- logger
- Zippo
- grabber
inventory:
- [2, lighter fluid]
- [1, packing peanut]
- name: judge
dir: east
system: true
entities:
- name: lighter fluid
display:
char: 'f'
description:
- Fuel for a Zippo
properties: [known, pickable]
- name: Zippo
display:
char: 'z'
description:
- Ignites things
properties: [known, pickable]
capabilities:
- capability: ignite
cost:
- [1, "lighter fluid"]
- name: packing peanut
display:
attr: snow
char: 's'
description:
- Easy to drop, but impossible to pick up.
- Highly combustible.
properties: [known, combustible]
combustion:
ignition: 0.5
duration: [10, 20]
product: ash
known: [water, ash]
world:
dsl: |
{water}
palette:
'B': [grass, erase, base]
'j': [grass, erase, judge]
'.': [grass, erase]
'c': [grass, packing peanut]
upperleft: [-1, 1]
map: |
......
Bcccc.
.j....
.cccc.
......
.cccc.
......
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
version: 1
name: Capability cost - bad entity reference
description: |
Capability cost recipe for 'ignite' in `Zippo`{=entity}
references a non-existent entity
creative: false
robots:
- name: base
dir: east
devices:
- Zippo
entities:
- name: heavier fluid
display:
char: 'f'
description:
- Fuel for a Zippo
properties: [known, pickable]
- name: Zippo
display:
char: 'z'
description:
- Ignites things
properties: [known, pickable]
capabilities:
- capability: ignite
cost:
- [1, "lighter fluid"]
known: []
world:
dsl: |
{grass}
palette:
'B': [grass, null, base]
'.': [grass]
upperleft: [-1, 1]
map: |
..
B.
20 changes: 19 additions & 1 deletion data/schema/entity.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,25 @@
"default": [],
"type": "array",
"items": {
"type": "string"
"oneOf": [
{
"type": "string"
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"capability": {
"description": "Capability name",
"type": "string"
},
"cost": {
"$ref": "inventory.json",
"description": "A list of ingredients consumed by the command."
}
}
}
]
},
"description": "A list of capabilities provided by entity, when it is equipped as a device. See [Capabilities](https://github.com/swarm-game/swarm/wiki/Capabilities-cheat-sheet)."
}
Expand Down
3 changes: 0 additions & 3 deletions src/Swarm/Doc/Util.hs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ codeQuote = wrap '`'
addLink :: Text -> Text -> Text
addLink l t = T.concat ["[", t, "](", l, ")"]

tshow :: (Show a) => a -> Text
tshow = T.pack . show

-- * Common symbols

operators :: [Const]
Expand Down
4 changes: 2 additions & 2 deletions src/Swarm/TUI/Controller.hs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ import Swarm.Game.State.Robot
import Swarm.Game.State.Runtime
import Swarm.Game.State.Substate
import Swarm.Game.Step (finishGameTick, gameTick)
import Swarm.Language.Capability (Capability (CDebug, CGod, CMake), constCaps)
import Swarm.Language.Capability (Capability (CGod, CMake), constCaps)
import Swarm.Language.Context
import Swarm.Language.Key (KeyCombo, mkKeyCombo)
import Swarm.Language.Module
Expand Down Expand Up @@ -307,7 +307,7 @@ handleMainEvent ev = do
let isRunning = maybe True isRunningModal mt
let isPaused = s ^. gameState . temporal . paused
let isCreative = s ^. gameState . creativeMode
let hasDebug = fromMaybe isCreative $ s ^? gameState . to focusedRobot . _Just . robotCapabilities . Lens.contains CDebug
let hasDebug = hasDebugCapability isCreative s
case ev of
AppEvent ae -> case ae of
Frame
Expand Down
9 changes: 9 additions & 0 deletions src/Swarm/TUI/Controller/Util.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ import Control.Lens
import Control.Monad (forM_, unless)
import Control.Monad.IO.Class (liftIO)
import Data.Map qualified as M
import Data.Set qualified as S
import Graphics.Vty qualified as V
import Swarm.Game.Device
import Swarm.Game.Robot (robotCapabilities)
import Swarm.Game.State
import Swarm.Game.State.Landscape
import Swarm.Game.State.Robot
import Swarm.Game.State.Substate
import Swarm.Game.Universe
import Swarm.Game.World qualified as W
import Swarm.Language.Capability (Capability (CDebug))
import Swarm.TUI.Model
import Swarm.TUI.Model.UI
import Swarm.TUI.View.Util (generateModal)
Expand Down Expand Up @@ -97,3 +101,8 @@ mouseLocToWorldCoords (Brick.Location mouseLoc) = do
mx = snd mouseLoc' + fst regionStart
my = fst mouseLoc' + snd regionStart
in pure . Just $ Cosmic (region ^. subworld) $ W.Coords (mx, my)

hasDebugCapability :: Bool -> AppState -> Bool
hasDebugCapability isCreative s =
maybe isCreative (S.member CDebug . getCapabilitySet) $
s ^? gameState . to focusedRobot . _Just . robotCapabilities
1 change: 1 addition & 0 deletions src/Swarm/TUI/Model.hs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ import GitHash (GitInfo)
import Graphics.Vty (ColorMode (..))
import Network.Wai.Handler.Warp (Port)
import Swarm.Game.Entity as E
import Swarm.Game.Ingredients
import Swarm.Game.Robot
import Swarm.Game.Robot.Concrete
import Swarm.Game.Robot.Context
Expand Down
1 change: 1 addition & 0 deletions src/Swarm/TUI/Model/Menu.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Data.Text (Text)
import Data.Vector qualified as V
import Swarm.Game.Achievement.Definitions
import Swarm.Game.Entity as E
import Swarm.Game.Ingredients
import Swarm.Game.ScenarioInfo (
ScenarioCollection,
ScenarioInfo (..),
Expand Down
11 changes: 7 additions & 4 deletions src/Swarm/TUI/View.hs
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,10 @@ import Network.Wai.Handler.Warp (Port)
import Numeric (showFFloat)
import Swarm.Constant
import Swarm.Game.CESK (CESK (..))
import Swarm.Game.Device (getMap)
import Swarm.Game.Display
import Swarm.Game.Entity as E
import Swarm.Game.Ingredients
import Swarm.Game.Location
import Swarm.Game.Recipe
import Swarm.Game.Robot
Expand Down Expand Up @@ -120,6 +122,7 @@ import Swarm.Language.Typecheck (inferConst)
import Swarm.Log
import Swarm.TUI.Border
import Swarm.TUI.Controller (ticksPerFrameCap)
import Swarm.TUI.Controller.Util (hasDebugCapability)
import Swarm.TUI.Editor.Model
import Swarm.TUI.Editor.View qualified as EV
import Swarm.TUI.Inventory.Sorting (renderSortMethod)
Expand Down Expand Up @@ -993,7 +996,7 @@ drawKeyMenu s =

isReplWorking = s ^. gameState . gameControls . replWorking
isPaused = s ^. gameState . temporal . paused
hasDebug = fromMaybe creative $ s ^? gameState . to focusedRobot . _Just . robotCapabilities . Lens.contains CDebug
hasDebug = hasDebugCapability creative s
viewingBase = (s ^. gameState . robotInfo . viewCenterRule) == VCRobot 0
creative = s ^. gameState . creativeMode
cheat = s ^. uiState . uiCheatMode
Expand Down Expand Up @@ -1199,8 +1202,8 @@ explainEntry s e =
, drawMarkdown (e ^. entityDescription)
, explainRecipes s e
]
<> [drawRobotMachine s False | e ^. entityCapabilities . Lens.contains CDebug]
<> [drawRobotLog s | e ^. entityCapabilities . Lens.contains CLog]
<> [drawRobotMachine s False | CDebug `M.member` getMap (e ^. entityCapabilities)]
<> [drawRobotLog s | CLog `M.member` getMap (e ^. entityCapabilities)]

displayProperties :: [EntityProperty] -> Widget Name
displayProperties = displayList . mapMaybe showProperty
Expand Down Expand Up @@ -1349,7 +1352,7 @@ drawRecipe me inv (Recipe ins outs reqs time _weight) =

-- | Ad-hoc entity to represent time - only used in recipe drawing
timeE :: Entity
timeE = mkEntity (defaultEntityDisplay '.') "ticks" mempty [] []
timeE = mkEntity (defaultEntityDisplay '.') "ticks" mempty [] mempty

drawReqs :: IngredientList Entity -> Widget Name
drawReqs = vBox . map (hCenter . drawReq)
Expand Down
Loading

0 comments on commit 01ac86a

Please sign in to comment.