packages feed

swarm 0.3.0.0 → 0.3.0.1

raw patch · 8 files changed

+75/−26 lines, 8 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -1,5 +1,13 @@ # Revision history for swarm +## **0.3.0.1** - 2023-02-01++A few critical bug fixes and improvements:++* Make sure the base always has a `logger` installed in every tutorial level, by @byorgey in [#1067](https://github.com/swarm-game/swarm/pull/1067) and @xsebek in [#1073](https://github.com/swarm-game/swarm/pull/1073)+* Allow dialog boxes to scroll by @byorgey in [#1071](https://github.com/swarm-game/swarm/pull/1071)+* Fix bug that sometimes caused scenarios to be skipped or repeated by @byorgey in [#1065](https://github.com/swarm-game/swarm/pull/1065)+ ## **0.3.0.0** - 2023-01-30  This is the first release of 2023! It contains:
data/scenarios/Tutorials/backstory.yaml view
@@ -62,6 +62,8 @@     loc: [0,0]     inventory:       - [1, READY]+    devices:+      - logger   - name: listener     system: true     display:
data/scenarios/Tutorials/bind2.yaml view
@@ -77,10 +77,12 @@       attr: robot     devices:       - 3D printer+      - logger     inventory:       - [1, solar panel]       - [1, treads]       - [1, grabber]+      - [1, compass]   - name: floorspot     system: true   - name: pedestal
data/scenarios/Tutorials/require.yaml view
@@ -56,6 +56,7 @@       - [10, boat]       - [10, grabber]       - [10, scanner]+      - [10, compass] known: [water] world:   default: [blank]
src/Swarm/TUI/Controller.hs view
@@ -189,6 +189,10 @@   _ -> error "No tutorials exist!"  -- | If we are in a New Game menu, advance the menu to the next item in order.+--+--   NOTE: be careful to maintain the invariant that the currently selected+--   menu item is always the same as the currently played scenario!  `quitGame`+--   is the only place this function should be called. advanceMenu :: Menu -> Menu advanceMenu = _NewGameMenu . ix 0 %~ BL.listMoveDown @@ -401,7 +405,7 @@       Just (Button QuitButton, _) -> quitGame       Just (Button KeepPlayingButton, _) -> toggleModal KeepPlayingModal       Just (Button StartOverButton, StartOver currentSeed siPair) -> restartGame currentSeed siPair-      Just (Button NextButton, Next siPair) -> saveScenarioInfoOnQuit >> startGame siPair Nothing+      Just (Button NextButton, Next siPair) -> quitGame >> startGame siPair Nothing       _ -> return ()   ev -> do     Brick.zoom (uiState . uiModal . _Just . modalDialog) (handleDialogEvent ev)@@ -419,7 +423,7 @@                 uiState . uiGoal . listWidget .= newList               GoalSummary -> handleInfoPanelEvent modalScroll (VtyEvent ev)             _ -> handleInfoPanelEvent modalScroll (VtyEvent ev)-      _ -> return ()+      _ -> handleInfoPanelEvent modalScroll (VtyEvent ev)    where     refreshList lw = nestEventM' lw $ handleListEventWithSeparators ev isHeader @@ -470,13 +474,28 @@ -- -- * writes out the updated REPL history to a @.swarm_history@ file -- * saves current scenario status (InProgress/Completed)+-- * advances the menu to the next scenario IF the current one was won -- * returns to the previous menu quitGame :: EventM Name AppState () quitGame = do+  -- Write out REPL history.   history <- use $ uiState . uiREPL . replHistory   let hist = mapMaybe getREPLEntry $ getLatestREPLHistoryItems maxBound history   liftIO $ (`T.appendFile` T.unlines hist) =<< getSwarmHistoryPath True++  -- Save scenario status info.   saveScenarioInfoOnQuit++  -- Automatically advance the menu to the next scenario iff the+  -- player has won the current one.+  wc <- use $ gameState . winCondition+  case wc of+    WinConditions (Won _) _ -> uiState . uiMenu %= advanceMenu+    _ -> return ()++  -- Either quit the entire app (if the scenario was chosen directly+  -- from the command line) or return to the menu (if the scenario was+  -- chosen from the menu).   menu <- use $ uiState . uiMenu   case menu of     NoMenu -> halt@@ -759,14 +778,19 @@       gameState . winCondition .= WinConditions (Unwinnable True) x       openModal LoseModal -      uiState . uiMenu %= advanceMenu       return True     WinConditions (Won False) x -> do       -- This clears the "flag" that the Win dialog needs to pop up       gameState . winCondition .= WinConditions (Won True) x       openModal WinModal -      uiState . uiMenu %= advanceMenu+      -- We do NOT advance the New Game menu to the next item here (we+      -- used to!), because we do not know if the user is going to+      -- select 'keep playing' or 'next challenge'.  We maintain the+      -- invariant that the current menu item is always the same as+      -- the scenario currently being played.  If the user either (1)+      -- quits to the menu or (2) selects 'next challenge' we will+      -- advance the menu at that point.       return True     WinConditions _ oc -> do       let newGoalTracking = GoalTracking announcementsList $ constructGoalMap isCheating oc
src/Swarm/TUI/Model/Menu.hs view
@@ -74,7 +74,11 @@ data Menu   = NoMenu -- We started playing directly from command line, no menu to show   | MainMenu (BL.List Name MainMenuEntry)-  | NewGameMenu (NonEmpty (BL.List Name ScenarioItem)) -- stack of scenario item lists+  | -- Stack of scenario item lists. INVARIANT: the currently selected+    -- menu item is ALWAYS the same as the scenario currently being played.+    -- See https://github.com/swarm-game/swarm/issues/1064 and+    -- https://github.com/swarm-game/swarm/pull/1065.+    NewGameMenu (NonEmpty (BL.List Name ScenarioItem))   | AchievementsMenu (BL.List Name CategorizedAchievement)   | MessagesMenu   | AboutMenu
swarm.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.4 name:               swarm-version:            0.3.0.0+version:            0.3.0.1 synopsis:           2D resource gathering game with programmable robots  description:        Swarm is a 2D programming and resource gathering
test/integration/Main.hs view
@@ -24,8 +24,8 @@ import Swarm.DocGen (EditorType (..)) import Swarm.DocGen qualified as DocGen import Swarm.Game.CESK (emptyStore, initMachine)-import Swarm.Game.Entity (EntityMap, loadEntities)-import Swarm.Game.Robot (LogEntry, defReqs, leText, machine, robotContext, robotLog, waitingUntil)+import Swarm.Game.Entity (EntityMap, loadEntities, lookupByName)+import Swarm.Game.Robot (LogEntry, defReqs, equippedDevices, leText, machine, robotContext, robotLog, waitingUntil) import Swarm.Game.Scenario (Scenario) import Swarm.Game.State (   GameState,@@ -155,28 +155,28 @@     "Test scenario solutions"     [ testGroup         "Tutorial"-        [ testSolution Default "Tutorials/backstory"-        , testSolution (Sec 3) "Tutorials/move"-        , testSolution Default "Tutorials/craft"-        , testSolution Default "Tutorials/grab"-        , testSolution Default "Tutorials/place"-        , testSolution Default "Tutorials/types"-        , testSolution Default "Tutorials/type-errors"-        , testSolution Default "Tutorials/equip"-        , testSolution Default "Tutorials/build"-        , testSolution Default "Tutorials/bind2"-        , testSolution' Default "Tutorials/crash" CheckForBadErrors $ \g -> do+        [ testTutorialSolution Default "Tutorials/backstory"+        , testTutorialSolution (Sec 3) "Tutorials/move"+        , testTutorialSolution Default "Tutorials/craft"+        , testTutorialSolution Default "Tutorials/grab"+        , testTutorialSolution Default "Tutorials/place"+        , testTutorialSolution Default "Tutorials/types"+        , testTutorialSolution Default "Tutorials/type-errors"+        , testTutorialSolution Default "Tutorials/equip"+        , testTutorialSolution Default "Tutorials/build"+        , testTutorialSolution Default "Tutorials/bind2"+        , testTutorialSolution' Default "Tutorials/crash" CheckForBadErrors $ \g -> do             let rs = toList $ g ^. robotMap             let hints = any (T.isInfixOf "you will win" . view leText) . toList . view robotLog             let win = isJust $ find hints rs             assertBool "Could not find a robot with winning instructions!" win-        , testSolution Default "Tutorials/scan"-        , testSolution Default "Tutorials/def"-        , testSolution Default "Tutorials/lambda"-        , testSolution Default "Tutorials/require"-        , testSolution (Sec 3) "Tutorials/requireinv"-        , testSolution Default "Tutorials/conditionals"-        , testSolution (Sec 5) "Tutorials/farming"+        , testTutorialSolution Default "Tutorials/scan"+        , testTutorialSolution Default "Tutorials/def"+        , testTutorialSolution Default "Tutorials/lambda"+        , testTutorialSolution Default "Tutorials/require"+        , testTutorialSolution (Sec 3) "Tutorials/requireinv"+        , testTutorialSolution Default "Tutorials/conditionals"+        , testTutorialSolution (Sec 5) "Tutorials/farming"         ]     , testGroup         "Challenges"@@ -289,6 +289,14 @@               -- printAllLogs               when (shouldCheckBadErrors == CheckForBadErrors) $ noBadErrors g               verify g++  tutorialHasLog :: GameState -> Assertion+  tutorialHasLog gs =+    let baseDevs = gs ^?! baseRobot . equippedDevices+     in assertBool "Base should have a logger installed!" (not . null $ lookupByName "logger" baseDevs)++  testTutorialSolution t f = testSolution' t f CheckForBadErrors tutorialHasLog+  testTutorialSolution' t f s v = testSolution' t f s $ \g -> tutorialHasLog g >> v g    playUntilWin :: StateT GameState IO ()   playUntilWin = do