これはStateTモナドを学習するための練習です。プログラムはゲームMorraを実装します。 2人のプレーヤーはコンピュータと人物です。状態は、コンピュータとプレーヤーのスコアを蓄積します。このプログラムは、関数morraの1回の反復で機能します。しかし、私はそれをループする方法を失っています。私はいくつかのことを試しましたが、何も動かないようです。StateTモナドを使用したループ
module Morra where
import Control.Monad.Trans.State.Lazy
import Control.Monad.IO.Class
import Data.Char (isDigit, digitToInt)
import System.Random (randomRIO)
import Control.Monad (when)
morra :: StateT (Int, Int) IO()
morra = do
p <- liftIO getChar
when (isDigit p) $
do
let p' = digitToInt p
c <- liftIO $ randomRIO (1, 2)
liftIO $ putStrLn ['P',':',' ',p] --"P: " ++ p)
liftIO $ putStrLn ("C: " ++ show c)
(pt, ct) <- get
if even (c + p') then
do
liftIO $ putStrLn "Computer Wins"
put (pt, ct + 1)
else
do
liftIO $ putStrLn "Player Wins"
put (pt + 1, ct)
main :: IO()
main = do
putStrLn "-- p is Player"
putStrLn "-- c is Computer"
putStrLn "-- Player is odds, Computer is evens."
fScore <- runStateT morra (0,0)
let personS = fst . snd $ fScore
compS = snd . snd $ fScore
putStrLn ("Person Score: " ++ show personS)
putStrLn ("Computer Score: " ++ show compS)
if personS > compS then
putStrLn "Winner is Person"
else
putStrLn "Winner is Computer"
ありがとう:これは最終的なコードです。しかし、私は関数morraのループが必要です。ファンクションメインは1回だけ実行されます。関数の最後に 'morra'を置くと(whenの後の' do'に沿って)何も起こりません。 – user1897830
@ user1897830あなたは 'when'(インジケートされた2つのスペースのみ)でインラインにする必要があります。 'whenDigit p'がtrueのときにのみループします。何も起こっていないということはどういう意味ですか?すぐに終了するのですか、それともループに巻き込まれてしまいますか? – Lazersmoke
'isDigit p'が真のときだけループする必要があります。 'isDigit p'が真でなくて終了するまでループします。しかし、私が 'モラ 'を単に中に入れると、それは単に出てループしません。 – user1897830