hanabi-dealer-0.7.1.0: Game/Hanabi/Strategies/SimpleStrategy.hs
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
module Game.Hanabi.Strategies.SimpleStrategy where
import Game.Hanabi hiding (main)
import System.Random
import Data.Maybe(isNothing)
-- An example of a simple and stupid strategy.
data Simple = S
instance Monad m => Strategy Simple m where
strategyName ms = return "Stupid example strategy"
move (pv:_) mvs s = let pub = publicView pv
nextPlayersHand = head $ handsPV pv ::[Card]
nextPlayersHints = givenHints pub !! 1
nextPlayer = zip3 [0..] nextPlayersHand nextPlayersHints
myHints = head $ givenHints pub
myPos = head $ possibilities pub
numHand = length myHints
mov = case filter (\(ix, te, hint) -> not (isHinted hint) && isCritical pub te) nextPlayer of
[] -> foo
us -> tryMove pv (Hint 1 $ Right (number $ sndOf3 $ last us)) foo
where foo = case break (\(_,card,_) -> isPlayable pub card) nextPlayer of
(ts,(_,d,(Nothing, _)) :_) | hintTokens pub >= 3 && all (\(_,c,_) -> color c /= color d) ts -> Hint 1 $ Left $ color d
(ts,(_,d,(Just _, Nothing)):_) | hintTokens pub >= 4 -> Hint 1 $ Right $ number d -- This should actually be ANY card.
_ ->
case filter (\(i,marks,pos) -> isDefinitelyPlayable pv marks pos) $ zip3 [0..] myHints myPos of
(i,_,_):_ -> Play i
[] ->
case mvs of
Hint 1 (Left c) : _ | isDefinitelyUseless pv (myHints!!i) (myPos!!i) -> tryMove pv (Drop i) rest
| otherwise -> Play i
where i = length $ takeWhile ((/=Just c) . fst) $ head $ givenHints $ publicView pv
_ -> rest
where rest = case definiteChopss pv myHints myPos of
((i:_):_) -> tryMove pv (Drop i)
(Hint 1 $ Right $ number $ last $ nextPlayersHand)
_ -> tryMove pv (Hint 1 $ Right $ number $ last $ nextPlayersHand)
(Drop $ pred numHand)
in return (mov, s)
sndOf3 (_,b,_) = b
main = do g <- newStdGen
-- ((eg,_),_) <- start defaultGS [] ([S],[stdio]) g -- Play it with standard I/O (human player).
((eg,_),_) <- start defaultGS [peek] [S,S] g -- Play it with itself.
putStrLn $ prettyEndGame eg