change _playerTavern to a Map and implement additional actions
This commit is contained in:
parent
8999128947
commit
a3b6810e0e
28
src/Test.hs
28
src/Test.hs
|
|
@ -25,6 +25,30 @@ f2 = Faction "Pilots" Green
|
||||||
l2 = Lord "Princess Anastasia" "" (QuestBonus [Arcana, Warfare] 4)
|
l2 = Lord "Princess Anastasia" "" (QuestBonus [Arcana, Warfare] 4)
|
||||||
p2 = ("Ned", f2, l2)
|
p2 = ("Ned", f2, l2)
|
||||||
|
|
||||||
|
q1 = Quest { _questType = Arcana
|
||||||
|
, _questTitle = "Research Palantirs"
|
||||||
|
, _questQuote = ""
|
||||||
|
, _questAction = Transaction $
|
||||||
|
[ Transaction $
|
||||||
|
map (\r -> ReturnResource [r]) [Cleric,Rogue,Rogue,Wizard]
|
||||||
|
, Repeat 4 $ ReturnResource [Gold]
|
||||||
|
, ScorePoints 15
|
||||||
|
, Repeat 8 $ TakeResource [Gold]
|
||||||
|
]
|
||||||
|
, _questPlotActions = []
|
||||||
|
}
|
||||||
|
|
||||||
|
q2 = Quest { _questType = Skullduggery
|
||||||
|
, _questTitle = "Rob Waterdeep Bank"
|
||||||
|
, _questQuote = ""
|
||||||
|
, _questAction = Transaction $
|
||||||
|
[ Repeat 8 $ ReturnResource [Rogue]
|
||||||
|
, ScorePoints 10
|
||||||
|
, Repeat 16 $ TakeResource [Gold]
|
||||||
|
]
|
||||||
|
, _questPlotActions = []
|
||||||
|
}
|
||||||
|
|
||||||
b1 = Building { _buildingCost = 6
|
b1 = Building { _buildingCost = 6
|
||||||
, _buildingTitle = "Monastary"
|
, _buildingTitle = "Monastary"
|
||||||
, _buildingAction = Group [TakeResource [Cleric], TakeResource [Cleric]]
|
, _buildingAction = Group [TakeResource [Cleric], TakeResource [Cleric]]
|
||||||
|
|
@ -116,7 +140,7 @@ dummyPrompt prm@(SolicitChoice w p t cs) = do
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
w <- newGame [p1, p2] [] [] [b1,b2,b3,b4,b5]
|
w <- newGame [p1, p2] [q1, q2] [] [b1, b2, b3, b4, b5]
|
||||||
winners <- fst <$> runWaterdeepM dummyPrompt waterdeepGame w
|
winners <- fst <$> runWaterdeepM dummyPrompt waterdeepGame w
|
||||||
let gamePlayerName n = w ^. gamePlayer n . playerName
|
let gamePlayerName n = w ^. gamePlayer n . playerName
|
||||||
putStrLn ("Winner(s): " ++ intercalate ", " (toListOf (traverse . to gamePlayerName) winners))
|
putStrLn ("Winner(s): " ++ intercalate ", " (winners ^.. traverse . to gamePlayerName))
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ module Waterdeep.Logic
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
|
import Control.Arrow ((&&&))
|
||||||
import Control.Lens
|
import Control.Lens
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Control.Monad.Random
|
import Control.Monad.Random
|
||||||
|
|
@ -20,6 +21,7 @@ import Waterdeep.Types
|
||||||
import Waterdeep.Monad
|
import Waterdeep.Monad
|
||||||
|
|
||||||
import qualified Data.IntMap as IM
|
import qualified Data.IntMap as IM
|
||||||
|
import qualified Data.Map as M
|
||||||
|
|
||||||
newGame :: (MonadRandom m, MonadSplit StdGen m)
|
newGame :: (MonadRandom m, MonadSplit StdGen m)
|
||||||
=> [(String,Faction,Lord)]
|
=> [(String,Faction,Lord)]
|
||||||
|
|
@ -79,7 +81,7 @@ newPlayerState i name faction lord =
|
||||||
, _playerFaction = faction
|
, _playerFaction = faction
|
||||||
, _playerLord = lord
|
, _playerLord = lord
|
||||||
, _playerScore = 0
|
, _playerScore = 0
|
||||||
, _playerTavern = []
|
, _playerTavern = M.empty
|
||||||
, _playerIncompleteQuests = []
|
, _playerIncompleteQuests = []
|
||||||
, _playerCompletedQuests = []
|
, _playerCompletedQuests = []
|
||||||
, _playerActivePlotQuests = []
|
, _playerActivePlotQuests = []
|
||||||
|
|
@ -97,29 +99,71 @@ waterdeepGame :: Waterdeep [PlayerID]
|
||||||
waterdeepGame = do
|
waterdeepGame = do
|
||||||
forM_ [1..8] $ \round -> do
|
forM_ [1..8] $ \round -> do
|
||||||
beginRound round
|
beginRound round
|
||||||
void $ solicitChoice 1 "Choose one" [("Option A", ()), ("Option B", ())]
|
performAction 1 $ TakeResource [Cleric, Fighter, Rogue, Wizard, Gold]
|
||||||
|
performAction 2 $ ChooseQuest
|
||||||
notifyState
|
notifyState
|
||||||
determineWinners
|
determineWinners
|
||||||
|
|
||||||
beginRound :: Int -> Waterdeep ()
|
beginRound :: Int -> Waterdeep ()
|
||||||
beginRound round = do
|
beginRound round = do
|
||||||
gameCurrentRound .= round
|
gameCurrentRound .= round
|
||||||
|
gameCurrentPlayer <~ use gameFirstPlayer
|
||||||
|
gameBasicBuildings . traverse . _2 .= []
|
||||||
|
gameAdvancedBuildings . traverse . _2 .= []
|
||||||
|
gameBuildersHall . traverse . _2 .= []
|
||||||
|
gameBuildersHall . traverse . _3 += 1
|
||||||
|
players <- IM.size <$> use gamePlayers
|
||||||
|
forM_ [1..players] $ \p -> do
|
||||||
|
qs <- gamePlayer p . playerUsedPlotQuests <<.= []
|
||||||
|
gamePlayer p . playerActivePlotQuests %= (++ qs)
|
||||||
|
gamePlayer p . playerAgentsInPool .= initialAgents players round
|
||||||
notifyState
|
notifyState
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
|
initialAgents :: Int -> Int -> Int
|
||||||
|
initialAgents players round =
|
||||||
|
if round >= 5 then startingAgents + 1 else startingAgents
|
||||||
|
where startingAgents = 6 - players
|
||||||
|
|
||||||
performAction :: PlayerID -> GameAction -> Waterdeep Bool
|
performAction :: PlayerID -> GameAction -> Waterdeep Bool
|
||||||
performAction p a = case a of
|
performAction p a = case a of
|
||||||
|
ScorePoints n -> do
|
||||||
|
gamePlayer p . playerScore += n
|
||||||
|
return True
|
||||||
|
TakeResource rs -> do
|
||||||
|
r <- solicitChoice p "Please choose one:" $ map (show &&& id) rs
|
||||||
|
gamePlayer p . playerTavern %= flip (M.unionWith (+)) (M.fromList [(r, 1)])
|
||||||
|
return True
|
||||||
|
ChooseQuest -> do
|
||||||
|
qs <- use gameCliffwatchInn
|
||||||
|
if null qs
|
||||||
|
then return False
|
||||||
|
else do
|
||||||
|
let names = qs ^.. traverse . questTitle
|
||||||
|
q <- solicitChoice p "Please choose a quest:" $ zip names qs
|
||||||
|
gameCliffwatchInn %= (\\ [q])
|
||||||
|
gamePlayer p . playerIncompleteQuests %= (++ [q])
|
||||||
|
restockCliffwatchInn
|
||||||
|
return True
|
||||||
DrawQuest -> do
|
DrawQuest -> do
|
||||||
mq <- drawQuest
|
mq <- drawQuest
|
||||||
case mq of
|
case mq of
|
||||||
Nothing -> return False
|
Nothing -> return False
|
||||||
Just q -> do
|
Just q -> do
|
||||||
gamePlayers . singular (ix p) . playerIncompleteQuests %= (++[q])
|
gamePlayer p . playerIncompleteQuests %= (++[q])
|
||||||
|
return True
|
||||||
|
DrawIntrigue -> do
|
||||||
|
mi <- drawIntrigue
|
||||||
|
case mi of
|
||||||
|
Nothing -> return False
|
||||||
|
Just i -> do
|
||||||
|
gamePlayer p . playerIntrigueCards %= (++[i])
|
||||||
return True
|
return True
|
||||||
_ -> return False
|
_ -> return False
|
||||||
|
|
||||||
determineWinners :: Waterdeep [PlayerID]
|
determineWinners :: Waterdeep [PlayerID]
|
||||||
determineWinners = do
|
determineWinners = do
|
||||||
|
-- TODO: Implement tie-breaker(s)
|
||||||
let compareScores a b = (b^.playerScore) `compare` (a^.playerScore)
|
let compareScores a b = (b^.playerScore) `compare` (a^.playerScore)
|
||||||
ps <- sortBy compareScores <$> toListOf traverse <$> use gamePlayers
|
ps <- sortBy compareScores <$> toListOf traverse <$> use gamePlayers
|
||||||
let bestScore = (head ps) ^. playerScore
|
let bestScore = (head ps) ^. playerScore
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,9 @@ notifyState :: Waterdeep ()
|
||||||
notifyState = get >>= Waterdeep . lift . prompt . NotifyState
|
notifyState = get >>= Waterdeep . lift . prompt . NotifyState
|
||||||
|
|
||||||
solicitChoice :: PlayerID -> String -> [(String, a)] -> Waterdeep a
|
solicitChoice :: PlayerID -> String -> [(String, a)] -> Waterdeep a
|
||||||
solicitChoice p t cs = do
|
solicitChoice _ _ [] = error "There must be at least one option to choose."
|
||||||
|
solicitChoice _ _ [c] = return (snd c) -- only one option, don't bother asking
|
||||||
|
solicitChoice p t cs = do
|
||||||
notifyState
|
notifyState
|
||||||
w <- get
|
w <- get
|
||||||
Waterdeep $ lift $ prompt (SolicitChoice w p t cs)
|
Waterdeep $ lift $ prompt (SolicitChoice w p t cs)
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ module Waterdeep.Types
|
||||||
|
|
||||||
import Control.Lens
|
import Control.Lens
|
||||||
import Data.IntMap (IntMap)
|
import Data.IntMap (IntMap)
|
||||||
|
import Data.Map (Map)
|
||||||
import System.Random (StdGen)
|
import System.Random (StdGen)
|
||||||
|
|
||||||
type PlayerID = Int
|
type PlayerID = Int
|
||||||
|
|
@ -124,7 +125,7 @@ data PlayerState =
|
||||||
, _playerFaction :: Faction
|
, _playerFaction :: Faction
|
||||||
, _playerLord :: Lord
|
, _playerLord :: Lord
|
||||||
, _playerScore :: Int
|
, _playerScore :: Int
|
||||||
, _playerTavern :: [(Int,Resource)]
|
, _playerTavern :: Map Resource Int
|
||||||
, _playerIncompleteQuests :: [Quest]
|
, _playerIncompleteQuests :: [Quest]
|
||||||
, _playerCompletedQuests :: [Quest]
|
, _playerCompletedQuests :: [Quest]
|
||||||
, _playerActivePlotQuests :: [Quest]
|
, _playerActivePlotQuests :: [Quest]
|
||||||
|
|
@ -247,3 +248,12 @@ instance Eq Faction where
|
||||||
|
|
||||||
instance Ord Faction where
|
instance Ord Faction where
|
||||||
a `compare` b = (a^.factionColor) `compare` (b^.factionColor)
|
a `compare` b = (a^.factionColor) `compare` (b^.factionColor)
|
||||||
|
|
||||||
|
instance Eq Quest where
|
||||||
|
a == b = a^.questTitle == b^.questTitle
|
||||||
|
|
||||||
|
instance Eq Building where
|
||||||
|
a == b = a^.buildingTitle == b^.buildingTitle
|
||||||
|
|
||||||
|
instance Eq IntrigueCard where
|
||||||
|
a == b = a^.intrigueTitle == b^.intrigueTitle
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue