Add players and strategies

This commit is contained in:
Barak Michener 2014-11-13 16:50:33 -05:00
parent c83a0541c2
commit 76e60894cd

View file

@ -4,6 +4,9 @@ import Control.Monad
import Control.Monad.Trans.Maybe
import Data.List
import Data.Maybe
import Data.Ord
import System.IO.Unsafe
data Cup = Cup {
green :: Int,
@ -131,8 +134,83 @@ playRound (Just player) = do
{-outcome <- rollHand playerWithHand-}
{-return $ acceptOutcome playerWithHand outcome-}
type StratFunction = Int -> [Int] -> PlayerState -> IO Bool
maxi xs = maximumBy (comparing fst) (zip xs [0..])
replace pos newVal list = take pos list ++ newVal : drop (pos+1) list
playZombieRound strat playerIndex scores = playZombieRound' strat playerIndex scores defaultPlayer
playZombieRound' :: (RandomGen g) => StratFunction -> Int -> [Int] -> PlayerState -> Rand g Int
playZombieRound' strat index scores state = do
if continue
then do
newState <- playRound (Just state)
if (isNothing newState)
then return (scores !! index)
else playZombieRound' strat index scores (fromJust newState)
else
return $ (scores !! index) + (brains state)
where continue = unsafePerformIO $ strat index scores state
playZombieDice playerStrats = evalRandIO $ playZombieDice' playerStrats 0 (-1) $ take (length playerStrats) $ repeat 0
playZombieDice' playerStrats playerIndex final scores =
if playerIndex == nPlayers
then playZombieDice' playerStrats 0 final scores
else if final == playerIndex then return $ snd $ maxi scores
else if (foldl max 0 scores) >= 13 && final == -1
then playZombieDice' playerStrats playerIndex newFinal scores
else do
newscore <- playZombieRound (playerStrats !! playerIndex) playerIndex scores
let newscores = replace playerIndex newscore scores in
playZombieDice' playerStrats (playerIndex + 1) final newscores
where nPlayers = length scores
newFinal = if (playerIndex == 0) then (nPlayers - 1) else (playerIndex - 1)
humanPlayer index scores state = do
putStrLn "\n"
putStrLn $ "Your Score: " ++ show (scores !! index)
putStrLn $ "Scores: " ++ show (scores) ++ " Index " ++ show index
putStrLn $ "Your State:"
print state
putStrLn "Continue?"
response <- getLine
if response == "y" then return True else return False
getNPlayer :: Int -> StratFunction
getNPlayer n index scores state = do
if (brains state) < n then return True else return False
getFourPlayer = getNPlayer 4
getFivePlayer = getNPlayer 5
fiftyFiftyPlayer :: Int -> StratFunction
fiftyFiftyPlayer n index scores state =
if brains state == 0 then return True else do
outcomeStates <- replicateM n (evalRandIO $ playNRounds 1 state)
if length (filter isJust outcomeStates) > ((3 * (quot n 4)) - (quot n 7)) then return True else return False
expectimaxPlayer :: Int -> Float -> StratFunction
expectimaxPlayer n limit index scores state = do
outcomeStates <- replicateM n (evalRandIO $ playNRounds 1 state)
let scoretotal = sum $ map (\x -> x - (brains state)) $ map brains $ catMaybes outcomeStates in
let badscore = failScore * (length $ filter isNothing outcomeStates) in
let expectedValue = (fromIntegral (scoretotal + badscore)) / (fromIntegral n) in do
{-print state-}
{-print expectedValue -}
if expectedValue > limit then return True else return False
where failScore = 0 - (brains state)
main = mainN 8 100000
playAndReport strats x = do
out <- replicateM x (playZombieDice strats)
print $ report out
mainN n x = do
outcomeStates <- replicateM x (evalRandIO $ playNRounds n defaultPlayer)
print "brains"