Add has and count commands (#265)

Closes #88.

Currently, these commands require no capability and no specific device (you already have an inventory, so why wouldn't you be able to look in it to see what you have?).  However, that makes it impossible to discover these commands without reading the source or tutorial.  Maybe we should make an "inventory" device?  I'm not sure.  Suggestions welcome.  Or maybe once we implement #84 it won't matter since players can discover commands that way.
This commit is contained in:
Brent Yorgey 2021-10-29 14:47:36 -05:00 committed by GitHub
parent a990406828
commit 5c8c17d787
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 32 additions and 2 deletions

View File

@ -263,8 +263,15 @@
attr: device
char: 'C'
description:
- An 8-bit counter.
- "Increment and reset, what more could you want?"
- |
A counter enables the command 'count : string -> cmd int',
which counts how many occurrences of an entity are currently
in the inventory. This is an upgraded version of the 'has'
command, which returns a bool instead of an int and does
not require any special device.
properties: [portable]
capabilities: [count]
- name: Linux
display:

View File

@ -20,6 +20,7 @@
module Swarm.Game.Step where
import Control.Lens hiding (Const, from, parts, use, uses, view, (%=), (+=), (.=), (<>=))
import Control.Monad (forM_, msum, unless, void, when)
import Data.Bool (bool)
import Data.Either (rights)
import Data.Int (Int64)
@ -59,7 +60,6 @@ import Control.Carrier.Throw.Either (ThrowC, runThrow)
import Control.Effect.Error
import Control.Effect.Lens
import Control.Effect.Lift
import Control.Monad (forM_, msum, unless, void, when)
-- | The maximum number of CESK machine evaluation steps each robot is
-- allowed during a single game tick.
@ -765,6 +765,16 @@ execConst c vs s k = do
robotInventory .= invTaken
finishCookingRecipe recipe (WorldUpdate Right) (RobotUpdate changeInv)
_ -> badConst
Has -> case vs of
[VString name] -> do
inv <- use robotInventory
return $ Out (VBool ((> 0) $ countByName name inv)) s k
_ -> badConst
Count -> case vs of
[VString name] -> do
inv <- use robotInventory
return $ Out (VInt (fromIntegral $ countByName name inv)) s k
_ -> badConst
Whereami -> do
V2 x y <- use robotLocation
return $ Out (VPair (VInt (fromIntegral x)) (VInt (fromIntegral y))) s k

View File

@ -57,6 +57,8 @@ data Capability
CInstall
| -- | Execute the 'Make' command
CMake
| -- | Execute the 'Count' command
CCount
| -- | Execute the 'Build' command
CBuild
| -- | Execute the 'Salvage' command
@ -240,6 +242,8 @@ constCaps =
Give -> [CGive]
Install -> [CInstall]
Make -> [CMake]
Has -> []
Count -> [CCount]
If -> [CCond]
Create -> [CCreate]
Blocked -> [CSensefront]

View File

@ -218,6 +218,10 @@ data Const
Install
| -- | Make an item.
Make
| -- | Sense whether we have a certain item.
Has
| -- | Sense how many of a certain item we have.
Count
| -- | Drill through an entity.
Drill
| -- | Construct a new robot.
@ -400,6 +404,8 @@ constInfo c = case c of
Give -> commandLow 2
Install -> commandLow 2
Make -> commandLow 1
Has -> commandLow 1
Count -> commandLow 1
Reprogram -> commandLow 2
Drill -> commandLow 1
Build -> commandLow 2

View File

@ -431,6 +431,8 @@ inferConst c = toU $ case c of
Give -> [tyQ| string -> string -> cmd () |]
Install -> [tyQ| string -> string -> cmd () |]
Make -> [tyQ| string -> cmd () |]
Has -> [tyQ| string -> cmd bool |]
Count -> [tyQ| string -> cmd int |]
Reprogram -> [tyQ| string -> {cmd a} -> cmd () |]
Build -> [tyQ| string -> {cmd a} -> cmd string |]
Drill -> [tyQ| dir -> cmd () |]

View File

@ -220,6 +220,7 @@ helpWidget = (helpKeys <=> fill ' ') <+> (helpCommands <=> fill ' ')
, ("turn <dir>", "Change the current direction")
, ("grab", "Grab whatver is available")
, ("give <robot> <item>", "Give an item to another robot")
, ("has <item>", "Check for an item in the inventory")
]
-- | Draw the error dialog window, if it should be displayed right now.