From 4a2edb218c9f2d1b6ef1e67b43b8238f8cd35113 Mon Sep 17 00:00:00 2001 From: Karl Ostmo Date: Sun, 26 Mar 2023 23:16:28 -0700 Subject: [PATCH] Sniff command towards #1171 --- editors/emacs/swarm-mode.el | 1 + editors/vscode/syntaxes/swarm.tmLanguage.json | 2 +- src/Swarm/Game/Step.hs | 16 +++++++++++++++- src/Swarm/Language/Capability.hs | 3 +++ src/Swarm/Language/Syntax.hs | 9 +++++++++ src/Swarm/Language/Typecheck.hs | 1 + 6 files changed, 30 insertions(+), 2 deletions(-) diff --git a/editors/emacs/swarm-mode.el b/editors/emacs/swarm-mode.el index 4dd42f897..6099802d9 100644 --- a/editors/emacs/swarm-mode.el +++ b/editors/emacs/swarm-mode.el @@ -77,6 +77,7 @@ "time" "whereami" "detect" + "sniff" "heading" "blocked" "scan" diff --git a/editors/vscode/syntaxes/swarm.tmLanguage.json b/editors/vscode/syntaxes/swarm.tmLanguage.json index 6019956ea..9ca47706d 100644 --- a/editors/vscode/syntaxes/swarm.tmLanguage.json +++ b/editors/vscode/syntaxes/swarm.tmLanguage.json @@ -58,7 +58,7 @@ }, { "name": "keyword.other", - "match": "\\b(?i)(self|parent|base|if|inl|inr|case|fst|snd|force|undefined|fail|not|format|chars|split|charat|tochar|noop|wait|selfdestruct|move|turn|grab|harvest|place|give|equip|unequip|make|has|equipped|count|drill|build|salvage|reprogram|say|listen|log|view|appear|create|time|whereami|detect|heading|blocked|scan|upload|ishere|isempty|meet|meetall|whoami|setname|random|run|return|try|swap|atomic|teleport|as|robotnamed|robotnumbered|knows)\\b" + "match": "\\b(?i)(self|parent|base|if|inl|inr|case|fst|snd|force|undefined|fail|not|format|chars|split|charat|tochar|noop|wait|selfdestruct|move|turn|grab|harvest|place|give|equip|unequip|make|has|equipped|count|drill|build|salvage|reprogram|say|listen|log|view|appear|create|time|whereami|detect|sniff|heading|blocked|scan|upload|ishere|isempty|meet|meetall|whoami|setname|random|run|return|try|swap|atomic|teleport|as|robotnamed|robotnumbered|knows)\\b" } ] }, diff --git a/src/Swarm/Game/Step.hs b/src/Swarm/Game/Step.hs index 0ac544b5d..8262a6e62 100644 --- a/src/Swarm/Game/Step.hs +++ b/src/Swarm/Game/Step.hs @@ -57,7 +57,7 @@ import Data.Text (Text) import Data.Text qualified as T import Data.Time (getZonedTime) import Data.Tuple (swap) -import Linear (V2 (..), zero) +import Linear (V2 (..), zero, perp) import Swarm.Game.Achievement.Attainment import Swarm.Game.Achievement.Definitions import Swarm.Game.CESK @@ -90,6 +90,10 @@ import System.Clock qualified import System.Random (UniformRange, uniformR) import Witch (From (from), into) import Prelude hiding (lookup) +import Data.Int (Int32) + +maxSniffRange :: Int32 +maxSniffRange = 250 -- | The main function to do one game step. -- @@ -1206,6 +1210,16 @@ execConst c vs s k = do firstOne <- findM (fmap (maybe False $ isEntityNamed name) . entityAt . (loc .+^)) sortedLocs return $ Out (asValue firstOne) s k _ -> badConst + Sniff -> case vs of + [VText name] -> do + loc <- use robotLocation + -- Grow a list of locations in a diamond shape outward, such that the nearest cells + -- are searched first by construction. + let genDiamondSide diameter = concat [map (diameter,)$ take 4 $ iterate perp $ V2 x (diameter - x) | x <- [0..diameter]] + let sortedLocs = (0, zero) : concatMap genDiamondSide [1..maxSniffRange] + firstOne <- findM (fmap (maybe False $ isEntityNamed name) . entityAt . (loc .+^) . snd) sortedLocs + return $ Out (asValue $ maybe (-1) fst firstOne) s k + _ -> badConst Heading -> do mh <- use robotOrientation -- In general, (1) entities might not have an orientation, and diff --git a/src/Swarm/Language/Capability.hs b/src/Swarm/Language/Capability.hs index b7848b1bd..b417c4df8 100644 --- a/src/Swarm/Language/Capability.hs +++ b/src/Swarm/Language/Capability.hs @@ -72,6 +72,8 @@ data Capability CSensehere | -- | Execute the 'Detect' command CDetectloc + | -- | Execute the 'Sniff' command + CDetectdistance | -- | Execute the 'Scan' command CScan | -- | Execute the 'Random' command @@ -216,6 +218,7 @@ constCaps = \case Wait -> Just CTime Whereami -> Just CSenseloc Detect -> Just CDetectloc + Sniff -> Just CDetectdistance Heading -> Just COrient -- ---------------------------------------------------------------- -- Text operations diff --git a/src/Swarm/Language/Syntax.hs b/src/Swarm/Language/Syntax.hs index dd2dce486..9d203f61d 100644 --- a/src/Swarm/Language/Syntax.hs +++ b/src/Swarm/Language/Syntax.hs @@ -234,6 +234,9 @@ data Const | -- | Locate the closest instance of a given entity within the rectangle -- specified by opposite corners, relative to the current location. Detect + | -- | Get the distance to the closest instance of the specified entity. + -- Returns (-1) if none found. + Sniff | -- | Get the current heading. Heading | -- | See if we can move forward or not. @@ -584,6 +587,12 @@ constInfo c = case c of Detect -> command 2 Intangible . doc "Detect an entity within a rectangle." $ ["Locate the closest instance of a given entity within the rectangle specified by opposite corners, relative to the current location."] + Sniff -> + command 1 short . doc "Determine distance to entity." $ + [ "Measures concentration of airborne particles to infer distance to a certain kind of entity." + , "If none is detected, returns (-1)." + , "Has a max range of 250 units." + ] Heading -> command 0 Intangible "Get the current heading." Blocked -> command 0 Intangible "See if the robot can move forward." Scan -> diff --git a/src/Swarm/Language/Typecheck.hs b/src/Swarm/Language/Typecheck.hs index 2cecd0927..a8aadfdaf 100644 --- a/src/Swarm/Language/Typecheck.hs +++ b/src/Swarm/Language/Typecheck.hs @@ -560,6 +560,7 @@ inferConst c = case c of Time -> [tyQ| cmd int |] Whereami -> [tyQ| cmd (int * int) |] Detect -> [tyQ| text -> ((int * int) * (int * int)) -> cmd (unit + (int * int)) |] + Sniff -> [tyQ| text -> cmd int |] Heading -> [tyQ| cmd dir |] Blocked -> [tyQ| cmd bool |] Scan -> [tyQ| dir -> cmd (unit + text) |]