]> git.rkrishnan.org Git - yorgey.git/blobdiff - hw12/Risk.hs
hw12: exercise 4
[yorgey.git] / hw12 / Risk.hs
index b78ac1002e30e094e6fa72e989a578dd84d2d69a..31298fa51df74d71d0addf55252a24eeafb01f5a 100644 (file)
@@ -4,8 +4,8 @@ module Risk where
 
 import Control.Applicative
 import Control.Monad.Random
-import Control.Monad(replicateM, liftM)
-import Data.List(sort)
+import Control.Monad(replicateM, liftM, foldM)
+import Data.List(sortBy)
 
 ------------------------------------------------------------
 -- Die values
@@ -30,10 +30,34 @@ type Army = Int
 
 data Battlefield = Battlefield { attackers :: Army, defenders :: Army }
 
--- battle :: Battlefield -> Rand StdGen Battlefield
+newBattlefield :: Battlefield -> [DieValue] -> [DieValue] -> Battlefield
+newBattlefield battlefield rollA rollB =
+    let pairList = zip (sortBy (flip compare) rollA) (sortBy (flip compare) rollB)
+    in
+      foldr (\(a, d) acc -> if a > d then Battlefield (attackers acc) ((defenders acc) - 1)
+                            else Battlefield ((attackers acc) - 1)  (defenders acc)) battlefield pairList
+
+
+battle :: Battlefield -> Rand StdGen Battlefield
 battle (Battlefield {attackers = a, defenders = d}) =
   let rolla = replicateM (min (a - 1) 3) die
       rolld = replicateM (min d 2) die
-      zipped = liftA2 zip rolla rolld
   in
-   
+    liftA2 (newBattlefield (Battlefield a d)) rolla rolld
+
+-- exercise 3.
+endgame :: Battlefield -> Bool
+endgame (Battlefield {attackers=a, defenders=d}) = d == 0 || a < 2
+
+enemyDestroyed :: Battlefield -> Bool
+enemyDestroyed bf = endgame bf && (defenders bf) == 1
+
+invade :: Battlefield -> Rand StdGen Battlefield
+-- invade battlefield = foldM (\acc f -> f $ acc) battlefield (repeat battle)
+invade battlefield = battle battlefield >>= \bf ->
+                     if (endgame bf) then return bf
+                     else invade bf
+-- exercise 4
+successProb :: Battlefield -> Rand StdGen Double
+successProb battlefield = (pure (filter enemyDestroyed) <*> replicateM 1000 (invade battlefield))
+                          >>= \xs -> return (fromIntegral (length xs) / 1000)