--- /dev/null
+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