hanabi-dealer-0.2.1.0: Hanabi card game

Safe HaskellSafe
LanguageHaskell2010

Game.Hanabi

Contents

Synopsis

Functions for Dealing Games

main :: IO () Source #

selfplay :: GameSpec -> IO () Source #

selfplay starts selfplay with yourself:)

Also,

selfplay defaultGS{numPlayers=n}

(where 1<n<10) starts selfplay with youselves:D

start :: (RandomGen g, Monad m, Strategies ps m) => GameSpec -> ps -> g -> m (((EndGame, [State], [Move]), ps), g) Source #

start creates and runs a game. This is just the composition of createGame and run.

createGame :: RandomGen g => GameSpec -> g -> (State, g) Source #

run :: (Monad m, Strategies ps m) => [State] -> [Move] -> ps -> m ((EndGame, [State], [Move]), ps) Source #

prettyEndGame :: (EndGame, [State], [Move]) -> String Source #

prettyEndGame can be used to pretty print the final situation.

isMoveValid :: PrivateView -> Move -> Bool Source #

isMoveValid can be used to check if the candidate Move is compliant to the rule under the current situation. Each player can decide it based on the current PrivateView (without knowing the full state).

help :: String Source #

The help text.

Datatypes

The Class of Strategies

class Strategies ps m Source #

The Strategies class defines the list of Strategys. If all the strategies have the same type, one can use the list instance. I (Susumu) guess that in most cases one can use Dynamic in order to force the same type, but just in case, the tuple instance is also provided. (Also, the tuple instance should be more handy.)

The strategies are used in order, cyclically. The number of strategies need not be the same as numPlayers, though the latter should be a divisor of the former. For normal play, they should be the same. If only one strategy is provided, that means selfplay, though this is not desired because all the hidden info can be memorized. (In order to avoid such cheating, the same strategy should be repeated.) If there are twice as many strategies as numPlayers, the game will be "Pair Hanabi", like "Pair Go" or "Pair Golf" or whatever. (Maybe this is also interesting.)

Minimal complete definition

runARound, broadcast

Instances
(Strategy p m, Monad m) => Strategies [p] m Source # 
Instance details

Defined in Game.Hanabi

Methods

runARound :: ([State] -> [Move] -> m ()) -> [State] -> [Move] -> [p] -> m ((Maybe EndGame, [State], [Move]), [p])

broadcast :: [State] -> [Move] -> [p] -> m [State]

(Strategies p1 m, Strategies p2 m, Monad m) => Strategies (p1, p2) m Source # 
Instance details

Defined in Game.Hanabi

Methods

runARound :: ([State] -> [Move] -> m ()) -> [State] -> [Move] -> (p1, p2) -> m ((Maybe EndGame, [State], [Move]), (p1, p2))

broadcast :: [State] -> [Move] -> (p1, p2) -> m [State]

class Monad m => Strategy p m where Source #

The Strategy class is exactly the interface that AI researchers defining their algorithms have to care about.

Minimal complete definition

strategyName, move

Methods

strategyName :: m p -> m String Source #

strategyName is just the name of the strategy. The designer of the instance should choose one.

move Source #

Arguments

:: [PrivateView]

The history of PrivateViews, new to old.

-> [Move]

The history of Moves, new to old.

-> p

The strategy's current state. This can be isomorphic to () if the strategy does not have any parameter.

-> m (Move, p)

move returns the pair of the Move and the next state, wrapped with monad m that is usually either IO or Identity. The next state can be the same as the current one unless the algorithm is learning on-line during the game.

move is the heart of the strategy. It takes the history of observations and moves, and selects a Move. Because the full history is available, your algorithm can be stateless, but still there is the option to design it in the stateful manner.

observe Source #

Arguments

:: [PrivateView]

The history of PrivateViews, new to old.

-> [Move]

The history of Moves, new to old.

-> p

The strategy's current state. This can be isomorphic to () if the strategy does not have any parameter.

-> m () 

observe is called during other players' turns. It allows (mainly) human players to think while waiting.

It is arguable whether algorithms running on the same machine may think during other players' turn, especially when the game is timed.

Instances
MonadIO m => Strategy ViaHandles m Source # 
Instance details

Defined in Game.Hanabi

MonadIO m => Strategy Blind m Source # 
Instance details

Defined in Game.Hanabi

Methods

strategyName :: m Blind -> m String Source #

move :: [PrivateView] -> [Move] -> Blind -> m (Move, Blind) Source #

