diff options
Diffstat (limited to 'calculette_aoo/lib/roll.ml')
-rw-r--r-- | calculette_aoo/lib/roll.ml | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/calculette_aoo/lib/roll.ml b/calculette_aoo/lib/roll.ml new file mode 100644 index 0000000..00d8465 --- /dev/null +++ b/calculette_aoo/lib/roll.ml @@ -0,0 +1,81 @@ +open StdLabels + +(** Evaluate the coefficient for the product of two polynamials *) +let mul p1 p2 = + let n1 = Array.length p1 and n2 = Array.length p2 in + let n = n1 + n2 in + let res = Array.make n 0 in + for i = 0 to n1 - 1 do + for j = 0 to n2 - 1 do + res.(i + j + 1) <- res.(i + j + 1) + (p1.(i) * p2.(j)) + done + done; + res + +(** Apply a power function over a polynomial *) +let pow p1 n = + let result = ref p1 in + for _ = 1 to n - 1 do + result := mul !result p1 + done; + !result + +(** Evaluate the odd to win agains a give difficulty *) +let against : int -> int array -> Q.t array = + fun n difficulties -> + match n with + | 0 -> Array.map ~f:(fun _ -> Q.zero) difficulties + | _ -> + (* Create the polynomial with the odd ratio for the given caracteristic *) + let arr = Array.make 3 1 in + let frequencies = pow arr n in + let ratio = Z.(of_int 3 ** n) in + + let get_chances difficulty = + (* Evaluate the ratio to win the roll *) + let chances = ref Z.zero in + for i = difficulty - 1 to Array.length frequencies - 1 do + (* The index in the table is the odd to get exactly this value in the roll. + Here, we just add every value in the array from the index strarting from + the given difficulty. *) + chances := Z.(!chances + of_int frequencies.(i)) + done; + Q.make !chances ratio + in + Array.map ~f:get_chances difficulties + +(** Compare two caracteristics. + [compare v1 v2] will evaluate the odds to win if the player has the + caracteristics [v1] against the openent [v2]. + + In case of equality, the win is given to [v1] *) +let compare : int -> int -> Q.t = + fun carac1 carac2 -> + let arr = Array.make 3 1 in + let z3 = Z.of_int 3 in + + let ordinal1 = Z.(z3 ** carac1) + and ordinal2 = Z.(z3 ** carac2) + (*Number of possibles values for each caracteristc *) + and elements1 = 3 * carac1 + and elements2 = 3 * carac2 in + + (* The number of iterations to do is elements1 × elements2. For every iteration of elements2, we have ordinal1 points to get. *) + let cases = Z.(ordinal1 * ordinal2) in + + let frequencies_1 = pow arr carac1 |> Array.map ~f:(fun v -> Z.(of_int v)) + and frequencies_2 = pow arr carac2 |> Array.map ~f:(fun v -> Z.(of_int v)) in + + (* Now, compare for each values the probabily to win *) + let res = ref Z.zero in + let () = + for i = 0 to elements1 - 1 do + for j = 0 to elements2 - 1 do + if i >= j then + (* Number of times this combinaison is occuring *) + let freq = Z.(frequencies_1.(i) * frequencies_2.(j)) in + Z.(res := !res + freq) + done + done + in + Q.make !res cases |