From 818385c842c137d106d3e9a2a0cbfaca21a97a95 Mon Sep 17 00:00:00 2001 From: Jesse McDonald Date: Sat, 18 Jul 2015 18:25:33 -0500 Subject: [PATCH 1/2] update to build with GHC 7.10.1 and stack 0.1 --- .gitignore | 1 + src/Waterdeep/Actions.hs | 37 +++++++++++++++++++++++-------------- src/Waterdeep/Util.hs | 6 +----- stack.yaml | 6 ++++++ waterdeep.cabal | 12 ++++++------ 5 files changed, 37 insertions(+), 25 deletions(-) create mode 100644 stack.yaml diff --git a/.gitignore b/.gitignore index c434a52..6780ee4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ *.hi *.o dist/ +.stack-work/ diff --git a/src/Waterdeep/Actions.hs b/src/Waterdeep/Actions.hs index c3047ed..1ece071 100644 --- a/src/Waterdeep/Actions.hs +++ b/src/Waterdeep/Actions.hs @@ -61,7 +61,7 @@ import Data.Maybe import Data.Monoid import Data.Foldable (foldMap, forM_, mapM_) import Data.Traversable (traverse, for, forM, mapM) -import Lens.Family2 +import Lens.Family2 hiding ((&)) import Lens.Family2.State import Lens.Family2.Stock import Prelude hiding (forM, mapM) @@ -307,10 +307,11 @@ returnAgent :: GameAction returnAgent = do w <- get let p = w^.gameActivePlayer - let buildings = flip foldMapBuildings w $ \_ bl -> - let agents = w^.bl.buildingAgents - title = w^.bl.building.buildingTitle - in mif (p `elem` agents) [(title, bl.buildingAgents %= (\\[p]))] + let buildings = foldMapBuildings f w + f :: Bool -> Lens' WaterdeepState BuildingState -> [(String, GameAction)] + f _ bl = mif (p `elem` agents) [(title, bl.buildingAgents %= (\\[p]))] + where agents = w^.bl.buildingAgents + title = w^.bl.building.buildingTitle join $ solicitChoice "Recall an agent from:" $ nubOn fst buildings activePlayerState . playerAgentsInPool += 1 @@ -368,7 +369,9 @@ assignAmbassador = do let includesOpponent = any (`elem` opponents) let usedOpSpace = (activePlayerState . playerCanUseOpSpace .= False) let canUseOpSpace = w ^. activePlayerState . playerCanUseOpSpace - let buildings = flip foldMapBuildings w $ \inHall bl -> + let buildings = foldMapBuildings f w + f :: Bool -> Lens' WaterdeepState BuildingState -> [(String, GameAction)] + f inHall bl = let agents = w^.bl.buildingAgents title = w^.bl.building.buildingTitle in if | canUseOpSpace && includesOpponent agents -> @@ -388,7 +391,9 @@ assignAgent = do let includesOpponent = any (`elem` opponents) let usedOpSpace = (activePlayerState . playerCanUseOpSpace .= False) let canUseOpSpace = w ^. activePlayerState . playerCanUseOpSpace - let buildings = flip foldMapBuildings w $ \inHall bl -> + let buildings = foldMapBuildings f w + f :: Bool -> Lens' WaterdeepState BuildingState -> [(String, GameAction)] + f inHall bl = let agents = w^.bl.buildingAgents title = w^.bl.building.buildingTitle in if | canUseOpSpace && includesOpponent agents -> @@ -408,7 +413,9 @@ assignAgentToBuildersHall = do let includesOpponent = any (`elem` opponents) let usedOpSpace = (activePlayerState . playerCanUseOpSpace .= False) let canUseOpSpace = w ^. activePlayerState . playerCanUseOpSpace - let buildings = flip foldMapBuildings w $ \inHall bl -> mif inHall $ + let buildings = foldMapBuildings f w + f :: Bool -> Lens' WaterdeepState BuildingState -> [(String, GameAction)] + f inHall bl = mif inHall $ let agents = w^.bl.buildingAgents title = w^.bl.building.buildingTitle in if null agents @@ -426,9 +433,10 @@ assignAgentToOpponentsSpace = do let p = w^.gameActivePlayer let opponents = (w^..gamePlayerStates.traverse.playerNumber) \\ [p] let includesOpponent = any (`elem` opponents) - let buildings = flip foldMapBuildings w $ \inHall bl -> - mif (includesOpponent (w^.bl.buildingAgents)) $ - [(w^.bl.building.buildingTitle, assignAgentToBuilding p bl)] + let buildings = foldMapBuildings f w + f :: Bool -> Lens' WaterdeepState BuildingState -> [(String, GameAction)] + f inHall bl = mif (includesOpponent (w^.bl.buildingAgents)) $ + [(w^.bl.building.buildingTitle, assignAgentToBuilding p bl)] join $ solicitChoice "Assign an agent to:" $ nubOn fst buildings useOpponentsSpace :: GameAction @@ -439,9 +447,10 @@ useOpponentsSpace = do let p = w^.gameActivePlayer let opponents = (w^..gamePlayerStates.traverse.playerNumber) \\ [p] let includesOpponent = any (`elem` opponents) - let buildings = flip foldMapBuildings w $ \inHall bl -> - mif (includesOpponent (w^.bl.buildingAgents)) $ - [(w^.bl.building.buildingTitle, useBuilding bl)] + let buildings = foldMapBuildings f w + f :: Bool -> Lens' WaterdeepState BuildingState -> [(String, GameAction)] + f inHall bl = mif (includesOpponent (w^.bl.buildingAgents)) $ + [(w^.bl.building.buildingTitle, useBuilding bl)] join $ solicitChoice "Use the effect of one building:" $ nubOn fst buildings gainLieutenant :: GameAction diff --git a/src/Waterdeep/Util.hs b/src/Waterdeep/Util.hs index a38e3e1..21be642 100644 --- a/src/Waterdeep/Util.hs +++ b/src/Waterdeep/Util.hs @@ -5,7 +5,6 @@ module Waterdeep.Util ( deleteAt , on , nubOn - , sortOn , countOf , singular , mif @@ -24,7 +23,7 @@ import Data.List import Data.Function import Data.Maybe import Data.Monoid -import Lens.Family2 +import Lens.Family2 hiding ((&)) import Lens.Family2.State import Lens.Family2.Stock @@ -37,9 +36,6 @@ deleteAt n l = left ++ drop 1 right nubOn :: Eq b => (a -> b) -> [a] -> [a] nubOn f = nubBy ((==) `on` f) -sortOn :: Ord b => (a -> b) -> [a] -> [a] -sortOn f = sortBy (compare `on` f) - countOf :: Num r => FoldLike (Sum r) a a' b b' -> (b -> Bool) -> a -> r countOf l f = getSum . views l (\b -> if f b then Sum 1 else Sum 0) diff --git a/stack.yaml b/stack.yaml new file mode 100644 index 0000000..96306a5 --- /dev/null +++ b/stack.yaml @@ -0,0 +1,6 @@ +flags: {} +packages: +- '.' +extra-deps: + - 'multiset-0.2.2' +resolver: nightly-2015-06-23 diff --git a/waterdeep.cabal b/waterdeep.cabal index a96f492..78dd283 100644 --- a/waterdeep.cabal +++ b/waterdeep.cabal @@ -25,16 +25,16 @@ executable waterdeep RankNTypes, TemplateHaskell, TupleSections - build-depends: base >=4.6 && <4.8, + build-depends: base >=4.6 && <4.9, MonadPrompt >=1.0 && <1.1, MonadRandom >=0.1 && <0.4, - containers >=0.5 && <0.6, + containers >=0.5.6.2 && <0.6, lens-family >=1.0 && <1.3, lens-family-th >=0.3 && <0.5, - mtl >=2.1 && <2.2, - multiset >=0.2 && <0.3, - random >=1.0 && <1.1, + mtl >=2.1 && <2.3, + multiset >= 0.2.2 && <0.3, + random >=1.0 && <1.2, random-shuffle >=0.0 && <0.1, - transformers >=0.3 && <0.4 + transformers >=0.3 && <0.5 hs-source-dirs: src default-language: Haskell2010 From fc9414f0725ef3d8480131cd31fd581ae47b93e4 Mon Sep 17 00:00:00 2001 From: Jesse McDonald Date: Sat, 18 Jul 2015 18:27:36 -0500 Subject: [PATCH 2/2] utility functions for constructing resource multisets --- src/Waterdeep/Intrigues.hs | 12 ++-- src/Waterdeep/Quests.hs | 120 ++++++++++++++++++------------------- src/Waterdeep/Types.hs | 12 ++++ 3 files changed, 78 insertions(+), 66 deletions(-) diff --git a/src/Waterdeep/Intrigues.hs b/src/Waterdeep/Intrigues.hs index 96690e1..9d1dd85 100644 --- a/src/Waterdeep/Intrigues.hs +++ b/src/Waterdeep/Intrigues.hs @@ -27,7 +27,7 @@ defaultIntrigueDeck = concat $ map (uncurry replicate) $ Quest { _questType = Mandatory , _questTitle = "Repel Drow Invaders" , _questQuote = "" - , _questCost = MS.fromList [Cleric, Rogue, Rogue] + , _questCost = clerics 1 <> rogues 2 , _questReward = scorePoints 2 , _questPlotActions = [] }) @@ -35,7 +35,7 @@ defaultIntrigueDeck = concat $ map (uncurry replicate) $ Quest { _questType = Mandatory , _questTitle = "Fend Off Bandits" , _questQuote = "" - , _questCost = MS.fromList [Fighter, Fighter, Wizard] + , _questCost = fighters 2 <> wizards 1 , _questReward = scorePoints 2 , _questPlotActions = [] }) @@ -43,7 +43,7 @@ defaultIntrigueDeck = concat $ map (uncurry replicate) $ Quest { _questType = Mandatory , _questTitle = "Foil the Zhentarim" , _questQuote = "" - , _questCost = MS.fromList [Fighter, Rogue, Wizard] + , _questCost = fighters 1 <> rogues 1 <> wizards 1 , _questReward = scorePoints 2 , _questPlotActions = [] }) @@ -51,7 +51,7 @@ defaultIntrigueDeck = concat $ map (uncurry replicate) $ Quest { _questType = Mandatory , _questTitle = "Stamp Out Cultists" , _questQuote = "" - , _questCost = MS.fromList [Cleric, Fighter, Rogue] + , _questCost = clerics 1 <> fighters 1 <> rogues 1 , _questReward = scorePoints 2 , _questPlotActions = [] }) @@ -59,7 +59,7 @@ defaultIntrigueDeck = concat $ map (uncurry replicate) $ Quest { _questType = Mandatory , _questTitle = "Placate Angry Merchants" , _questQuote = "" - , _questCost = MS.fromList [Cleric, Fighter, Wizard] + , _questCost = clerics 1 <> fighters 1 <> wizards 1 , _questReward = scorePoints 4 , _questPlotActions = [] }) @@ -67,7 +67,7 @@ defaultIntrigueDeck = concat $ map (uncurry replicate) $ Quest { _questType = Mandatory , _questTitle = "Quell Riots" , _questQuote = "" - , _questCost = MS.fromList [Cleric, Cleric, Fighter] + , _questCost = clerics 2 <> fighters 1 , _questReward = scorePoints 4 , _questPlotActions = [] }) diff --git a/src/Waterdeep/Quests.hs b/src/Waterdeep/Quests.hs index 835e0a3..fdd4ba8 100644 --- a/src/Waterdeep/Quests.hs +++ b/src/Waterdeep/Quests.hs @@ -24,7 +24,7 @@ defaultQuestDeck = [ Quest { _questType = Piety , _questTitle = "Recruit Paladins for Tyr" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 2), (Fighter, 4), (Gold, 4)] + , _questCost = clerics 2 <> fighters 4 <> gold 4 , _questReward = do scorePoints 10 takeResources 3 [Cleric] @@ -33,7 +33,7 @@ defaultQuestDeck = , Quest { _questType = Piety , _questTitle = "Defend the Tower of Luck" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 2), (Fighter, 1), (Rogue, 1), (Wizard, 1)] + , _questCost = clerics 2 <> fighters 1 <> rogues 1 <> wizards 1 , _questReward = do takeResources 1 [Cleric,Fighter,Rogue,Wizard] , _questPlotActions = @@ -42,7 +42,7 @@ defaultQuestDeck = , Quest { _questType = Piety , _questTitle = "Protect the House of Wonder" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 2), (Fighter, 1), (Gold, 2)] + , _questCost = clerics 2 <> fighters 1 <> gold 2 , _questReward = do scorePoints 8 , _questPlotActions = @@ -51,7 +51,7 @@ defaultQuestDeck = , Quest { _questType = Piety , _questTitle = "Produce a Miracle for the Masses" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 2), (Gold, 4)] + , _questCost = clerics 2 <> gold 4 , _questReward = do scorePoints 5 , _questPlotActions = @@ -64,7 +64,7 @@ defaultQuestDeck = , Quest { _questType = Piety , _questTitle = "Convert a Noble to Lathander" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 2), (Fighter, 1)] + , _questCost = clerics 2 <> fighters 1 , _questReward = do scorePoints 8 chooseQuest @@ -73,7 +73,7 @@ defaultQuestDeck = , Quest { _questType = Piety , _questTitle = "Heal Fallen Gray Hand Soldiers" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 2), (Wizard, 1), (Gold, 4)] + , _questCost = clerics 2 <> wizards 1 <> gold 4 , _questReward = do scorePoints 6 takeResources 6 [Fighter] @@ -82,7 +82,7 @@ defaultQuestDeck = , Quest { _questType = Piety , _questTitle = "Create a Shrine to Oghma" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 5), (Gold, 2)] + , _questCost = clerics 5 <> gold 2 , _questReward = do scorePoints 25 , _questPlotActions = [] @@ -90,7 +90,7 @@ defaultQuestDeck = , Quest { _questType = Piety , _questTitle = "Seal Gate to Cyric's Realm" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 2), (Rogue, 3), (Gold, 4)] + , _questCost = clerics 2 <> rogues 3 <> gold 4 , _questReward = do scorePoints 20 , _questPlotActions = [] @@ -98,7 +98,7 @@ defaultQuestDeck = , Quest { _questType = Piety , _questTitle = "Perform the Penance of Duty" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 2), (Fighter, 2), (Gold, 4)] + , _questCost = clerics 2 <> fighters 2 <> gold 4 , _questReward = do scorePoints 12 takeResources 1 [Cleric] @@ -108,7 +108,7 @@ defaultQuestDeck = , Quest { _questType = Piety , _questTitle = "Form an Alliance with the Rashemi" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 2), (Wizard, 1)] + , _questCost = clerics 2 <> wizards 1 , _questReward = do scorePoints 10 chooseQuest @@ -117,7 +117,7 @@ defaultQuestDeck = , Quest { _questType = Piety , _questTitle = "Eliminate Vampire Coven" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 2), (Fighter, 2), (Rogue, 1)] + , _questCost = clerics 2 <> fighters 2 <> rogues 1 , _questReward = do scorePoints 11 takeResources 4 [Gold] @@ -126,7 +126,7 @@ defaultQuestDeck = , Quest { _questType = Piety , _questTitle = "Discover Hidden Temple of Lolth" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 2), (Fighter, 1), (Rogue, 1)] + , _questCost = clerics 2 <> fighters 1 <> rogues 1 , _questReward = do scorePoints 10 chooseQuest @@ -135,7 +135,7 @@ defaultQuestDeck = , Quest { _questType = Warfare , _questTitle = "Deliver Weapons to Selûne's Temple" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 4), (Rogue, 1), (Wizard, 1), (Gold, 2)] + , _questCost = fighters 4 <> rogues 1 <> wizards 1 <> gold 2 , _questReward = do scorePoints 9 takeResources 2 [Cleric] @@ -144,7 +144,7 @@ defaultQuestDeck = , Quest { _questType = Warfare , _questTitle = "Raid Orc Stronghold" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 4), (Rogue, 2)] + , _questCost = fighters 4 <> rogues 2 , _questReward = do scorePoints 8 takeResources 4 [Gold] @@ -153,7 +153,7 @@ defaultQuestDeck = , Quest { _questType = Warfare , _questTitle = "Bolster City Guard" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 9), (Rogue, 2)] + , _questCost = fighters 9 <> rogues 2 , _questReward = do scorePoints 25 , _questPlotActions = [] @@ -161,7 +161,7 @@ defaultQuestDeck = , Quest { _questType = Warfare , _questTitle = "Recruit Lieutenant" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Fighter, 5), (Rogue, 1), (Wizard, 1)] + , _questCost = clerics 1 <> fighters 5 <> rogues 1 <> wizards 1 , _questReward = do noAction , _questPlotActions = @@ -170,7 +170,7 @@ defaultQuestDeck = , Quest { _questType = Warfare , _questTitle = "Train Bladesingers" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 3), (Wizard, 1)] + , _questCost = fighters 3 <> wizards 1 , _questReward = do scorePoints 4 takeResources 1 [Fighter] @@ -180,7 +180,7 @@ defaultQuestDeck = , Quest { _questType = Warfare , _questTitle = "Repel Seawraiths" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Fighter, 4), (Wizard, 1)] + , _questCost = clerics 1 <> fighters 4 <> wizards 1 , _questReward = do scorePoints 15 takeResources 2 [Gold] @@ -189,7 +189,7 @@ defaultQuestDeck = , Quest { _questType = Warfare , _questTitle = "Bolster Griffon Cavalry" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 4), (Gold, 4)] + , _questCost = fighters 4 <> gold 4 , _questReward = do scorePoints 6 , _questPlotActions = @@ -198,7 +198,7 @@ defaultQuestDeck = , Quest { _questType = Warfare , _questTitle = "Deliver an Ultimatum" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 4), (Rogue, 1), (Wizard, 1)] + , _questCost = fighters 4 <> rogues 1 <> wizards 1 , _questReward = do scorePoints 11 takeResources 4 [Gold] @@ -207,7 +207,7 @@ defaultQuestDeck = , Quest { _questType = Warfare , _questTitle = "Ambush Artor Morlin" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Fighter, 3), (Rogue, 1)] + , _questCost = clerics 1 <> fighters 3 <> rogues 1 , _questReward = do scorePoints 8 takeResources 4 [Gold] @@ -216,7 +216,7 @@ defaultQuestDeck = , Quest { _questType = Warfare , _questTitle = "Quell Mercenary Uprising" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Fighter, 4)] + , _questCost = clerics 1 <> fighters 4 , _questReward = do scorePoints 8 takeResources 4 [Gold] @@ -226,7 +226,7 @@ defaultQuestDeck = , Quest { _questType = Warfare , _questTitle = "Confront the Xanathar" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Fighter, 4), (Rogue, 2), (Wizard, 1)] + , _questCost = clerics 1 <> fighters 4 <> rogues 2 <> wizards 1 , _questReward = do scorePoints 20 takeResources 2 [Gold] @@ -235,7 +235,7 @@ defaultQuestDeck = , Quest { _questType = Warfare , _questTitle = "Defeat Uprising from Undermountain" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Fighter, 3), (Rogue, 1), (Gold, 2)] + , _questCost = clerics 1 <> fighters 3 <> rogues 1 <> gold 2 , _questReward = do scorePoints 11 takeResources 2 [Fighter] @@ -244,7 +244,7 @@ defaultQuestDeck = , Quest { _questType = Skullduggery , _questTitle = "Place a Sleeper Agent in Skullport" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 1), (Rogue, 4), (Wizard, 1)] + , _questCost = fighters 1 <> rogues 4 <> wizards 1 , _questReward = do noAction , _questPlotActions = @@ -253,7 +253,7 @@ defaultQuestDeck = , Quest { _questType = Skullduggery , _questTitle = "Establish Shadow Thieves' Guild" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 1), (Rogue, 8), (Wizard, 1)] + , _questCost = fighters 1 <> rogues 8 <> wizards 1 , _questReward = do scorePoints 25 , _questPlotActions = [] @@ -261,7 +261,7 @@ defaultQuestDeck = , Quest { _questType = Skullduggery , _questTitle = "Build a Reputation in Skullport" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 1), (Rogue, 3), (Gold, 4)] + , _questCost = fighters 1 <> rogues 3 <> gold 4 , _questReward = do scorePoints 10 drawIntrigue @@ -270,7 +270,7 @@ defaultQuestDeck = , Quest { _questType = Skullduggery , _questTitle = "Fence Goods for Duke of Darkness" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 1), (Rogue, 3), (Gold, 4)] + , _questCost = fighters 1 <> rogues 3 <> gold 4 , _questReward = do scorePoints 6 , _questPlotActions = @@ -279,7 +279,7 @@ defaultQuestDeck = , Quest { _questType = Skullduggery , _questTitle = "Raid on Undermountain" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Fighter, 2), (Rogue, 4), (Wizard, 1)] + , _questCost = clerics 1 <> fighters 2 <> rogues 4 <> wizards 1 , _questReward = do scorePoints 20 takeResources 2 [Gold] @@ -288,7 +288,7 @@ defaultQuestDeck = , Quest { _questType = Skullduggery , _questTitle = "Steal from House Adarbrent" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 1), (Rogue, 4), (Wizard, 1)] + , _questCost = fighters 1 <> rogues 4 <> wizards 1 , _questReward = do scorePoints 10 takeResources 6 [Gold] @@ -297,7 +297,7 @@ defaultQuestDeck = , Quest { _questType = Skullduggery , _questTitle = "Prison Break" , _questQuote = "" - , _questCost = MS.fromOccurList [(Rogue, 4), (Wizard, 2), (Gold, 2)] + , _questCost = rogues 4 <> wizards 2 <> gold 2 , _questReward = do scorePoints 14 takeResources 2 [Fighter] @@ -307,7 +307,7 @@ defaultQuestDeck = , Quest { _questType = Skullduggery , _questTitle = "Take Over Rival Organization" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 1), (Rogue, 2), (Wizard, 1), (Gold, 6)] + , _questCost = fighters 1 <> rogues 2 <> wizards 1 <> gold 6 , _questReward = do scorePoints 10 takeResources 4 [Rogue] @@ -317,7 +317,7 @@ defaultQuestDeck = , Quest { _questType = Skullduggery , _questTitle = "Procure Stolen Goods" , _questQuote = "" - , _questCost = MS.fromOccurList [(Rogue, 3), (Gold, 6)] + , _questCost = rogues 3 <> gold 6 , _questReward = do scorePoints 8 drawIntrigue @@ -327,7 +327,7 @@ defaultQuestDeck = , Quest { _questType = Skullduggery , _questTitle = "Establish Harpers Safe House" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 2), (Rogue, 3), (Gold, 2)] + , _questCost = fighters 2 <> rogues 3 <> gold 2 , _questReward = do scorePoints 8 forEachControlledBuilding $ @@ -337,7 +337,7 @@ defaultQuestDeck = , Quest { _questType = Skullduggery , _questTitle = "Expose Cult Corruption" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Rogue, 4)] + , _questCost = clerics 1 <> rogues 4 , _questReward = do scorePoints 4 takeResources 2 [Cleric] @@ -346,7 +346,7 @@ defaultQuestDeck = , Quest { _questType = Skullduggery , _questTitle = "Install a Spy in Castle Waterdeep" , _questQuote = "" - , _questCost = MS.fromOccurList [(Rogue, 4), (Gold, 4)] + , _questCost = rogues 4 <> gold 4 , _questReward = do scorePoints 8 , _questPlotActions = @@ -355,7 +355,7 @@ defaultQuestDeck = , Quest { _questType = Arcana , _questTitle = "Expose Red Wizards' Spies" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Fighter, 1), (Rogue, 2), (Wizard, 2), (Gold, 2)] + , _questCost = clerics 1 <> fighters 1 <> rogues 2 <> wizards 2 <> gold 2 , _questReward = do scorePoints 20 drawIntrigue @@ -364,7 +364,7 @@ defaultQuestDeck = , Quest { _questType = Arcana , _questTitle = "Host Festival for Sune" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 2), (Wizard, 2), (Gold, 4)] + , _questCost = fighters 2 <> wizards 2 <> gold 4 , _questReward = do scorePoints 9 takeResources 2 [Cleric] @@ -373,7 +373,7 @@ defaultQuestDeck = , Quest { _questType = Arcana , _questTitle = "Steal Spellbook from Silverhand" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 1), (Rogue, 2), (Wizard, 2)] + , _questCost = fighters 1 <> rogues 2 <> wizards 2 , _questReward = do scorePoints 7 drawIntrigue @@ -384,7 +384,7 @@ defaultQuestDeck = , Quest { _questType = Arcana , _questTitle = "Recruit for Blackstaff Academy" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 1), (Rogue, 1), (Wizard, 2), (Gold, 4)] + , _questCost = fighters 1 <> rogues 1 <> wizards 2 <> gold 4 , _questReward = do scorePoints 6 takeResources 3 [Wizard] @@ -393,7 +393,7 @@ defaultQuestDeck = , Quest { _questType = Arcana , _questTitle = "Retrieve Ancient Artifacts" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 2), (Rogue, 1), (Wizard, 2)] + , _questCost = fighters 2 <> rogues 1 <> wizards 2 , _questReward = do scorePoints 11 takeResources 4 [Gold] @@ -402,7 +402,7 @@ defaultQuestDeck = , Quest { _questType = Arcana , _questTitle = "Recover the Magister's Orb" , _questQuote = "" - , _questCost = MS.fromOccurList [(Rogue, 3), (Wizard, 2)] + , _questCost = rogues 3 <> wizards 2 , _questReward = do scorePoints 6 enableAssignOnceToOpponentsSpace @@ -412,7 +412,7 @@ defaultQuestDeck = , Quest { _questType = Arcana , _questTitle = "Study the Illusk Arch" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Wizard, 2)] + , _questCost = clerics 1 <> wizards 2 , _questReward = do scorePoints 8 , _questPlotActions = @@ -421,7 +421,7 @@ defaultQuestDeck = , Quest { _questType = Arcana , _questTitle = "Explore Ahghairon's Tower" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 1), (Wizard, 2), (Gold, 2)] + , _questCost = fighters 1 <> wizards 2 <> gold 2 , _questReward = do scorePoints 6 , _questPlotActions = @@ -430,7 +430,7 @@ defaultQuestDeck = , Quest { _questType = Arcana , _questTitle = "Infiltrate Halaster's Circle" , _questQuote = "" - , _questCost = MS.fromOccurList [(Wizard, 5), (Gold, 2)] + , _questCost = wizards 5 <> gold 2 , _questReward = do scorePoints 25 , _questPlotActions = [] @@ -438,7 +438,7 @@ defaultQuestDeck = , Quest { _questType = Arcana , _questTitle = "Domesticate Owlbears" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Wizard, 2)] + , _questCost = clerics 1 <> wizards 2 , _questReward = do scorePoints 8 takeResources 1 [Fighter] @@ -448,7 +448,7 @@ defaultQuestDeck = , Quest { _questType = Arcana , _questTitle = "Investigate Aberrant Infestation" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Fighter, 1), (Wizard, 2)] + , _questCost = clerics 1 <> fighters 1 <> wizards 2 , _questReward = do scorePoints 13 drawIntrigue @@ -457,7 +457,7 @@ defaultQuestDeck = , Quest { _questType = Arcana , _questTitle = "Research Chronomancy" , _questQuote = "" - , _questCost = MS.fromOccurList [(Wizard, 2), (Gold, 4)] + , _questCost = wizards 2 <> gold 4 , _questReward = do scorePoints 4 takeResources 1 [Wizard] @@ -467,7 +467,7 @@ defaultQuestDeck = , Quest { _questType = Commerce , _questTitle = "Infiltrate Builder's Hall" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 2), (Rogue, 2), (Gold, 4)] + , _questCost = fighters 2 <> rogues 2 <> gold 4 , _questReward = do scorePoints 6 , _questPlotActions = @@ -476,7 +476,7 @@ defaultQuestDeck = , Quest { _questType = Commerce , _questTitle = "Loot the Crypt of Chauntea" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Rogue, 3), (Gold, 2)] + , _questCost = clerics 1 <> rogues 3 <> gold 2 , _questReward = do scorePoints 7 drawIntrigue @@ -486,7 +486,7 @@ defaultQuestDeck = , Quest { _questType = Commerce , _questTitle = "Impersonate Adarbrent Noble" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Fighter, 2), (Rogue, 2), (Wizard, 1), (Gold, 4)] + , _questCost = clerics 1 <> fighters 2 <> rogues 2 <> wizards 1 <> gold 4 , _questReward = do scorePoints 18 drawIntrigue @@ -496,7 +496,7 @@ defaultQuestDeck = , Quest { _questType = Commerce , _questTitle = "Safeguard Eltorchul Mage" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 1), (Rogue, 1), (Wizard, 1), (Gold, 4)] + , _questCost = fighters 1 <> rogues 1 <> wizards 1 <> gold 4 , _questReward = do scorePoints 4 takeResources 2 [Wizard] @@ -505,7 +505,7 @@ defaultQuestDeck = , Quest { _questType = Commerce , _questTitle = "Thin the City Watch" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Fighter, 1), (Rogue, 1), (Gold, 4)] + , _questCost = clerics 1 <> fighters 1 <> rogues 1 <> gold 4 , _questReward = do scorePoints 9 takeResources 4 [Rogue] @@ -514,7 +514,7 @@ defaultQuestDeck = , Quest { _questType = Commerce , _questTitle = "Bribe the Shipwrights" , _questQuote = "" - , _questCost = MS.fromOccurList [(Rogue, 4), (Wizard, 1), (Gold, 4)] + , _questCost = rogues 4 <> wizards 1 <> gold 4 , _questReward = do scorePoints 10 , _questPlotActions = @@ -523,7 +523,7 @@ defaultQuestDeck = , Quest { _questType = Commerce , _questTitle = "Lure Artisans of Mirabar" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Fighter, 1), (Rogue, 1)] + , _questCost = clerics 1 <> fighters 1 <> rogues 1 , _questReward = do scorePoints 4 chooseFreeBuilding @@ -532,7 +532,7 @@ defaultQuestDeck = , Quest { _questType = Commerce , _questTitle = "Placate the Walking Statue" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 2), (Rogue, 2)] + , _questCost = clerics 2 <> rogues 2 , _questReward = do scorePoints 10 drawFreeBuilding @@ -541,7 +541,7 @@ defaultQuestDeck = , Quest { _questType = Commerce , _questTitle = "Establish New Merchant Guild" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Fighter, 2), (Gold, 4)] + , _questCost = clerics 1 <> fighters 2 <> gold 4 , _questReward = do scorePoints 8 , _questPlotActions = @@ -550,7 +550,7 @@ defaultQuestDeck = , Quest { _questType = Commerce , _questTitle = "Send Aid to the Harpers" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Fighter, 1), (Rogue, 1), (Gold, 4)] + , _questCost = clerics 1 <> fighters 1 <> rogues 1 <> gold 4 , _questReward = do scorePoints 15 forOneOpponent $ takeResources 4 [Gold] @@ -559,7 +559,7 @@ defaultQuestDeck = , Quest { _questType = Commerce , _questTitle = "Ally with House Thann" , _questQuote = "" - , _questCost = MS.fromOccurList [(Cleric, 1), (Rogue, 3), (Wizard, 1), (Gold, 8)] + , _questCost = clerics 1 <> rogues 3 <> wizards 1 <> gold 8 , _questReward = do scorePoints 25 , _questPlotActions = [] @@ -567,7 +567,7 @@ defaultQuestDeck = , Quest { _questType = Commerce , _questTitle = "Spy on the House of Light" , _questQuote = "" - , _questCost = MS.fromOccurList [(Fighter, 3), (Rogue, 2), (Gold, 2)] + , _questCost = fighters 3 <> rogues 2 <> gold 2 , _questReward = do scorePoints 6 takeResources 6 [Gold] diff --git a/src/Waterdeep/Types.hs b/src/Waterdeep/Types.hs index 4899cd7..cddf274 100644 --- a/src/Waterdeep/Types.hs +++ b/src/Waterdeep/Types.hs @@ -108,6 +108,11 @@ module Waterdeep.Types , runWaterdeepM , canPerformAction , filterChoices + , clerics + , fighters + , rogues + , wizards + , gold ) where import Control.Applicative @@ -234,6 +239,13 @@ data Resource = Cleric | Fighter | Rogue | Wizard | Gold type ResourceSet = Set.Set Resource type ResourceBag = MS.MultiSet Resource +clerics, fighters, rogues, wizards, gold :: MS.Occur -> ResourceBag +clerics n = MS.insertMany Cleric n MS.empty +fighters n = MS.insertMany Fighter n MS.empty +rogues n = MS.insertMany Rogue n MS.empty +wizards n = MS.insertMany Wizard n MS.empty +gold n = MS.insertMany Gold n MS.empty + data QuestType = Piety | Warfare | Skullduggery | Arcana | Commerce | Mandatory deriving (Eq,Ord,Enum,Bounded,Show)