module Game.LambdaHack.Client.MonadClient
(
MonadClientRead ( getsClient
, liftIO
)
, MonadClient(modifyClient)
, getClient, putClient
, debugPossiblyPrint, createTabBFS, rndToAction, rndToActionForget
) where
import Prelude ()
import Game.LambdaHack.Core.Prelude
import Control.Monad.ST.Strict (stToIO)
import qualified Control.Monad.Trans.State.Strict as St
import Data.Bits (finiteBitSize, xor, (.&.))
import qualified Data.Primitive.PrimArray as PA
import qualified Data.Text.IO as T
import System.IO (hFlush, stdout)
import qualified System.Random as R
import Game.LambdaHack.Client.ClientOptions
import Game.LambdaHack.Client.State
import Game.LambdaHack.Common.Kind
import Game.LambdaHack.Common.MonadStateRead
import Game.LambdaHack.Common.Point
import Game.LambdaHack.Common.State
import Game.LambdaHack.Common.Time
import Game.LambdaHack.Content.RuleKind
import Game.LambdaHack.Core.Random
class MonadStateRead m => MonadClientRead m where
getsClient :: (StateClient -> a) -> m a
liftIO :: IO a -> m a
class MonadClientRead m => MonadClient m where
modifyClient :: (StateClient -> StateClient) -> m ()
getClient :: MonadClientRead m => m StateClient
getClient = getsClient id
putClient :: MonadClient m => StateClient -> m ()
putClient s = modifyClient (const s)
debugPossiblyPrint :: MonadClient m => Text -> m ()
debugPossiblyPrint t = do
sdbgMsgCli <- getsClient $ sdbgMsgCli . soptions
when sdbgMsgCli $ liftIO $ do
T.hPutStrLn stdout t
hFlush stdout
createTabBFS :: MonadClient m => m (PA.PrimArray PointI)
createTabBFS = do
COps{corule=RuleContent{rXmax, rYmax}} <- getsState scops
liftIO $ stToIO $ do
tabAMutable <- PA.newPrimArray (rXmax * rYmax)
PA.unsafeFreezePrimArray tabAMutable
rndToAction :: MonadClient m => Rnd a -> m a
rndToAction r = do
gen1 <- getsClient srandom
let (a, gen2) = St.runState r gen1
modifyClient $ \cli -> cli {srandom = gen2}
return a
rndToActionForget :: MonadClientRead m => Rnd a -> m a
rndToActionForget r = do
gen <- getsClient srandom
let i = fst $ R.next gen
time <- getsState stime
let positiveIntSize = finiteBitSize (1 :: Int) - 1
oneBitsPositiveInt = 2 ^ positiveIntSize - 1
timeSmallBits = fromEnum $ timeTicks time .&. oneBitsPositiveInt
genNew = R.mkStdGen $ i `xor` timeSmallBits
return $! St.evalState r genNew