observe :: [PrivateView] -> [Move] -> Blind -> m () Source #

(Strategy p m, MonadIO m) => Strategy (Verbose p) m Source # 
Instance details

Defined in Game.Hanabi

Methods

strategyName :: m (Verbose p) -> m String Source #

move :: [PrivateView] -> [Move] -> Verbose p -> m (Move, Verbose p) Source #

observe :: [PrivateView] -> [Move] -> Verbose p -> m () Source #

data Verbose p Source #

Verbose makes a player verbose. It is useful to monitor the viewpoint of a specific player.

Constructors

Verbose 

Fields

Instances
Read p => Read (Verbose p) Source # 
Instance details

Defined in Game.Hanabi

Show p => Show (Verbose p) Source # 
Instance details

Defined in Game.Hanabi

Methods

showsPrec :: Int -> Verbose p -> ShowS #

show :: Verbose p -> String #

showList :: [Verbose p] -> ShowS #

(Strategy p m, MonadIO m) => Strategy (Verbose p) m Source # 
Instance details

Defined in Game.Hanabi

Methods

strategyName :: m (Verbose p) -> m String Source #

move :: [PrivateView] -> [Move] -> Verbose p -> m (Move, Verbose p) Source #

observe :: [PrivateView] -> [Move] -> Verbose p -> m () Source #

data Blind Source #

Instances
MonadIO m => Strategy Blind m Source # 
Instance details

Defined in Game.Hanabi

Methods

strategyName :: m Blind -> m String Source #

move :: [PrivateView] -> [Move] -> Blind -> m (Move, Blind) Source #

observe :: [PrivateView] -> [Move] -> Blind -> m () Source #

data ViaHandles Source #

Constructors

VH 

Fields

Instances
MonadIO m => Strategy ViaHandles m Source # 
Instance details

Defined in Game.Hanabi

data Verbosity Source #

Verbosity is the set of options used by verbose Strategys

Constructors

V 

Fields

Instances
Eq Verbosity Source # 
Instance details

Defined in Game.Hanabi

Read Verbosity Source # 
Instance details

Defined in Game.Hanabi

Show Verbosity Source # 
Instance details

Defined in Game.Hanabi

Generic Verbosity Source # 
Instance details

Defined in Game.Hanabi

Associated Types

type Rep Verbosity :: Type -> Type #

type Rep Verbosity Source # 
Instance details

Defined in Game.Hanabi

The Game Specification

data GameSpec Source #

Constructors

GS 

Fields

Instances
Eq GameSpec Source # 
Instance details

Defined in Game.Hanabi

Read GameSpec Source # 
Instance details

Defined in Game.Hanabi

Show GameSpec Source # 
Instance details

Defined in Game.Hanabi

Generic GameSpec Source # 
Instance details

Defined in Game.Hanabi

Associated Types

type Rep GameSpec :: Type -> Type #

Methods

from :: GameSpec -> Rep GameSpec x #

to :: Rep GameSpec x -> GameSpec #

type Rep GameSpec Source # 
Instance details

Defined in Game.Hanabi

type Rep GameSpec = D1 (MetaData "GameSpec" "Game.Hanabi" "hanabi-dealer-0.2.1.0-APvcobGhNNR8n7mnvi9ksn" False) (C1 (MetaCons "GS" PrefixI True) (S1 (MetaSel (Just "numPlayers") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Int) :*: S1 (MetaSel (Just "rule") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Rule)))

data Rule Source #

Rule is the datatype representing the game variants.

Minor remark
When adopting Variant 4, that is, the rule of continuing even after a round after the pile is exhausted, there can be a situation where a player cannot choose any valid move, because she has no card and there is no hint token. This can happen, after one player (who has no critical card) repeats discarding, and other players repeat hinting each other, consuming hint tokens. Seemingly, the rule book does not state what happens in such a case, but I (Susumu) believe the game should end as failure, then, because
  • This situation can easily be made, and easily be avoided;
  • If deadline is set up, this should cause time out;
  • When Variant 4 is adopted, the game must end with either the perfect game or failure.

See also the definition of checkEndGame.

Constructors

R 

