Skip to content

Commit

Permalink
goal dialog suppression with --autoplay (#1344)
Browse files Browse the repository at this point in the history
Closes #1340.

Compare:

    scripts/play.sh --scenario data/scenarios/Challenges/blender.yaml --run data/scenarios/Challenges/_blender/solution.sw

vs.

    scripts/play.sh --scenario data/scenarios/Challenges/blender.yaml --autoplay
  • Loading branch information
kostmo authored Jun 25, 2023
1 parent 31c4844 commit e8a77d6
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 24 deletions.
17 changes: 14 additions & 3 deletions src/Swarm/Game/State.hs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ module Swarm.Game.State (
notificationsCount,
notificationsContent,

-- ** Launch parameters
LaunchParams,
ValidatedLaunchParams,

-- ** GameState initialization
GameStateConfig (..),
initGameState,
Expand Down Expand Up @@ -164,6 +168,7 @@ import Swarm.Game.Recipe (
)
import Swarm.Game.Robot
import Swarm.Game.Scenario.Objective
import Swarm.Game.Scenario.Status
import Swarm.Game.ScenarioInfo
import Swarm.Game.Terrain (TerrainType (..))
import Swarm.Game.World (Coords (..), WorldFun (..), locToCoords, worldFunFromArray)
Expand Down Expand Up @@ -941,6 +946,13 @@ deleteRobot rn = do
-- Initialization
------------------------------------------------------------

type LaunchParams a = ParameterizableLaunchParams CodeToRun a

-- | In this stage in the UI pipeline, both fields
-- have already been validated, and "Nothing" means
-- that the field is simply absent.
type ValidatedLaunchParams = LaunchParams Identity

-- | Record to pass information needed to create an initial
-- 'GameState' record when starting a scenario.
data GameStateConfig = GameStateConfig
Expand Down Expand Up @@ -1001,11 +1013,10 @@ initGameState gsc =
-- | Create an initial game state corresponding to the given scenario.
scenarioToGameState ::
Scenario ->
Maybe Seed ->
Maybe CodeToRun ->
ValidatedLaunchParams ->
GameStateConfig ->
IO GameState
scenarioToGameState scenario userSeed toRun gsc = do
scenarioToGameState scenario (LaunchParams (Identity userSeed) (Identity toRun)) gsc = do
-- Decide on a seed. In order of preference, we will use:
-- 1. seed value provided by the user
-- 2. seed value specified in the scenario description
Expand Down
12 changes: 10 additions & 2 deletions src/Swarm/TUI/Controller.hs
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,13 @@ updateUI = do

goalOrWinUpdated <- doGoalUpdates

let redraw = g ^. needsRedraw || inventoryUpdated || replUpdated || logUpdated || infoPanelUpdated || goalOrWinUpdated
let redraw =
g ^. needsRedraw
|| inventoryUpdated
|| replUpdated
|| logUpdated
|| infoPanelUpdated
|| goalOrWinUpdated
pure redraw

-- | Either pops up the updated Goals modal
Expand Down Expand Up @@ -942,7 +948,9 @@ doGoalUpdates = do
-- automatically popped up.
gameState . announcementQueue .= mempty

openModal GoalModal
isAutoplaying <- use $ uiState . uiIsAutoplay
unless isAutoplaying $
openModal GoalModal

return goalWasUpdated

Expand Down
9 changes: 1 addition & 8 deletions src/Swarm/TUI/Launch/Model.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,13 @@ import Control.Lens (makeLenses)
import Data.Functor.Identity (Identity (Identity))
import Data.Text (Text)
import Swarm.Game.Scenario.Status (ParameterizableLaunchParams (LaunchParams), ScenarioInfoPair, SerializableLaunchParams)
import Swarm.Game.State (CodeToRun, getRunCodePath, parseCodeFile)
import Swarm.Game.State (CodeToRun, LaunchParams, ValidatedLaunchParams, getRunCodePath, parseCodeFile)
import Swarm.TUI.Model.Name

type LaunchParams a = ParameterizableLaunchParams CodeToRun a

-- | Use this to store error messages
-- on individual fields
type EditingLaunchParams = LaunchParams (Either Text)

-- | In this stage in the UI pipeline, both fields
-- have already been validated, and "Nothing" means
-- that the field is simply absent.
type ValidatedLaunchParams = LaunchParams Identity

toSerializableParams :: ValidatedLaunchParams -> SerializableLaunchParams
toSerializableParams (LaunchParams seedValue (Identity codeToRun)) =
LaunchParams seedValue $ pure $ getRunCodePath =<< codeToRun
Expand Down
2 changes: 1 addition & 1 deletion src/Swarm/TUI/Launch/Prep.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.Functor.Identity (runIdentity)
import Data.Text qualified as T
import Swarm.Game.Scenario.Status (ParameterizableLaunchParams (..), ScenarioInfoPair, getLaunchParams, scenarioStatus)
import Swarm.Game.State (Seed, getRunCodePath)
import Swarm.Game.State (Seed, ValidatedLaunchParams, getRunCodePath)
import Swarm.TUI.Launch.Model
import Swarm.TUI.Model.Name
import Swarm.Util (listEnums)
Expand Down
29 changes: 19 additions & 10 deletions src/Swarm/TUI/Model/StateUpdate.hs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ 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
import Swarm.TUI.Launch.Model (ValidatedLaunchParams, toSerializableParams)
import Swarm.TUI.Launch.Model (toSerializableParams)
import Swarm.TUI.Model
import Swarm.TUI.Model.Goal (emptyGoalDisplay)
import Swarm.TUI.Model.Repl
Expand Down Expand Up @@ -110,7 +110,7 @@ startGameWithSeed ::
ScenarioInfoPair ->
ValidatedLaunchParams ->
m ()
startGameWithSeed siPair@(_scene, si) lp@(LaunchParams (Identity userSeed) (Identity toRun)) = do
startGameWithSeed siPair@(_scene, si) lp = do
t <- liftIO getZonedTime
ss <- use $ runtimeState . scenarios
p <- liftIO $ normalizeScenarioPath ss (si ^. scenarioPath)
Expand All @@ -124,7 +124,7 @@ startGameWithSeed siPair@(_scene, si) lp@(LaunchParams (Identity userSeed) (Iden
(toSerializableParams lp)
(Metric Attempted $ ProgressStats t emptyAttemptMetric)
(prevBest t)
scenarioToAppState siPair userSeed toRun
scenarioToAppState siPair lp
-- Beware: currentScenarioPath must be set so that progress/achievements can be saved.
-- It has just been cleared in scenarioToAppState.
gameState . currentScenarioPath .= Just p
Expand All @@ -137,15 +137,18 @@ startGameWithSeed siPair@(_scene, si) lp@(LaunchParams (Identity userSeed) (Iden
scenarioToAppState ::
(MonadIO m, MonadState AppState m) =>
ScenarioInfoPair ->
Maybe Seed ->
Maybe CodeToRun ->
ValidatedLaunchParams ->
m ()
scenarioToAppState siPair@(scene, _) userSeed toRun = do
scenarioToAppState siPair@(scene, _) lp = do
rs <- use runtimeState
gs <- liftIO $ scenarioToGameState scene userSeed toRun (mkGameStateConfig rs)
gs <- liftIO $ scenarioToGameState scene lp $ mkGameStateConfig rs
gameState .= gs
void $ withLensIO uiState $ scenarioToUIState siPair gs
void $ withLensIO uiState $ scenarioToUIState isAutoplaying siPair gs
where
isAutoplaying = case runIdentity (initialCode lp) of
Just (CodeToRun ScenarioSuggested _) -> True
_ -> False

withLensIO :: (MonadIO m, MonadState AppState m) => Lens' AppState x -> (x -> IO x) -> m x
withLensIO l a = do
x <- use l
Expand Down Expand Up @@ -174,13 +177,19 @@ attainAchievement' t p a = do
liftIO $ saveAchievementsInfo $ M.elems newAchievements

-- | Modify the UI state appropriately when starting a new scenario.
scenarioToUIState :: ScenarioInfoPair -> GameState -> UIState -> IO UIState
scenarioToUIState siPair@(scenario, _) gs u = do
scenarioToUIState ::
Bool ->
ScenarioInfoPair ->
GameState ->
UIState ->
IO UIState
scenarioToUIState isAutoplaying siPair@(scenario, _) gs u = do
curTime <- getTime Monotonic
return $
u
& uiPlaying .~ True
& uiGoal .~ emptyGoalDisplay
& uiIsAutoplay .~ isAutoplaying
& uiFocusRing .~ initFocusRing
& uiInventory .~ Nothing
& uiInventorySort .~ defaultSortOptions
Expand Down
6 changes: 6 additions & 0 deletions src/Swarm/TUI/Model/UI.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ module Swarm.TUI.Model.UI (
uiError,
uiModal,
uiGoal,
uiIsAutoplay,
uiAchievements,
lgTicksPerSecond,
lastFrameTime,
Expand Down Expand Up @@ -111,6 +112,7 @@ data UIState = UIState
, _uiError :: Maybe Text
, _uiModal :: Maybe Modal
, _uiGoal :: GoalDisplay
, _uiIsAutoplay :: Bool
, _uiAchievements :: Map CategorizedAchievement Attainment
, _uiShowFPS :: Bool
, _uiShowREPL :: Bool
Expand Down Expand Up @@ -197,6 +199,9 @@ uiModal :: Lens' UIState (Maybe Modal)
-- has been displayed to the user initially.
uiGoal :: Lens' UIState GoalDisplay

-- | When running with --autoplay, suppress the goal dialogs
uiIsAutoplay :: Lens' UIState Bool

-- | Map of achievements that were attained
uiAchievements :: Lens' UIState (Map CategorizedAchievement Attainment)

Expand Down Expand Up @@ -326,6 +331,7 @@ initUIState speedFactor showMainMenu cheatMode = do
, _uiError = Nothing
, _uiModal = Nothing
, _uiGoal = emptyGoalDisplay
, _uiIsAutoplay = False
, _uiAchievements = M.fromList $ map (view achievement &&& id) achievements
, _uiShowFPS = False
, _uiShowREPL = True
Expand Down

0 comments on commit e8a77d6

Please sign in to comment.