Skip to content

Commit

Permalink
Compute and display activity ratio
Browse files Browse the repository at this point in the history
  • Loading branch information
kostmo committed Sep 4, 2023
1 parent 38fbcbd commit 7d246ec
Show file tree
Hide file tree
Showing 17 changed files with 320 additions and 35 deletions.
69 changes: 65 additions & 4 deletions data/scenarios/Testing/1341-command-count.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
version: 1
name: Count commands
creative: true
description: |
Count commands
Count commands and demonstrate various "duty cycles"
with system robots. The four robots should have duty
cycles of 100%, 50%, 33%, and 25% based on the number
of ticks that they `wait`.
objectives:
- goal:
- |
Expand Down Expand Up @@ -31,6 +35,58 @@ robots:
- comparator
- hourglass
- branch predictor
- name: idler1
dir: [1, 0]
system: true
devices:
- dictionary
- strange loop
- hourglass
program: |
def go =
wait 1;
go;
end;
go;
- name: idler2
dir: [1, 0]
system: true
devices:
- dictionary
- strange loop
- hourglass
program: |
def go =
wait 2;
go;
end;
go;
- name: idler3
dir: [1, 0]
system: true
devices:
- dictionary
- strange loop
- hourglass
program: |
def go =
wait 3;
go;
end;
go;
- name: idler4
dir: [1, 0]
system: true
devices:
- dictionary
- strange loop
- hourglass
program: |
def go =
wait 4;
go;
end;
go;
known: [flower, tree]
world:
default: [blank]
Expand All @@ -39,8 +95,13 @@ world:
'f': [grass, flower]
'T': [grass, tree]
'B': [grass, null, base]
'1': [grass, null, idler1]
'2': [grass, null, idler2]
'3': [grass, null, idler3]
'4': [grass, null, idler4]
upperleft: [-1, 1]
map: |
.......
.B.fff.
...T...
........1
.B.fff..2
...T....3
........4
11 changes: 10 additions & 1 deletion src/Swarm/Game/Robot.hs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ module Swarm.Game.Robot (
tangibleCommandCount,
commandsHistogram,
lifetimeStepCount,
activityWindow,

-- ** Creation & instantiation
mkRobot,
Expand Down Expand Up @@ -110,6 +111,7 @@ import Swarm.Language.Typed (Typed (..))
import Swarm.Language.Types (TCtx)
import Swarm.Language.Value as V
import Swarm.Util.Lens (makeLensesExcluding, makeLensesNoSigs)
import Swarm.Util.WindowedCounter
import Swarm.Util.Yaml
import System.Clock (TimeSpec)

Expand Down Expand Up @@ -177,6 +179,7 @@ data ActivityCounts = ActivityCounts
, _tangibleCommandCount :: Int
, _commandsHistogram :: Map Const Int
, _lifetimeStepCount :: Int
, _activityWindow :: WindowedCounter Integer
}
deriving (Eq, Show, Generic, FromJSON, ToJSON)

Expand Down Expand Up @@ -226,14 +229,17 @@ tickStepBudget :: Lens' ActivityCounts Int
-- | Total number of tangible commands executed over robot's lifetime
tangibleCommandCount :: Lens' ActivityCounts Int

-- | Total number of commands executed over robot's lifetime
-- | Histogram of commands executed over robot's lifetime
commandsHistogram :: Lens' ActivityCounts (Map Const Int)

-- | Total number of CESK steps executed over robot's lifetime.
-- This could be thought of as "CPU cycles" consumed, and is labeled
-- as "cycles" in the F2 dialog in the UI.
lifetimeStepCount :: Lens' ActivityCounts Int

-- | Sliding window over a span of ticks indicating ratio of activity
activityWindow :: Lens' ActivityCounts (WindowedCounter Integer)