Fields

  • numBlackTokens :: Int

    E.g., if this is 3, the third failure ends the game with failure.

  • funPlayerHand :: [Int]

    memoized function taking the number of players; the default is [5,5,4,4,4,4,4,4,4,4,4,4,4,4]

  • numColors :: Int

    number of colors. 5 for the normal rule, and 6 for Variant 1-3 of the rule book.

  • prolong :: Bool

    continue even after a round after the pile is exhausted. True for Variant 4 of the rule book.

  • numMulticolors :: [Int]

    number of each of multicolor cards. [3,2,2,2,1] for Variant 1 (and Variant 3?), and [1,1,1,1,1] for Variant 2.

Instances
Eq Rule Source # 
Instance details

Defined in Game.Hanabi

Methods

(==) :: Rule -> Rule -> Bool #

(/=) :: Rule -> Rule -> Bool #

Read Rule Source # 
Instance details

Defined in Game.Hanabi

Show Rule Source # 
Instance details

Defined in Game.Hanabi

Methods

showsPrec :: Int -> Rule -> ShowS #

show :: Rule -> String #

showList :: [Rule] -> ShowS #

Generic Rule Source # 
Instance details

Defined in Game.Hanabi

Associated Types

type Rep Rule :: Type -> Type #

Methods

from :: Rule -> Rep Rule x #

to :: Rep Rule x -> Rule #

type Rep Rule Source # 
Instance details

Defined in Game.Hanabi

defaultRule :: Rule Source #

defaultRule is the normal rule from the rule book of the original card game Hanabi.

The Game State and Interaction History

data Move Source #

Constructors

Drop

drop the card (0-origin)

Fields

Play

play the card (0-origin)

Fields

Hint Int (Either Color Number)

give hint to the ith next player

Instances
Eq Move Source # 
Instance details

Defined in Game.Hanabi

Methods

(==) :: Move -> Move -> Bool #

(/=) :: Move -> Move -> Bool #

Read Move Source # 
Instance details

Defined in Game.Hanabi

Show Move Source # 
Instance details

Defined in Game.Hanabi

Methods

showsPrec :: Int -> Move -> ShowS #

show :: Move -> String #

showList :: [Move] -> ShowS #

Generic Move Source # 
Instance details

Defined in Game.Hanabi

Associated Types

type Rep Move :: Type -> Type #

Methods

from :: Move -> Rep Move x #

to :: Rep Move x -> Move #

type Rep Move Source # 
Instance details

Defined in Game.Hanabi

type Index = Int Source #

data State Source #

State consists of all the information of the current game state, including public info, private info, and the hidden deck.

Constructors

St 

Fields

  • publicState :: PublicInfo
     
  • pile :: [Card]

    invisible card pile or deck.

  • hands :: [[Card]]

    partly invisible list of each player's hand. In the current implementation (arguably), this represents [current player's hand, next player's hand, second next player's hand, ...] and this is rotated every turn.

Instances
Eq State Source # 
Instance details

Defined in Game.Hanabi

Methods

(==) :: State -> State -> Bool #

(/=) :: State -> State -> Bool #

Read State Source # 
Instance details

Defined in Game.Hanabi

Show State Source # 
Instance details

Defined in Game.Hanabi

Methods

showsPrec :: Int -> State -> ShowS #

show :: State -> String #

showList :: [State] -> ShowS #

Generic State Source # 
Instance details

Defined in Game.Hanabi

Associated Types

type Rep State :: Type -> Type #

Methods

from :: State -> Rep State x #

to :: Rep State x -> State #

type Rep State Source # 
Instance details

Defined in Game.Hanabi

type Rep State = D1 (MetaData "State" "Game.Hanabi" "hanabi-dealer-0.2.1.0-APvcobGhNNR8n7mnvi9ksn" False) (C1 (MetaCons "St" PrefixI True) (S1 (MetaSel (Just "publicState") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 PublicInfo) :*: (S1 (MetaSel (Just "pile") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 [Card]) :*: S1 (MetaSel (Just "hands") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 [[Card]]))))

data PrivateView Source #

PrivateView is the info that is available to the player that has head hands.

Constructors

PV 

