Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

disambiguate doc links, elaborate waypoint ordering #1531

Merged
merged 1 commit into from
Sep 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Swarm/Doc/Gen.hs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ data GenerateDocs where
RecipeGraph :: GenerateDocs
-- | Keyword lists for editors.
EditorKeywords :: Maybe EditorType -> GenerateDocs
-- | List of special key names recognized by 'key' command
-- | List of special key names recognized by 'Swarm.Language.Syntax.Key' command
SpecialKeyNames :: GenerateDocs
-- | Cheat sheets for inclusion on the Swarm wiki.
CheatSheet :: PageAddress -> Maybe SheetType -> GenerateDocs
Expand Down
8 changes: 4 additions & 4 deletions src/Swarm/Game/Exception.hs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import Witch (from)
-- | Suggested way to fix things when a robot does not meet the
-- requirements to run a command.
data IncapableFix
= -- | Equip the missing device on yourself/target
= -- | 'Swarm.Language.Syntax.Equip' the missing device on yourself/target
FixByEquip
| -- | Add the missing device to your inventory
FixByObtain
Expand All @@ -72,11 +72,11 @@ data Exn
-- term that caused the problem, and a suggestion for how to fix
-- things.
Incapable IncapableFix Requirements Term
| -- | A command failed in some "normal" way (/e.g./ a 'Move'
-- command could not move, or a 'Grab' command found nothing to
| -- | A command failed in some "normal" way (/e.g./ a 'Swarm.Language.Syntax.Move'
-- command could not move, or a 'Swarm.Language.Syntax.Grab' command found nothing to
-- grab, /etc./). Can be caught by a @try@ block.
CmdFailed Const Text (Maybe GameplayAchievement)
| -- | The user program explicitly called 'Undefined' or 'Fail'. Can
| -- | The user program explicitly called 'Swarm.Language.Syntax.Undefined' or 'Swarm.Language.Syntax.Fail'. Can
-- be caught by a @try@ block.
User Text
deriving (Eq, Show, Generic, FromJSON, ToJSON)
Expand Down
12 changes: 6 additions & 6 deletions src/Swarm/Game/Location.hs
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,17 @@ import Swarm.Util qualified as Util
-- >>> import Linear
-- >>> import Swarm.Language.Direction

-- | A Location is a pair of (x,y) coordinates, both up to 32 bits.
-- | A t'Location' is a pair of @(x,y)@ coordinates, both up to 32 bits.
-- The positive x-axis points east and the positive y-axis points
-- north. These are the coordinates that are shown to players.
--
-- See also the 'Swarm.Game.World.Coords' type defined in "Swarm.Game.World", which
-- use a (row, column) format instead, which is more convenient for
-- internal use. The "Swarm.Game.World" module also defines
-- conversions between 'Location' and 'Swarm.Game.World.Coords'.
-- conversions between t'Location' and 'Swarm.Game.World.Coords'.
type Location = Point V2 Int32

-- | A convenient way to pattern-match on 'Location' values.
-- | A convenient way to pattern-match on t'Location' values.
pattern Location :: Int32 -> Int32 -> Location
pattern Location x y = P (V2 x y)

Expand All @@ -76,13 +76,13 @@ instance ToJSON Location where

-- | A @Heading@ is a 2D vector, with 32-bit coordinates.
--
-- 'Location' and 'Heading' are both represented using types from
-- t'Location' and 'Heading' are both represented using types from
-- the @linear@ package, so they can be manipulated using a large
-- number of operators from that package. For example:
--
-- * Two headings can be added with '^+^'.
-- * The difference between two 'Location's is a 'Heading' (via '.-.').
-- * A 'Location' plus a 'Heading' is another 'Location' (via 'Linear.Affine..^+').
-- * The difference between two t'Location's is a 'Heading' (via '.-.').
-- * A t'Location' plus a 'Heading' is another t'Location' (via 'Linear.Affine..^+').
type Heading = V2 Int32

deriving instance ToJSON (V2 Int32)
Expand Down
17 changes: 9 additions & 8 deletions src/Swarm/Game/Robot.hs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ data ActivityCounts = ActivityCounts
makeLensesNoSigs ''ActivityCounts

-- | A counter that is decremented upon each step of the robot within the
-- CESK machine. Initially set to 'robotStepsPerTick' at each new tick.
-- CESK machine. Initially set to 'Swarm.Game.State.robotStepsPerTick'
-- at each new tick.
--
-- The need for 'tickStepBudget' is a bit technical, and I hope I can
-- eventually find a different, better way to accomplish it.
Expand Down Expand Up @@ -341,20 +342,20 @@ robotDisplay = lens getDisplay setDisplay

-- | The robot's current location, represented as @(x,y)@. This is only
-- a getter, since when changing a robot's location we must remember
-- to update the 'robotsByLocation' map as well. You can use the
-- 'updateRobotLocation' function for this purpose.
-- to update the 'Swarm.Game.State.robotsByLocation' map as well. You can use the
-- 'Swarm.Game.Step.updateRobotLocation' function for this purpose.
robotLocation :: Getter Robot (Cosmic Location)

-- | Set a robot's location. This is unsafe and should never be
-- called directly except by the 'updateRobotLocation' function.
-- The reason is that we need to make sure the 'robotsByLocation'
-- called directly except by the 'Swarm.Game.Step.updateRobotLocation' function.
-- The reason is that we need to make sure the 'Swarm.Game.State.robotsByLocation'
-- map stays in sync.
unsafeSetRobotLocation :: Cosmic Location -> Robot -> Robot
unsafeSetRobotLocation loc r = r {_robotLocation = loc}

-- | A template robot's location. Unlike 'robotLocation', this is a
-- lens, since when dealing with robot templates there is as yet no
-- 'robotsByLocation' map to keep up-to-date.
-- 'Swarm.Game.State.robotsByLocation' map to keep up-to-date.
trobotLocation :: Lens' TRobot (Maybe (Cosmic Location))
trobotLocation = lens _robotLocation (\r l -> r {_robotLocation = l})

Expand Down Expand Up @@ -414,8 +415,8 @@ equippedDevices = lens _equippedDevices setEquipped
}