-- | With a robot template, we may or may not have a location. With a
-- concrete robot we must have a location.
type family RobotLocation (phase :: RobotPhase) :: Data.Kind.Type where
Expand Down Expand Up @@ -523,6 +529,9 @@ mkRobot rid pid name descr loc dir disp m devs inv sys heavy ts =
, _tangibleCommandCount = 0
, _commandsHistogram = mempty
, _lifetimeStepCount = 0
, -- NOTE: This value was chosen experimentally.
-- TODO(#1341): Make this dynamic based on game speed.
_activityWindow = mkWindow 64
}
, _runningAtomic = False
}
Expand Down
3 changes: 3 additions & 0 deletions src/Swarm/Game/Step.hs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ import Swarm.Language.Typed (Typed (..))
import Swarm.Language.Value
import Swarm.Util hiding (both)
import Swarm.Util.Effect (throwToMaybe)
import Swarm.Util.WindowedCounter qualified as WC
import System.Clock (TimeSpec)
import Witch (From (from), into)
import Prelude hiding (Applicative (..), lookup)
Expand Down Expand Up @@ -523,10 +524,12 @@ stepRobot :: (Has (State GameState) sig m, Has (Lift IO) sig m) => Robot -> m Ro
stepRobot r = do
(r', cesk') <- runState (r & activityCounts . tickStepBudget -~ 1) (stepCESK (r ^. machine))
-- sendIO $ appendFile "out.txt" (prettyString cesk' ++ "\n")
TickNumber t <- use ticks
return $
r'
& machine .~ cesk'
& activityCounts . lifetimeStepCount +~ 1
& (activityCounts . activityWindow %~ WC.insert t)

-- | replace some entity in the world with another entity
updateWorld ::
Expand Down
2 changes: 1 addition & 1 deletion src/Swarm/TUI/Editor/View.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ import Swarm.Game.Scenario.Topography.EntityFacade
import Swarm.Game.Terrain (TerrainType)
import Swarm.Game.Universe
import Swarm.Game.World qualified as W
import Swarm.TUI.Attr
import Swarm.TUI.Border
import Swarm.TUI.Editor.Model
import Swarm.TUI.Model
import Swarm.TUI.Model.Name
import Swarm.TUI.Model.UI
import Swarm.TUI.Panel
import Swarm.TUI.View.Attribute.Attr
import Swarm.TUI.View.CellDisplay (renderDisplay)
import Swarm.TUI.View.Util qualified as VU
import Swarm.Util (listEnums)
Expand Down
2 changes: 1 addition & 1 deletion src/Swarm/TUI/Launch/View.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ import Data.Text qualified as T
import Swarm.Game.Scenario (scenarioSeed)
import Swarm.Game.Scenario.Status (ParameterizableLaunchParams (..))
import Swarm.Game.State (getRunCodePath)
import Swarm.TUI.Attr
import Swarm.TUI.Launch.Model
import Swarm.TUI.Launch.Prep
import Swarm.TUI.Model.Name
import Swarm.TUI.View.Attribute.Attr
import Swarm.TUI.View.Util (EllipsisSide (Beginning), withEllipsis)
import Swarm.Util (brackets, parens)

Expand Down
4 changes: 2 additions & 2 deletions src/Swarm/TUI/Model/StateUpdate.hs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ import Swarm.Game.ScenarioInfo (
)
import Swarm.Game.State
import Swarm.Language.Pretty (prettyText)
import Swarm.TUI.Attr (swarmAttrMap)
import Swarm.TUI.Editor.Model qualified as EM
import Swarm.TUI.Editor.Util qualified as EU
import Swarm.TUI.Inventory.Sorting
Expand All @@ -67,7 +66,8 @@ import Swarm.TUI.Model
import Swarm.TUI.Model.Goal (emptyGoalDisplay)
import Swarm.TUI.Model.Repl
import Swarm.TUI.Model.UI
import Swarm.TUI.View.CustomStyling (toAttrPair)
import Swarm.TUI.View.Attribute.Attr (swarmAttrMap)
import Swarm.TUI.View.Attribute.CustomStyling (toAttrPair)
import Swarm.Util.Effect (asExceptT, withThrow)
import System.Clock

Expand Down
2 changes: 1 addition & 1 deletion src/Swarm/TUI/Model/UI.hs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ import Swarm.Game.ScenarioInfo (
)
import Swarm.Game.Universe
import Swarm.Game.World qualified as W
import Swarm.TUI.Attr (swarmAttrMap)
import Swarm.TUI.Editor.Model
import Swarm.TUI.Inventory.Sorting
import Swarm.TUI.Launch.Model
Expand All @@ -85,6 +84,7 @@ import Swarm.TUI.Model.Goal
import Swarm.TUI.Model.Menu
import Swarm.TUI.Model.Name
import Swarm.TUI.Model.Repl
import Swarm.TUI.View.Attribute.Attr (swarmAttrMap)
import Swarm.Util
import Swarm.Util.Lens (makeLensesExcluding)
import System.Clock
Expand Down
41 changes: 34 additions & 7 deletions src/Swarm/TUI/View.hs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import Data.Text qualified as T
import Data.Time (NominalDiffTime, defaultTimeLocale, formatTime)
import Linear
import Network.Wai.Handler.Warp (Port)
import Numeric (fromRat, showFFloat)
import Swarm.Constant
import Swarm.Game.CESK (CESK (..), TickNumber (..))
import Swarm.Game.Display
Expand All @@ -93,7 +94,6 @@ import Swarm.Language.Capability (Capability (..), constCaps)
import Swarm.Language.Pretty (prettyText)
import Swarm.Language.Syntax
import Swarm.Language.Typecheck (inferConst)
import Swarm.TUI.Attr
import Swarm.TUI.Border
import Swarm.TUI.Controller (ticksPerFrameCap)
import Swarm.TUI.Editor.Model
Expand All @@ -107,10 +107,12 @@ import Swarm.TUI.Model.Repl (lastEntry)
import Swarm.TUI.Model.UI
import Swarm.TUI.Panel
import Swarm.TUI.View.Achievement
import Swarm.TUI.View.Attribute.Attr
import Swarm.TUI.View.CellDisplay
import Swarm.TUI.View.Objective qualified as GR
import Swarm.TUI.View.Util as VU
import Swarm.Util
import Swarm.Util.WindowedCounter qualified as WC
import Swarm.Version (NewReleaseFailure (..))
import System.Clock (TimeSpec (..))
import Text.Printf
Expand Down Expand Up @@ -606,13 +608,18 @@ drawModal s = \case
DescriptionModal e -> descriptionWidget s e
QuitModal -> padBottom (Pad 1) $ hCenter $ txt (quitMsg (s ^. uiState . uiMenu))
GoalModal -> GR.renderGoalsDisplay (s ^. uiState . uiGoal)
KeepPlayingModal -> padLeftRight 1 (displayParagraphs ["Have fun! Hit Ctrl-Q whenever you're ready to proceed to the next challenge or return to the menu."])
KeepPlayingModal ->
padLeftRight 1 $
displayParagraphs $
pure
"Have fun! Hit Ctrl-Q whenever you're ready to proceed to the next challenge or return to the menu."
TerrainPaletteModal -> EV.drawTerrainSelector s
EntityPaletteModal -> EV.drawEntityPaintSelector s

robotsListWidget :: AppState -> Widget Name
robotsListWidget s = hCenter table
where
TickNumber curTicks = s ^. gameState . ticks
table =
BT.renderTable
. BT.columnBorders False
Expand All @@ -630,6 +637,7 @@ robotsListWidget s = hCenter table
, "Actions"
, "Commands"
, "Cycles"
, "Activity"
, "Log"
]
headers = withAttr robotAttr . txt <$> applyWhen cheat ("ID" :) headings
Expand All @@ -644,12 +652,32 @@ robotsListWidget s = hCenter table
, padRight (Pad 1) (str $ show rInvCount)
, statusWidget
, str $ show $ robot ^. activityCounts . tangibleCommandCount
, str . show . sum . M.elems $ robot ^. activityCounts . commandsHistogram
, -- TODO(#1341): May want to expose the details of this histogram in
-- a per-robot pop-up
str . show . sum . M.elems $ robot ^. activityCounts . commandsHistogram
, str $ show $ robot ^. activityCounts . lifetimeStepCount
, dutyCycleDisplay
, txt rLog
]