Fields

  • publicView :: PublicInfo
     
  • handsPV :: [[Card]]

    Other players' hands. [next player's hand, second next player's hand, ...] This is based on the viewer's viewpoint (unlike hands which is based on the current player's viewpoint), and the view history [PrivateView] must be from the same player's viewpoint (as the matter of course).

  • invisibleBag :: IntMap Int

    Card -> Int. This represents the bag of unknown cards (which are either in the pile or in the player's hand). This can be computed from publicView and handsSV.

Instances
Eq PrivateView Source # 
Instance details

Defined in Game.Hanabi

Read PrivateView Source # 
Instance details

Defined in Game.Hanabi

Show PrivateView Source # 
Instance details

Defined in Game.Hanabi

Generic PrivateView Source # 
Instance details

Defined in Game.Hanabi

Associated Types

type Rep PrivateView :: Type -> Type #

type Rep PrivateView Source # 
Instance details

Defined in Game.Hanabi

type Rep PrivateView = D1 (MetaData "PrivateView" "Game.Hanabi" "hanabi-dealer-0.2.1.0-APvcobGhNNR8n7mnvi9ksn" False) (C1 (MetaCons "PV" PrefixI True) (S1 (MetaSel (Just "publicView") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 PublicInfo) :*: (S1 (MetaSel (Just "handsPV") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 [[Card]]) :*: S1 (MetaSel (Just "invisibleBag") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (IntMap Int)))))

data PublicInfo Source #

PublicInfo is the info that is available to all players.

Constructors

PI 

Fields

Instances
Eq PublicInfo Source # 
Instance details

Defined in Game.Hanabi

Read PublicInfo Source # 
Instance details

Defined in Game.Hanabi

Show PublicInfo Source # 
Instance details

Defined in Game.Hanabi

Generic PublicInfo Source # 
Instance details

Defined in Game.Hanabi

Associated Types

type Rep PublicInfo :: Type -> Type #

type Rep PublicInfo Source # 
Instance details

Defined in Game.Hanabi

data Result Source #

Result is the result of the last move.

Constructors

None

Hinted or at the beginning of the game

Discard Card 
Success Card 
Fail Card 
Instances
Eq Result Source # 
Instance details

Defined in Game.Hanabi

Methods

(==) :: Result -> Result -> Bool #

(/=) :: Result -> Result -> Bool #

Read Result Source # 
Instance details

Defined in Game.Hanabi

Show Result Source # 
Instance details

Defined in Game.Hanabi

Generic Result Source # 
Instance details

Defined in Game.Hanabi

Associated Types

type Rep Result :: Type -> Type #

Methods

from :: Result -> Rep Result x #

to :: Rep Result x -> Result #

type Rep Result Source # 
Instance details

Defined in Game.Hanabi

data EndGame Source #

EndGame represents the game score, along with the info of how the game ended. It is not just Int in order to distinguish Failure (disaster / no life) from Soso 0 (not playing any card), though Soso 0 does not look more attractive than Failure.

Constructors

Failure 
Soso Int 
Perfect 
Instances
Eq EndGame Source # 
Instance details

Defined in Game.Hanabi

Methods

(==) :: EndGame -> EndGame -> Bool #

(/=) :: EndGame -> EndGame -> Bool #

Read EndGame Source # 
Instance details

Defined in Game.Hanabi

Show EndGame Source # 
Instance details

Defined in Game.Hanabi

Generic EndGame Source # 
Instance details

Defined in Game.Hanabi

Associated Types

type Rep EndGame :: Type -> Type #

Methods

from :: EndGame -> Rep EndGame x #

to :: Rep EndGame x -> EndGame #

type Rep EndGame Source # 
Instance details

Defined in Game.Hanabi

type Rep EndGame = D1 (MetaData "EndGame" "Game.Hanabi" "hanabi-dealer-0.2.1.0-APvcobGhNNR8n7mnvi9ksn" False) (C1 (MetaCons "Failure" PrefixI False) (U1 :: Type -> Type) :+: (C1 (MetaCons "Soso" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Int)) :+: C1 (MetaCons "Perfect" PrefixI False) (U1 :: Type -> Type)))

The Cards

data Card Source #

Constructors

C 

Fields

Instances
Eq Card Source # 
Instance details

Defined in Game.Hanabi

Methods

(==) :: Card -> Card -> Bool #

(/=) :: Card -> Card -> Bool #

Read Card Source # 
Instance details

Defined in Game.Hanabi

Show Card Source # 
Instance details

Defined in Game.Hanabi

Methods

showsPrec :: Int -> Card -> ShowS #

show :: Card -> String #

showList :: [Card] -> ShowS #

Generic Card Source # 
Instance details

Defined in Game.Hanabi

Associated Types

type Rep Card :: Type -> Type #

Methods

from :: Card -> Rep Card x #

to :: Rep Card x -> Card #

type Rep Card Source # 
Instance details

Defined in Game.Hanabi

type Rep Card = D1 (MetaData "Card" "Game.Hanabi" "hanabi-dealer-0.2.1.0-APvcobGhNNR8n7mnvi9ksn" False) (C1 (MetaCons "C" PrefixI True) (S1 (MetaSel (Just "color") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Color) :*: S1 (MetaSel (Just "number") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Number)))

data Color Source #

Constructors

White 
Yellow 
Red 
Green 
Blue 
Multicolor 
Instances
Enum Color Source # 
Instance details

Defined in Game.Hanabi

Eq Color Source # 
Instance details

Defined in Game.Hanabi

Methods

(==) :: Color -> Color -> Bool #

(/=) :: Color -> Color -> Bool #

Read Color Source # 
Instance details

Defined in Game.Hanabi

Show Color Source # 
Instance details

Defined in Game.Hanabi

Methods

showsPrec :: Int -> Color -> ShowS #

show :: Color -> String #

showList :: [Color] -> ShowS #

Generic Color Source # 
Instance details

Defined in Game.Hanabi

Associated Types

type Rep Color :: Type -> Type #

Methods

from :: Color -> Rep Color x #

to :: Rep Color x -> Color #

type Rep Color Source # 
Instance details

Defined in Game.Hanabi

type Rep Color = D1 (MetaData "Color" "Game.Hanabi" "hanabi-dealer-0.2.1.0-APvcobGhNNR8n7mnvi9ksn" False) ((C1 (MetaCons "White" PrefixI False) (U1 :: Type -> Type) :+: (C1 (MetaCons "Yellow" PrefixI False) (U1 :: Type -> Type) :+: C1 (MetaCons "Red" PrefixI False) (U1 :: Type -> Type))) :+: (C1 (MetaCons "Green" PrefixI False) (U1 :: Type -> Type) :+: (C1 (MetaCons "Blue" PrefixI False) (U1 :: Type -> Type) :+: C1 (MetaCons "Multicolor" PrefixI False) (U1 :: Type -> Type))))

data Number Source #

Constructors

Empty 
K1 
K2 
K3 
K4 
K5 
Instances
Bounded Number Source # 
Instance details

Defined in Game.Hanabi

Enum Number Source # 
Instance details

Defined in Game.Hanabi

Eq Number Source # 
Instance details

Defined in Game.Hanabi

Methods

(==) :: Number -> Number -> Bool #

(/=) :: Number -> Number -> Bool #

Ord Number Source # 
Instance details

Defined in Game.Hanabi

Read Number Source # 
Instance details

Defined in Game.Hanabi

Show Number Source # 
Instance details

Defined in Game.Hanabi

Generic Number Source # 
Instance details

Defined in Game.Hanabi

Associated Types

type Rep Number :: Type -> Type #

Methods

from :: Number -> Rep Number x #

to :: Rep Number x -> Number #

type Rep Number Source # 
Instance details

Defined in Game.Hanabi

type Rep Number = D1 (MetaData "Number" "Game.Hanabi" "hanabi-dealer-0.2.1.0-APvcobGhNNR8n7mnvi9ksn" False) ((C1 (MetaCons "Empty" PrefixI False) (U1 :: Type -> Type) :+: (C1 (MetaCons "K1" PrefixI False) (U1 :: Type -> Type) :+: C1 (MetaCons "K2" PrefixI False) (U1 :: Type -> Type))) :+: (C1 (MetaCons "K3" PrefixI False) (U1 :: Type -> Type) :+: (C1 (MetaCons "K4" PrefixI False) (U1 :: Type -> Type) :+: C1 (MetaCons "K5" PrefixI False) (U1 :: Type -> Type))))

Utilities

Hints

isCritical :: PublicInfo -> Card -> Bool Source #

A critical card is a useful card and the last card that has not been dropped.

Unmarked critical card on the chop should be marked.

isUseless :: PublicInfo -> Card -> Bool Source #

isUseless pi card means either the card is already played or it is above the bestPossibleRank.

bestPossibleRank :: PublicInfo -> Color -> Number Source #

the best achievable rank for each color.

Minor ones

what'sUp :: Show a => Verbosity -> [Char] -> [PrivateView] -> [a] -> [Char] Source #

ithPlayer :: (Eq a, Num a, Show a) => p -> a -> [Char] Source #

recentEvents :: Show a => (Int -> Int -> [Char]) -> [PrivateView] -> [a] -> String Source #

ithPlayerFromTheLast :: (Eq a, Num a, Show a) => a -> a -> [Char] Source #