-- | The robot's own private message log, most recent message last.
-- Messages can be added both by explicit use of the 'Log' command,
-- and by uncaught exceptions. Stored as a "Data.Sequence" so that
-- Messages can be added both by explicit use of the 'Swarm.Language.Syntax.Log' command,
-- and by uncaught exceptions. Stored as a 'Seq' so that
-- we can efficiently add to the end and also process from beginning
-- to end. Note that updating via this lens will also set the
-- 'robotLogUpdated'.
Expand Down
2 changes: 2 additions & 0 deletions src/Swarm/Game/Scenario/Style.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ instance FromJSON StyleFlag where
instance ToJSON StyleFlag where
toJSON = genericToJSON styleFlagJsonOptions

-- | Hexadecimal color notation.
-- May include a leading hash symbol (see 'Data.Colour.SRGB.sRGB24read').
newtype HexColor = HexColor Text
deriving (Eq, Show, Generic, FromJSON, ToJSON)

Expand Down
5 changes: 4 additions & 1 deletion src/Swarm/Game/Scenario/Topography/Area.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Data.Maybe (listToMaybe)
import Linear (V2 (..))
import Swarm.Game.Location

-- | Height and width of a 2D map region
data AreaDimensions = AreaDimensions
{ rectWidth :: Int32
, rectHeight :: Int32
Expand All @@ -22,7 +23,7 @@ renderRectDimensions (AreaDimensions w h) =
invertY :: V2 Int32 -> V2 Int32
invertY (V2 x y) = V2 x (-y)

-- | Incorporates an offset by -1, since the area is
-- | Incorporates an offset by @-1@, since the area is
-- "inclusive" of the lower-right coordinate.
-- Inverse of 'cornersToArea'.
upperLeftToBottomRight :: AreaDimensions -> Location -> Location
Expand All @@ -41,9 +42,11 @@ cornersToArea upperLeft lowerRight =
where
V2 x y = (+ 1) <$> invertY (lowerRight .-. upperLeft)

-- | Has zero width or height.
isEmpty :: AreaDimensions -> Bool
isEmpty (AreaDimensions w h) = w == 0 || h == 0

-- | Extracts the dimensions of a map grid.
getAreaDimensions :: [[a]] -> AreaDimensions
getAreaDimensions cellGrid =
AreaDimensions w h
Expand Down
6 changes: 3 additions & 3 deletions src/Swarm/Game/Scenario/Topography/Navigation/Portal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ data AnnotatedDestination a = AnnotatedDestination
-- on the portal location specification method ('portalExitLoc').
--
-- == @additionalDimension@
-- As a member of the 'WorldDescription', waypoints are only known within a
-- As a member of the 'Swarm.Game.Scenario.Topography.WorldDescription.WorldDescription', waypoints are only known within a
-- a single subworld, so 'additionalDimension' is 'Identity' for the map
-- of waypoint names to planar locations.
-- At the Scenario level, in contrast, we have access to all subworlds, so
Expand Down Expand Up @@ -129,7 +129,7 @@ failWaypointLookup (WaypointName rawName) =
-- == Data flow
--
-- Waypoints are defined within a subworld and are namespaced by it.
-- Optional intra-subworld uniqueness of Waypoints is enforced at WorldDescription
-- Optional intra-subworld uniqueness of Waypoints is enforced at 'Swarm.Game.Scenario.Topography.WorldDescription.WorldDescription'
-- parse time.
-- Portals are declared within a subworld. The portal entrance must be a waypoint
-- within this subworld.
Expand All @@ -140,7 +140,7 @@ failWaypointLookup (WaypointName rawName) =
-- no entrances overlap can also be performed at that level.
-- * However, enforcement of single-multiplicity on portal /exits/ must be performed
-- at scenario-parse level, because for a portal exit that references a waypoint in
-- another subworld, we can't know at the single-WorldDescription level whether
-- another subworld, we can't know at the single-'Swarm.Game.Scenario.Topography.WorldDescription.WorldDescription' level whether
-- that waypoint has plural multiplicity.
validatePartialNavigation ::
(MonadFail m, Traversable t) =>
Expand Down
16 changes: 16 additions & 0 deletions src/Swarm/Game/Scenario/Topography/Navigation/Waypoint.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

-- |
-- SPDX-License-Identifier: BSD-3-Clause
--
-- Landmarks that are used to specify portal locations
-- and can serve as navigation aids via the `waypoint` command.
--
-- = Waypoint ordering
--
-- The sequence of waypoints of a given name is dictated by criteria in the following order:
--
-- 1. Ordering of structure placements
-- (see implementation of 'Swarm.Game.Scenario.Topography.Structure.mergeStructures');
-- later placements are ordered first.
-- 2. Placement of cells within a map. Map locations go by row-major order
-- (compare to docs for 'Swarm.Game.State.genRobotTemplates').
--
-- TODO (#1366): May be useful to have a mechanism for more
-- precise control of ordering.
module Swarm.Game.Scenario.Topography.Navigation.Waypoint where

import Data.Int (Int32)
Expand Down
2 changes: 1 addition & 1 deletion src/Swarm/Game/Scenario/Topography/Structure.hs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ instance FromJSONE (EntityMap, RobotMap) (PStructure (Maybe (PCell Entity))) whe
return $ Structure maskedArea localStructureDefs placementDefs $ waypointDefs <> mapWaypoints

-- | \"Paint\" a world map using a 'WorldPalette', turning it from a raw
-- string into a nested list of 'Cell' values by looking up each
-- string into a nested list of 'PCell' values by looking up each
-- character in the palette, failing if any character in the raw map
-- is not contained in the palette.
paintMap ::
Expand Down
10 changes: 6 additions & 4 deletions src/Swarm/Game/ScenarioInfo.hs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ import Witch (into)
-- ----------------------------------------------------------------------------

-- | A scenario item is either a specific scenario, or a collection of
-- scenarios (*e.g.* the scenarios contained in a subdirectory).
-- scenarios (/e.g./ the scenarios contained in a subdirectory).
data ScenarioItem = SISingle ScenarioInfoPair | SICollection Text ScenarioCollection
deriving (Show)

Expand All @@ -85,15 +85,17 @@ scenarioItemName (SISingle (s, _ss)) = s ^. scenarioName
scenarioItemName (SICollection name _) = name

-- | A scenario collection is a tree of scenarios, keyed by name,
-- together with an optional order. Invariant: every item in the
-- scOrder exists as a key in the scMap.
-- together with an optional order.
--
-- /Invariant:/ every item in the
-- 'scOrder' exists as a key in the 'scMap'.
data ScenarioCollection = SC
{ scOrder :: Maybe [FilePath]
, scMap :: Map FilePath ScenarioItem
}
deriving (Show)

-- | Access and modify ScenarioItems in collection based on their path.
-- | Access and modify 'ScenarioItem's in collection based on their path.
scenarioItemByPath :: FilePath -> Traversal' ScenarioCollection ScenarioItem
scenarioItemByPath path = ixp ps
where
Expand Down
8 changes: 4 additions & 4 deletions src/Swarm/Game/State.hs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ data REPLStatus
= -- | The REPL is not doing anything actively at the moment.
-- We persist the last value and its type though.
--
-- INVARIANT: the 'Value' stored here is not a 'VResult'.
-- INVARIANT: the 'Value' stored here is not a 'Swarm.Language.Value.VResult'.
REPLDone (Maybe (Typed Value))
| -- | A command entered at the REPL is currently being run. The
-- 'Polytype' represents the type of the expression that was
Expand Down Expand Up @@ -694,7 +694,7 @@ recipesInfo :: Lens' GameState Recipes

-- | The filepath of the currently running scenario.
--
-- This is useful as an index to 'scenarios' collection,
-- This is useful as an index to the scenarios collection,
-- see 'Swarm.Game.ScenarioInfo.scenarioItemByPath'.
currentScenarioPath :: Lens' GameState (Maybe FilePath)

Expand Down Expand Up @@ -732,15 +732,15 @@ focusedRobotID = to _focusedRobotID
------------------------------------------------------------

-- | The current rule for determining the center of the world view.
-- It updates also, viewCenter and 'focusedRobotName' to keep
-- It updates also, 'viewCenter' and 'focusedRobot' to keep
-- everything synchronized.
viewCenterRule :: Lens' GameState ViewCenterRule
viewCenterRule = lens getter setter
where
getter :: GameState -> ViewCenterRule
getter = _viewCenterRule

-- The setter takes care of updating viewCenter and focusedRobotName
-- The setter takes care of updating 'viewCenter' and 'focusedRobot'
-- So non of this fields get out of sync.
setter :: GameState -> ViewCenterRule -> GameState
setter g rule =
Expand Down
11 changes: 6 additions & 5 deletions src/Swarm/Game/Step.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
-- ** Note on the IO:
--
-- The only reason we need @IO@ is so that robots can run programs
-- loaded from files, via the 'Run' command.
-- This could be avoided by using 'Import' command instead and parsing
-- loaded from files, via the 'Swarm.Language.Syntax.Run' command.
-- This could be avoided by using a hypothetical @import@ command instead and parsing
-- the required files at the time of declaration.
-- See <https://github.com/swarm-game/swarm/issues/495>.
module Swarm.Game.Step where
Expand Down Expand Up @@ -457,7 +457,7 @@ traceLogShow = void . traceLog Logged Info . from . show

-- | Capabilities needed for a specific robot to evaluate or execute a
-- constant. Right now, the only difference is whether the robot is
-- heavy or not when executing the 'Move' command, but there might
-- heavy or not when executing the 'Swarm.Language.Syntax.Move' command, but there might
-- be other exceptions added in the future.
constCapsFor :: Const -> Robot -> Maybe Capability
constCapsFor Move r
Expand Down Expand Up @@ -796,7 +796,7 @@ stepCESK cesk = case cesk of
runningAtomic .= False
return $ Out v s k

-- Machinery for implementing the 'meetAll' command.
-- Machinery for implementing the 'Swarm.Language.Syntax.MeetAll' command.
-- First case: done meeting everyone.
Out b s (FMeetAll _ [] : k) -> return $ Out b s k
-- More still to meet: apply the function to the current value b and
Expand Down Expand Up @@ -2615,7 +2615,8 @@ formatDevices = T.intercalate " or " . map (^. entityName) . S.toList

-- | Give some entities from a parent robot (the robot represented by
-- the ambient @State Robot@ effect) to a child robot (represented
-- by the given 'RID') as part of a 'Build' or 'Reprogram' command.
-- by the given 'RID') as part of a 'Swarm.Language.Syntax.Build'
-- or 'Swarm.Language.Syntax.Reprogram' command.
-- The first 'Inventory' is devices to be equipped, and the second
-- is entities to be transferred.
--
Expand Down
12 changes: 6 additions & 6 deletions src/Swarm/Game/Step/Combustion.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
-- |
-- SPDX-License-Identifier: BSD-3-Clause
--
-- Some entities are "combustible". A command, `ignite`, will
-- Some entities are "combustible". A command, 'Swarm.Language.Syntax.Ignite', will
-- initiate combustion on such an entity.
-- Furthermore, combustion can spread to (4-)adjacent entities, depending
-- on the 'ignition' property of that entity.
Expand Down Expand Up @@ -77,7 +77,7 @@ igniteCommand c d = do
-- by placed entities.
-- The "combustion bot" represents the burning of a single
-- entity; propagating the fire to neighbors is handled upstream,
-- within the `ignite` command.
-- within the 'Swarm.Language.Syntax.Ignite' command.
addCombustionBot ::
Has (State GameState) sig m =>
Entity ->
Expand Down Expand Up @@ -143,8 +143,8 @@ ignitionProgram waitTime =
--
-- 1. Create sub-partitions (of say, 10-tick duration) of the combustion duration
-- to re-evaluate opportunities to light adjacent entities on fire.
-- 2. Use the `watch` command to observe for changes to adjacent entities.
-- Note that if we "wake" from our `wait` due to the `watch` being triggered,
-- 2. Use the 'Swarm.Language.Syntax.Watch' command to observe for changes to adjacent entities.
-- Note that if we "wake" from our 'Swarm.Language.Syntax.Wait' due to the 'Swarm.Language.Syntax.Watch' being triggered,
-- we would need to maintain bookkeeping of how much time is left.
-- 3. Spawn more robots whose sole purpose is to observe for changes to neighbor
-- cells. This would avoid polluting the logic of the currently burning cell
Expand All @@ -165,7 +165,7 @@ combustionProgram combustionDuration (Combustibility _ _ maybeCombustionProduct)
Nothing -> (0, "")
Just p -> (1, p)

-- | We treat the 'ignition' field in the 'Combustion' record
-- | We treat the 'ignition' field in the 'Combustibility' record
-- as a /rate/ in a Poisson distribution.
-- Ignition of neighbors depends on that particular neighbor entity's
-- combustion /rate/, but also on the duration
Expand Down Expand Up @@ -197,7 +197,7 @@ igniteNeighbor creationTime sourceDuration loc = do
probabilityOfIgnition = 1 - exp (negate $ rate * fromIntegral sourceDuration)

-- | Construct an invisible "ignition robot" and add it to the world.
-- Its sole purpose is to delay the `ignite` command for a neighbor
-- Its sole purpose is to delay the 'Swarm.Language.Syntax.Ignite' command for a neighbor
-- that has been a priori determined that it shall be ignited.
addIgnitionBot ::
Has (State GameState) sig m =>
Expand Down
Loading
Loading