Skip to content

Commit

Permalink
Refactor capabilities (#1553)
Browse files Browse the repository at this point in the history
* add `CExecute Const`
  * remove all capabilities for constants
  * update YAML to mention each capability for constant explicitly
* uses [`generic-data`](https://hackage.haskell.org/package/generic-data-1.1.0.0/docs/Generic-Data.html#t:FiniteEnumeration) package to get `Enum` and `Bounded`
  ```Haskell
  deriving (Enum, Bounded) via (FiniteEnumeration Capability)
  ```
* closes #1548
* closes #2018
  • Loading branch information
xsebek authored Sep 10, 2024
1 parent 65c5ef9 commit 9270ff8
Show file tree
Hide file tree
Showing 19 changed files with 127 additions and 321 deletions.
61 changes: 35 additions & 26 deletions data/entities.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
description:
- A medium-sized rock... that looks a little different. It seems to react to iron and surprisingly also to naturally growing bits.
properties: [pickable]
capabilities: [negation]
capabilities: [not]
- name: beaglepuss
display:
attr: rubber
Expand Down Expand Up @@ -361,7 +361,7 @@
in "Number of widgets: " ++ format numWidgets
```
properties: [pickable]
capabilities: [concat]
capabilities: ["++"]
- name: caliper
display:
attr: silver
Expand All @@ -374,7 +374,7 @@
```
computes the number of characters in a `Text`{=type} value.
properties: [pickable]
capabilities: [charcount]
capabilities: [chars]
- name: wedge
display:
attr: silver
Expand Down Expand Up @@ -416,7 +416,7 @@
`split : Int -> Text -> Text * Text` splits a `Text`{=type} value into
two pieces, one before the given index and one after.
properties: [pickable]
capabilities: [format, concat, charcount, split]
capabilities: [format, '++', chars, split]
- name: decoder ring
display:
attr: silver
Expand All @@ -433,7 +433,7 @@
`toChar : Int -> Text` creates a singleton (length-1) `Text`{=type}
value containing a character with the given numeric code.
properties: [pickable]
capabilities: [code]
capabilities: [charat, tochar]
- name: lambda
display:
attr: flower
Expand Down Expand Up @@ -588,7 +588,7 @@
`floorplan : Text -> Cmd (Int * Int)`
- Gets the dimensions of a structure template.
properties: [pickable]
capabilities: [structure]
capabilities: [structure, floorplan]
- name: drill bit
display:
attr: entity
Expand Down Expand Up @@ -743,7 +743,7 @@
char: '%'
description:
- Tank treads work like treads, but are large enough to move even heavy robots around.
capabilities: [move, turn, moveheavy]
capabilities: [move, turn, move heavy robot]
properties: [pickable]
- name: tape drive
display:
Expand Down Expand Up @@ -791,7 +791,7 @@
char: 'B'
description:
- Allows one to `scout` for other robots
capabilities: [recondir]
capabilities: [scout]
properties: [pickable]
- name: welder
display:
Expand Down Expand Up @@ -921,7 +921,7 @@
if (x > 3) {move} {turn right; move}
```
properties: [pickable]
capabilities: [cond]
capabilities: [if, '&&', '||']
- name: detonator
display:
attr: fire
Expand All @@ -942,11 +942,20 @@
attr: device
char: '$'
description:
- "With a scanner device, robots can use the `scan` command to learn about their surroundings. Simply give `scan` a direction in which to scan, and information about the scanned item (if any) will be added to the robot's inventory."
- "A scanner also enables `blocked : Cmd Bool`, which returns a boolean value indicating whether the robot's path is blocked (i.e. whether executing a `move` command would fail); `ishere : Text -> Cmd Bool` for checking whether the current cell contains a particular entity; and `isempty : Cmd Bool` for checking whether the current cell is empty of entities. Note that `ishere` and `isempty` do not detect robots, only entities."
- "Finally, robots can use the `upload` command to copy their accumulated knowledge to another nearby robot; for example, `upload base`."
- |
With a scanner device, robots can use the `scan` command to learn about their surroundings.
Simply give `scan` a direction in which to scan, and information about the scanned item (if any)
will be added to the robot's inventory.
- |
A scanner also enables `blocked : Cmd Bool`, which returns a boolean value indicating whether the robot's path is blocked
(i.e. whether executing a `move` command would fail); `ishere : Text -> Cmd Bool` for checking whether the current cell
contains a particular entity; and `isempty : Cmd Bool` for checking whether the current cell is empty of entities.
Note that `ishere` and `isempty` do not detect robots, only entities."
- |
Finally, robots can use the `upload` command to copy their accumulated knowledge to another nearby robot;
for example, `upload base`."
properties: [pickable]
capabilities: [scan, sensefront, sensehere]
capabilities: [scan, blocked, ishere, isempty, upload]
- name: olfactometer
display:
char: 'N'
Expand All @@ -955,7 +964,7 @@
- |
`sniff : Text -> Cmd Int` returns the distance to the nearest specified entity.
properties: [pickable]
capabilities: [detectdistance]
capabilities: [sniff]
- name: flash memory
display:
attr: device
Expand All @@ -975,7 +984,7 @@
- "A mirror enables the `whoami` command, which returns the robot's name as a string."
- "It also enables the special `self` variable, which gives a robot a reference to itself."
properties: [pickable]
capabilities: [whoami]
capabilities: [whoami, self]
- name: logger
display:
attr: device
Expand Down Expand Up @@ -1019,7 +1028,7 @@
description:
- "A calculator allows a robot to do basic arithmetic calculations: addition, subtraction, multiplication, division, and exponentiation."
properties: [pickable]
capabilities: [arith]
capabilities: ['+', '-', neg, '*', '/', '^']
- name: ADT calculator
display:
attr: device
Expand Down Expand Up @@ -1052,7 +1061,7 @@
example, `case (inl 3) (\x. 2*x) (\y. 3*y) == 6`, and `case (inr
3) (\x. 2*x) (\y. 3*y) == 9`.
properties: [pickable]
capabilities: [arith, sum, prod]
capabilities: ['+', '-', neg, '*', '/', '^', sum, prod]
- name: hyperloop
display:
attr: device
Expand All @@ -1067,7 +1076,7 @@
`t = T(t)`{=snippet}. For exmple, `rec l. Unit + Int * l`{=type} is
the type of lists of integers.
properties: [pickable]
capabilities: [arith, sum, prod, rectype]
capabilities: ['+', '-', neg, '*', '/', '^', sum, prod, rectype]
- name: compass
display:
attr: device
Expand All @@ -1085,7 +1094,7 @@
- |
`d <- heading; turn east; move; turn d`
properties: [pickable]
capabilities: [orient]
capabilities: [orient, heading]
- name: clock
display:
attr: device
Expand All @@ -1097,7 +1106,7 @@
- |
`wait : Int -> Cmd Unit` causes a robot to sleep for a specified amount of time (measured in game ticks).
properties: [pickable]
capabilities: [timeabs, timerel]
capabilities: [time, wait]
- name: hourglass
display:
attr: device
Expand All @@ -1107,7 +1116,7 @@
- |
`wait : Int -> Cmd Unit` causes a robot to sleep for a specified amount of time (measured in game ticks).
properties: [pickable]
capabilities: [timerel]
capabilities: [wait]
- name: rolex
display:
char: R
Expand All @@ -1118,7 +1127,7 @@
`watch : Dir -> Cmd Unit` will mark an adjacent (in the specified direction) location of interest to monitor for placement or removal of items.
A subsequent call to `wait` will be interrupted upon a change to the location.
properties: [pickable]
capabilities: [timerel, wakeself]
capabilities: [time, wait, watch]
- name: comparator
display:
attr: device
Expand All @@ -1127,7 +1136,7 @@
- "A comparator allows comparing two values to see whether the first is less, equal, or greater than the second."
- "Valid comparison operators are <, <=, >, >=, ==, and !=."
properties: [pickable]
capabilities: [compare]
capabilities: ['<', '<=', '>', '>=', '==', '!=']
- name: I/O cable
display:
attr: device
Expand Down Expand Up @@ -1186,7 +1195,7 @@
`meetAll : Cmd (rec l. Unit + Actor * l)` returns a list of
all the nearby actors other than oneself.
properties: [pickable]
capabilities: [meet]
capabilities: [meet, meetAll]
- name: GPS receiver
display:
attr: device
Expand All @@ -1197,7 +1206,7 @@
some convenient satellite signals,
enabling the command `whereami : Cmd (Int * Int)`.
properties: [pickable]
capabilities: [senseloc]
capabilities: [whereami]
- name: tweezers
display:
attr: device
Expand Down Expand Up @@ -1259,7 +1268,7 @@
`key : Text -> Key` constructs values of type `Key`{=type}, for
example `key "Down"` or `key "C-S-x"`.
properties: [pickable]
capabilities: [handleinput]
capabilities: [key, installKeyHandler]
- name: halting oracle
display:
attr: device
Expand Down
2 changes: 1 addition & 1 deletion data/scenarios/Challenges/Ranching/beekeeping.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ entities:
description:
- Senses direction to nectar-producing flowers
properties: [known, pickable]
capabilities: [detectdirection, structure]
capabilities: [chirp, structure]
- name: honey
display:
char: 'h'
Expand Down
2 changes: 1 addition & 1 deletion data/scenarios/Challenges/Ranching/powerset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ entities:
description:
- Allows one to `stride` across multiple cells
properties: [known, pickable]
capabilities: [movemultiple]
capabilities: [stride]
- name: bell
display:
char: 'B'
Expand Down
8 changes: 4 additions & 4 deletions data/scenarios/Challenges/Sliding Puzzles/3x3.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -157,16 +157,16 @@ entities:
display:
char: 'G'
description:
- Generates a magnetic field gradient that allows the use of `resonate`
- Generates a magnetic field gradient that allows the use of `resonate` and `density`.
properties: [known]
capabilities: [detectcount]
capabilities: [resonate, density]
- name: locator
display:
char: '{'
description:
- Enables the `detect` command
- Enables the `detect` command.
properties: [known]
capabilities: [detectloc]
capabilities: [detect]
- name: border
display:
char: ''
Expand Down
2 changes: 1 addition & 1 deletion data/scenarios/Testing/1218-stride-command.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ entities:
description:
- Allows one to "stride" across multiple cells
properties: [known, pickable]
capabilities: [movemultiple]
capabilities: [stride]
known: [tree, flower, boulder, water]
world:
palette:
Expand Down
4 changes: 2 additions & 2 deletions data/scenarios/Testing/508-capability-subset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ entities:
description:
- A satellite navigation device.
properties: [known, pickable]
capabilities: [senseloc]
capabilities: [whereami]
- name: Tardis
display:
attr: water
char: ''
description:
- Bigger on the inside.
properties: [known, pickable]
capabilities: [senseloc, teleport]
capabilities: [whereami, teleport]
6 changes: 5 additions & 1 deletion src/swarm-doc/Swarm/Doc/Wiki/Cheatsheet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,11 @@ capabilityTable a em cs = T.unlines $ header <> map (listToRow mw) capabilityRow
header = [listToRow mw capabilityHeader, separatingLine mw]

capabilityPage :: PageAddress -> EntityMap -> Text
capabilityPage a em = capabilityTable a em enumerate
capabilityPage a em = capabilityTable a em $ filter usedCapability enumerate
where
usedCapability c = case c of
Capability.CExecute con -> Capability.constCaps con == Just c
_ -> True

-- ** Entities

Expand Down
8 changes: 4 additions & 4 deletions src/swarm-engine/Swarm/Game/Exception.hs
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ formatIncapableFix = \case
-- >>> import Swarm.Game.Failure (LoadingFailure)
-- >>> import qualified Data.Set as S
-- >>> :set -XTypeApplications
-- >>> w = mkEntity (defaultEntityDisplay 'l') "magic wand" mempty mempty (S.singleton CAppear)
-- >>> r = mkEntity (defaultEntityDisplay 'o') "the one ring" mempty mempty (S.singleton CAppear)
-- >>> w = mkEntity (defaultEntityDisplay 'l') "magic wand" mempty mempty (S.singleton $ CExecute Appear)
-- >>> r = mkEntity (defaultEntityDisplay 'o') "the one ring" mempty mempty (S.singleton $ CExecute Appear)
-- >>> m = fromRight mempty . run . runThrow @LoadingFailure $ buildEntityMap [w,r]
-- >>> incapableError cs t = putStr . unpack $ formatIncapable m FixByEquip cs t
--
Expand All @@ -152,13 +152,13 @@ formatIncapableFix = \case
-- 'as'
-- If God in troth thou wantest to play, try thou a Creative game.
--
-- >>> incapableError (R.singletonCap CAppear) (TConst Appear)
-- >>> incapableError (R.singletonCap $ CExecute Appear) (TConst Appear)
-- You do not have the device required for:
-- 'appear'
-- Please equip:
-- - magic wand or the one ring
--
-- >>> incapableError (R.singletonCap CRandom) (TConst Random)
-- >>> incapableError (R.singletonCap $ CExecute Random) (TConst Random)
-- Missing the random capability for:
-- 'random'
-- but no device yet provides it. See
Expand Down
2 changes: 1 addition & 1 deletion src/swarm-engine/Swarm/Game/Step.hs
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ stepCESK cesk = case cesk of
--
-- HOWEVER, we have to make sure to check that the robot has the
-- 'log' capability which is required to collect and view logs.
h <- hasCapability CLog
h <- hasCapability $ CExecute Log
em <- use $ landscape . terrainAndEntities . entityMap
when h $ void $ traceLog RobotError (exnSeverity exn) (formatExn em exn)
return $ case menv of
Expand Down
6 changes: 3 additions & 3 deletions src/swarm-engine/Swarm/Game/Step/Const.hs
Original file line number Diff line number Diff line change
Expand Up @@ -778,8 +778,8 @@ execConst runChildProg c vs s k = do
let addToRobotLog :: (Has (State GameState) sgn m) => Robot -> m ()
addToRobotLog r = do
maybeRidLoc <- evalState r $ do
hasLog <- hasCapability CLog
hasListen <- hasCapability CListen
hasLog <- hasCapability $ CExecute Log
hasListen <- hasCapability $ CExecute Listen
loc' <- use robotLocation
rid <- use robotID
return $ do
Expand Down Expand Up @@ -1258,7 +1258,7 @@ execConst runChildProg c vs s k = do
doDrill d = do
ins <- use equippedDevices

let equippedDrills = extantElemsWithCapability CDrill ins
let equippedDrills = extantElemsWithCapability (CExecute Drill) ins
-- Heuristic: choose the drill with the more elaborate name.
-- E.g. "metal drill" vs. "drill"
preferredDrill = listToMaybe $ sortOn (Down . T.length . (^. entityName)) equippedDrills
Expand Down
6 changes: 3 additions & 3 deletions src/swarm-engine/Swarm/Game/Step/Util/Command.hs
Original file line number Diff line number Diff line change
Expand Up @@ -269,11 +269,11 @@ grantAchievement a = do
-- be other exceptions added in the future.
constCapsFor :: Const -> Robot -> Maybe Capability
constCapsFor Move r
| r ^. robotHeavy = Just CMoveheavy
| r ^. robotHeavy = Just CMoveHeavy
constCapsFor Backup r
| r ^. robotHeavy = Just CMoveheavy
| r ^. robotHeavy = Just CMoveHeavy
constCapsFor Stride r
| r ^. robotHeavy = Just CMoveheavy
| r ^. robotHeavy = Just CMoveHeavy
constCapsFor c _ = constCaps c

-- | Requires that the target location is within one cell.
Expand Down
Loading

0 comments on commit 9270ff8

Please sign in to comment.