initial framework added
[fp1415-soccerfun.git] / src / Game / randomstream.icl
diff --git a/src/Game/randomstream.icl b/src/Game/randomstream.icl
new file mode 100644 (file)
index 0000000..f5a907e
--- /dev/null
@@ -0,0 +1,101 @@
+implementation module randomstream\r
+\r
+import StdEnv, StdEnvExt\r
+import RandomExt\r
+\r
+::     Stream a :== [a]\r
+\r
+randomStream                                   :: !Int !([Int] -> a) !RandomSeed -> Stream a\r
+randomStream nrInts transform seed\r
+       # (ints,seed)                           = randoms nrInts seed\r
+       = [transform ints : randomStream nrInts transform seed]\r
+where\r
+       randoms                                         :: !Int !RandomSeed -> (![Int],!RandomSeed)\r
+       randoms 0 seed                          = ([],seed)\r
+       randoms n seed\r
+               # (r, seed)                             = random seed\r
+               # (rs,seed)                             = randoms (n-1) seed\r
+               = ([r:rs],seed)\r
+\r
+intRandomStream                                        :: !RandomSeed -> Stream Int\r
+intRandomStream seed                   = randomStream 2 createInt seed\r
+where\r
+       createInt                                       :: ![Int] -> Int\r
+       createInt [a,b]                         = if (isOdd a) -1 1 * (abs b)\r
+       createInt _                                     = abort "Fatal error: intRandomStream applied to unexpected number of integers.\n"\r
+\r
+realRandomStream                               :: !RandomSeed -> Stream Real\r
+realRandomStream seed                  = randomStream 4 createReal seed\r
+where\r
+       createReal                                      :: ![Int] -> Real\r
+       createReal [s,a,b,c]            = toReal (if (isOdd s) "-" "" <+++ abs a <+++ "." <+++ abs b <+++ "E" <+++ (c rem 100))\r
+       createReal _                            = abort "Fatal error: realRandomStream applied to unexpected number of integers.\n"\r
+\r
+boolRandomStream                               :: !RandomSeed -> Stream Bool\r
+boolRandomStream seed                  = randomStream 1 createBool seed\r
+where\r
+       createBool                                      :: ![Int] -> Bool\r
+       createBool [i]                          = isEven i\r
+       createBool _                            = abort "Fatal error: boolRandomStream applied to unexpected number of integers.\n"\r
+\r
+probabilityRandomStream                        :: !RandomSeed -> Stream P\r
+probabilityRandomStream seed   = randomStream 2 createProbability seed\r
+where\r
+       createProbability                       :: ![Int] -> P\r
+       createProbability [a,b]\r
+               | b==0                                  = 1.0\r
+               | otherwise                             = (toReal a`) / (toReal b`)\r
+       where\r
+               [a`,b`:_]                               = sort [abs a,abs b]\r
+       createProbability _                     = abort "Fatal error: probabilityRandomStream applied to unexpected number of integers.\n"\r
+\r
+onesStream                                             :: Stream P\r
+onesStream                                             = [one,one..]\r
+\r
+nextRandomInt                                  :: !RandomSeed -> .(!Int, !RandomSeed)\r
+nextRandomInt seed\r
+       # (r1,seed)                                     = random seed\r
+       # (r2,seed)                                     = random seed\r
+       = (if (isOdd r1) -1 1 * (abs r2),seed)\r
+\r
+nextRandomReal                                 :: !RandomSeed -> .(!Real,!RandomSeed)\r
+nextRandomReal seed\r
+       # (r1,seed)                                     = random seed\r
+       # (r2,seed)                                     = random seed\r
+       # (r3,seed)                                     = random seed\r
+       # (r4,seed)                                     = random seed\r
+       = (toReal (if (isOdd r1) "-" "" <+++ abs r2 <+++ "." <+++ abs r3 <+++ "E" <+++ (r4 rem 100)),seed)\r
+       \r
+nextRandomBool                                 :: !RandomSeed -> .(!Bool,!RandomSeed)\r
+nextRandomBool seed\r
+       # (r1,seed)                                     = random seed\r
+       = (isEven r1,seed)\r
+\r
+nextRandomP                                            :: !RandomSeed -> .(!P,   !RandomSeed)\r
+nextRandomP seed\r
+       # (r1,seed)                                     = random seed\r
+       # (r2,seed)                                     = random seed\r
+       # (a,b)                                         = minmax (abs r1,abs r2)\r
+       = (if (r2==0) 1.0 ((toReal a)/(toReal b)),seed)\r
+\r
+next1                                                  :: !RandomSeed -> .(!P,   !RandomSeed)\r
+next1 seed                                             = (1.0,seed)\r
+\r
+/** make the random realistic, as in, small errors occur more often:\r
+               \r -> 1.0-r^4\r
+               zero <= r <= 1.0\r
+*/\r
+makeRandomRealistic                            :: !P -> P\r
+makeRandomRealistic r                  = 1.0-r^4.0\r
+\r
+makeRandomRealisticSkilled             :: !P -> P\r
+makeRandomRealisticSkilled r   = 1.0-r^10.0\r
+\r
+selectMostProbableAction               :: ![(P,a)] !RandomSeed -> (!Maybe a,!RandomSeed)\r
+selectMostProbableAction odds seed\r
+       = case sortBy (\(p1,_) (p2,_) -> p1 > p2) (filter (\(p,_) -> p > zero) odds) of\r
+               []                                              = (Nothing,seed)\r
+               odds=:[(p,_):_]                 = let mostProbable      = takeWhile ((==) p o fst) odds\r
+                                                                     nr                        = length mostProbable\r
+                                                                     (p1,seed1)        = nextRandomP seed\r
+                                                                  in (Just (snd (odds !! (entier (p1 * toReal nr)))),seed1)\r