Add players and strategies
This commit is contained in:
parent
c83a0541c2
commit
76e60894cd
1 changed files with 78 additions and 0 deletions
|
|
@ -4,6 +4,9 @@ import Control.Monad
|
||||||
import Control.Monad.Trans.Maybe
|
import Control.Monad.Trans.Maybe
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
|
import Data.Ord
|
||||||
|
import System.IO.Unsafe
|
||||||
|
|
||||||
|
|
||||||
data Cup = Cup {
|
data Cup = Cup {
|
||||||
green :: Int,
|
green :: Int,
|
||||||
|
|
@ -131,8 +134,83 @@ playRound (Just player) = do
|
||||||
{-outcome <- rollHand playerWithHand-}
|
{-outcome <- rollHand playerWithHand-}
|
||||||
{-return $ acceptOutcome playerWithHand outcome-}
|
{-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
|
main = mainN 8 100000
|
||||||
|
|
||||||
|
playAndReport strats x = do
|
||||||
|
out <- replicateM x (playZombieDice strats)
|
||||||
|
print $ report out
|
||||||
|
|
||||||
mainN n x = do
|
mainN n x = do
|
||||||
outcomeStates <- replicateM x (evalRandIO $ playNRounds n defaultPlayer)
|
outcomeStates <- replicateM x (evalRandIO $ playNRounds n defaultPlayer)
|
||||||
print "brains"
|
print "brains"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue