packages feed

hanabi-dealer-0.15.1.1: Game/Hanabi/Strategies/EndGameSearch.hs

{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, CPP #-}
module Game.Hanabi.Strategies.EndGameSearch where
import Game.Hanabi hiding (main)
import Game.Hanabi.Strategies.EndGameLite
import Game.Hanabi.Strategies.EndGameOld
import Game.Hanabi.Strategies.Stateless hiding (main)
import Game.Hanabi.Strategies.SimpleStrategy hiding (main)
import System.Random


-- x #define EXACT

-- A strategy with endgame search
#ifdef EXACT
data EndGameSearch = EG Stateless | EGS Stateless (EndGameMirrorLite Stateless (EndGameLite Stateless Stateless [EndGameMirrorLite Stateless Stateless]))
mkEG :: Stateless -> Int -> EndGameMirrorLite Stateless (EndGameLite Stateless Stateless [EndGameMirrorLite Stateless Stateless])
#else
data EndGameSearch = EG Stateless | EGS Stateless (EndGameMirrorLite Stateless (EndGameLite Stateless Stateless [Stateless]))
mkEG :: Stateless -> Int -> EndGameMirrorLite Stateless (EndGameLite Stateless Stateless [Stateless])
#endif
mkEG fb nump =
     -- assumeOthersAre SL SL
     -- searchExhaustivelyLite SL
#ifdef EXACT
     searchExhaustivelyLite $ assumeOthers fb $ searchExhaustivelyLite fb -- This is more exact, but sometimes prohibitively time-consuming.
#else
     searchExhaustivelyLite $ assumeOthers fb $ SL $ S False
#endif
     -- searchExhaustively SL
     -- assumeOthersAreSL SL
     -- searchExhaustively $ assumeOthersAreSL SL
  where
                                    searchExhaustivelyLite :: s -> EndGameMirrorLite Stateless s
                                    searchExhaustivelyLite fallback = egml (\pub -> pileNum pub == 0) (SL $ S False) fallback nump
                                    assumeOthers fallback other = egl (\pub -> pileNum pub <= 1) (SL $ S False) fallback $ replicate (pred nump) other
                                    searchExhaustively fallback = egmo (\pub -> pileNum pub == 0) fallback nump
                                    assumeOthersAreSL  fallback = EGO (\pub -> pileNum pub <= 1 && hintTokens pub <= 2) fallback $ replicate (pred nump) SL
--                                    assumeOthersAreSL  fallback = EGO (\pub -> pileNum pub <=2 && hintTokens pub <= 4) fallback $ replicate (pred nump) SL
--                                    assumeOthersAreSL  fallback = EGO (\pub -> pileNum pub + hintTokens pub < 4) fallback $ replicate (pred nump) SL

instance (Monad m) => Strategy EndGameSearch m where
  strategyName ms = return "EndGame"
  move pvs@(pv:_) mvs (EG pd) = do (m, e') <- move (sontakuColorHint pvs mvs) mvs $ mkEG pd $ numPlayers $ gameSpec $ publicView pv
                                   return (m, EGS pd e')
  move pvs@(pv:_) mvs (EGS pd e) = do (m, e') <- move (sontakuColorHint pvs mvs) mvs e
                                      return (m, if pileNum (publicView pv) > 1 then EG pd else EGS pd e')
main = do g <- newStdGen
          ((eg,_),_) <- start defaultGS [] ([EG $ SL $ S False], [stdio]) g -- Play it with standard I/O (human player).
--          ((eg,_),_) <- start defaultGS [peek] [EG False, EG False] g -- Play it with itself.
          putStrLn $ prettyEndGame eg