Copyright | (c) Henry J. Wylde, 2016 |
---|---|
License | BSD3 |
Maintainer | public@hjwylde.com |
Safe Haskell | None |
Language | Haskell2010 |
A game is not quite as simple as players! Roughly speaking though, this engine is stateful. The
game state only changes when a command is issued (see Game.Werewolf.Command). Thus, this module
defines the Game
data structure and any fields required to keep track of the current state.
It also has a few additional functions for manipulating and querying the game state.
- data Game
- stage :: Lens' Game Stage
- round :: Lens' Game Int
- players :: Lens' Game [Player]
- events :: Lens' Game [Event]
- boots :: Lens' Game (Map Text [Text])
- passes :: Lens' Game [Text]
- allegianceChosen :: Lens' Game (Maybe Allegiance)
- allowedVoters :: Lens' Game [Text]
- heal :: Lens' Game Bool
- healUsed :: Lens' Game Bool
- poison :: Lens' Game (Maybe Text)
- poisonUsed :: Lens' Game Bool
- priorProtect :: Lens' Game (Maybe Text)
- protect :: Lens' Game (Maybe Text)
- roleModel :: Lens' Game (Maybe Text)
- scapegoatBlamed :: Lens' Game Bool
- see :: Lens' Game (Maybe Text)
- villageIdiotRevealed :: Lens' Game Bool
- votes :: Lens' Game (Map Text Text)
- data Stage
- _DefendersTurn :: Prism' Stage ()
- _DevotedServantsTurn :: Prism' Stage ()
- _GameOver :: Prism' Stage ()
- _Lynching :: Prism' Stage ()
- _ScapegoatsTurn :: Prism' Stage ()
- _SeersTurn :: Prism' Stage ()
- _Sunrise :: Prism' Stage ()
- _Sunset :: Prism' Stage ()
- _UrsussGrunt :: Prism' Stage ()
- _VillagesTurn :: Prism' Stage ()
- _WerewolvesTurn :: Prism' Stage ()
- _WildChildsTurn :: Prism' Stage ()
- _WitchsTurn :: Prism' Stage ()
- _WolfHoundsTurn :: Prism' Stage ()
- allStages :: [Stage]
- stageCycle :: [Stage]
- stageAvailable :: Game -> Stage -> Bool
- data Event
- _DevourEvent :: Prism' Event Text
- _NoDevourEvent :: Prism' Event ()
- _PoisonEvent :: Prism' Event Text
- newGame :: [Player] -> Game
- killPlayer :: Text -> Game -> Game
- getAllowedVoters :: Game -> [Player]
- getPendingVoters :: Game -> [Player]
- getVoteResult :: Game -> [Player]
- isFirstRound :: Game -> Bool
- doesPlayerExist :: Text -> Game -> Bool
- hasAnyoneWon :: Game -> Bool
- hasAngelWon :: Game -> Bool
- hasVillagersWon :: Game -> Bool
- hasWerewolvesWon :: Game -> Bool
Game
There are a few key pieces of information that a game always needs to hold. These are:
Any further fields on the game are specific to one or more roles (and their respective turns!).
Some of the additional fields are reset each round (e.g., the Seer's see
) while others are
kept around for the whole game (e.g., the Wild-child's roleModel
).
In order to advance a game's state
, a Command
from a user needs to be
received. Afterwards the following steps should be performed:
apply
theCommand
.- run
checkStage
. - run
checkGameOver
.
checkStage
will perform any additional checks and manipulations to the
game state before advancing the game's stage
. It also runs any relevant events
.
checkGameOver
will check to see if any of the win conditions are met and
if so, advance the game's stage
to GameOver
.
allowedVoters :: Lens' Game [Text] Source
Most of these are fairly self-sufficient (the turn stages). Sunrise
and Sunset
are provided
as meaningful breaks between the day and night as, for example, a VillagesTurn
may not always
be available (curse that retched Scapegoat).
Once the game reaches a turn stage, it requires a Command
to help push
it past. Often only certain roles and commands may be performed at any given stage.
_DefendersTurn :: Prism' Stage () Source
_ScapegoatsTurn :: Prism' Stage () Source
_SeersTurn :: Prism' Stage () Source
_UrsussGrunt :: Prism' Stage () Source
_VillagesTurn :: Prism' Stage () Source
_WerewolvesTurn :: Prism' Stage () Source
_WildChildsTurn :: Prism' Stage () Source
_WitchsTurn :: Prism' Stage () Source
_WolfHoundsTurn :: Prism' Stage () Source
stageCycle :: [Stage] Source
An infinite cycle of all Stage
s in the order that they should occur.
stageAvailable :: Game -> Stage -> Bool Source
Checks whether the stage is available for the given Game
. Most often this just involves
checking if there is an applicable role alive, but sometimes it is more complex.
One of the more complex checks here is for the VillagesTurn
. If the Angel is in play, then
the VillagesTurn
is available on the first day rather than only after the first night.
Events occur after a Stage
is advanced. This is automatically handled in
checkStage
, while an event's specific behaviour is defined by
eventAvailable
and applyEvent
.
For the most part events are used to allow something to happen on a Stage
different to when
it was triggered. E.g., the DeovurEvent
occurs after the village wakes up rather than when
the Werewolves' vote, this gives the Witch a chance to heal the victim.
DevourEvent Text | Werewolves |
NoDevourEvent | Defender, Werewolves and Witch |
PoisonEvent Text | Witch |
_NoDevourEvent :: Prism' Event () Source
Manipulations
killPlayer :: Text -> Game -> Game Source
Kills the given player! This function should be used carefully as it doesn't clear any state
that the player's role may use. If you're after just removing a player from a game for a test,
try using a quitCommand
instead.
Searches
getAllowedVoters :: Game -> [Player] Source
Gets all the allowedVoters
in a game (which is names only) and maps them to their player.
getPendingVoters :: Game -> [Player] Source
Gets all Alive
players that have yet to vote.
getVoteResult :: Game -> [Player] Source
Gets all players that had the highest vote count. This could be 1 or more players depending on whether the votes were in conflict.
Queries
isFirstRound :: Game -> Bool Source
isFirstRound
game = game ^.round
== 0
doesPlayerExist :: Text -> Game -> Bool Source
Queries whether the player is in the game.
hasAnyoneWon :: Game -> Bool Source
Queries whether anyone has won.
hasAngelWon :: Game -> Bool Source
Queries whether the Angel has won. The Angel wins if they manage to get themselves killed on the first round.
N.B., we check that the Angel isn't a villager
as the Angel's role is altered if they don't
win.
hasVillagersWon :: Game -> Bool Source
hasWerewolvesWon :: Game -> Bool Source
Queries whether the Werewolves
have won. The Werewolves
win if they are the only players
surviving.