dutyCycleAttrIdx = floor $ dutyCycleRatio * fromIntegral (length meterAttributeNames - 1)
dutyCycleAttr = meterAttributeNames !! dutyCycleAttrIdx
dutyCycleDisplay = withAttr dutyCycleAttr . str . flip (showFFloat (Just 1)) "%" $ dutyCyclePercentage

dutyCycleRatio =
WC.getOccupancy curTicks $
robot ^. activityCounts . activityWindow

dutyCyclePercentage :: Double
dutyCyclePercentage = fromRat . (100 *) $ dutyCycleRatio

idWidget = str $ show $ robot ^. robotID
nameWidget = hBox [renderDisplay (robot ^. robotDisplay), highlightSystem . txt $ " " <> robot ^. robotName]
nameWidget =
hBox
[ renderDisplay (robot ^. robotDisplay)
, highlightSystem . txt $ " " <> robot ^. robotName
]

highlightSystem = if robot ^. systemRobot then withAttr highlightAttr else id

ageStr
Expand Down Expand Up @@ -856,9 +884,8 @@ colorLogs e = case e ^. leSource of
Critical -> redAttr
where
-- color each robot message with different color of the world
robotColor rid = fgCols !! (rid `mod` fgColLen)
fgCols = map fst worldAttributes
fgColLen = length fgCols
robotColor rid = worldAttributeNames !! (rid `mod` fgColLen)
fgColLen = length worldAttributeNames

-- | Draw the F-key modal menu. This is displayed in the top left world corner.
drawModalMenu :: AppState -> Widget Name
Expand Down
2 changes: 1 addition & 1 deletion src/Swarm/TUI/View/Achievement.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import Data.Time.Format (defaultTimeLocale, formatTime)
import Swarm.Game.Achievement.Attainment
import Swarm.Game.Achievement.Definitions
import Swarm.Game.Achievement.Description
import Swarm.TUI.Attr
import Swarm.TUI.Model
import Swarm.TUI.Model.UI
import Swarm.TUI.View.Attribute.Attr
import Text.Wrap

padAllEvenly :: Int -> Widget Name -> Widget Name
Expand Down

0 comments on commit 7d246ec

Please sign in to comment.