initial framework added
[fp1415-soccerfun.git] / src / Game / randomstream.icl
1 implementation module randomstream
2
3 import StdEnv, StdEnvExt
4 import RandomExt
5
6 :: Stream a :== [a]
7
8 randomStream :: !Int !([Int] -> a) !RandomSeed -> Stream a
9 randomStream nrInts transform seed
10 # (ints,seed) = randoms nrInts seed
11 = [transform ints : randomStream nrInts transform seed]
12 where
13 randoms :: !Int !RandomSeed -> (![Int],!RandomSeed)
14 randoms 0 seed = ([],seed)
15 randoms n seed
16 # (r, seed) = random seed
17 # (rs,seed) = randoms (n-1) seed
18 = ([r:rs],seed)
19
20 intRandomStream :: !RandomSeed -> Stream Int
21 intRandomStream seed = randomStream 2 createInt seed
22 where
23 createInt :: ![Int] -> Int
24 createInt [a,b] = if (isOdd a) -1 1 * (abs b)
25 createInt _ = abort "Fatal error: intRandomStream applied to unexpected number of integers.\n"
26
27 realRandomStream :: !RandomSeed -> Stream Real
28 realRandomStream seed = randomStream 4 createReal seed
29 where
30 createReal :: ![Int] -> Real
31 createReal [s,a,b,c] = toReal (if (isOdd s) "-" "" <+++ abs a <+++ "." <+++ abs b <+++ "E" <+++ (c rem 100))
32 createReal _ = abort "Fatal error: realRandomStream applied to unexpected number of integers.\n"
33
34 boolRandomStream :: !RandomSeed -> Stream Bool
35 boolRandomStream seed = randomStream 1 createBool seed
36 where
37 createBool :: ![Int] -> Bool
38 createBool [i] = isEven i
39 createBool _ = abort "Fatal error: boolRandomStream applied to unexpected number of integers.\n"
40
41 probabilityRandomStream :: !RandomSeed -> Stream P
42 probabilityRandomStream seed = randomStream 2 createProbability seed
43 where
44 createProbability :: ![Int] -> P
45 createProbability [a,b]
46 | b==0 = 1.0
47 | otherwise = (toReal a`) / (toReal b`)
48 where
49 [a`,b`:_] = sort [abs a,abs b]
50 createProbability _ = abort "Fatal error: probabilityRandomStream applied to unexpected number of integers.\n"
51
52 onesStream :: Stream P
53 onesStream = [one,one..]
54
55 nextRandomInt :: !RandomSeed -> .(!Int, !RandomSeed)
56 nextRandomInt seed
57 # (r1,seed) = random seed
58 # (r2,seed) = random seed
59 = (if (isOdd r1) -1 1 * (abs r2),seed)
60
61 nextRandomReal :: !RandomSeed -> .(!Real,!RandomSeed)
62 nextRandomReal seed
63 # (r1,seed) = random seed
64 # (r2,seed) = random seed
65 # (r3,seed) = random seed
66 # (r4,seed) = random seed
67 = (toReal (if (isOdd r1) "-" "" <+++ abs r2 <+++ "." <+++ abs r3 <+++ "E" <+++ (r4 rem 100)),seed)
68
69 nextRandomBool :: !RandomSeed -> .(!Bool,!RandomSeed)
70 nextRandomBool seed
71 # (r1,seed) = random seed
72 = (isEven r1,seed)
73
74 nextRandomP :: !RandomSeed -> .(!P, !RandomSeed)
75 nextRandomP seed
76 # (r1,seed) = random seed
77 # (r2,seed) = random seed
78 # (a,b) = minmax (abs r1,abs r2)
79 = (if (r2==0) 1.0 ((toReal a)/(toReal b)),seed)
80
81 next1 :: !RandomSeed -> .(!P, !RandomSeed)
82 next1 seed = (1.0,seed)
83
84 /** make the random realistic, as in, small errors occur more often:
85 \r -> 1.0-r^4
86 zero <= r <= 1.0
87 */
88 makeRandomRealistic :: !P -> P
89 makeRandomRealistic r = 1.0-r^4.0
90
91 makeRandomRealisticSkilled :: !P -> P
92 makeRandomRealisticSkilled r = 1.0-r^10.0
93
94 selectMostProbableAction :: ![(P,a)] !RandomSeed -> (!Maybe a,!RandomSeed)
95 selectMostProbableAction odds seed
96 = case sortBy (\(p1,_) (p2,_) -> p1 > p2) (filter (\(p,_) -> p > zero) odds) of
97 [] = (Nothing,seed)
98 odds=:[(p,_):_] = let mostProbable = takeWhile ((==) p o fst) odds
99 nr = length mostProbable
100 (p1,seed1) = nextRandomP seed
101 in (Just (snd (odds !! (entier (p1 * toReal nr)))),seed1)