aboutsummaryrefslogtreecommitdiff
path: root/calculette_aoo/js/main.ml
blob: 3106041b43cae6d7fefeb826960d0ac94be253ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
open Brr
open StdLabels

let ( let=? ) : 'a option -> ('a -> unit) -> unit =
 fun f opt -> Option.iter opt f

let get_int_value element =
  let value = El.prop El.Prop.value element in
  match Jstr.to_int value with
  | Some v -> v
  | None -> 0

let cout_a = (800, 200, 100)
let cout_m = (110, 55, 35)
let cout_rm = (50, 40, 20)
let cout_pm = (5, 3, 1)
let cout_fm = (100, 50, 30)

let get_element_by_id id =
  Jstr.of_string id |> Brr.Document.find_el_by_id Brr.G.document

let distance_table fm =
  Array.init 4 ~f:(fun i ->
      Array.init 7 ~f:(fun i -> max 1 ((i + 4) * 4))
      |> Aoo.Roll.against (fm + i)
      |> Array.map ~f:(fun v -> Q.to_float v *. 100.))

let get_int_element id =
  Jstr.of_string id
  |> Brr.Document.find_el_by_id Brr.G.document
  |> Option.map get_int_value |> Option.value ~default:0

let eval _ =
  let a_element = get_int_element "a" in
  let m_element = get_int_element "m" in
  let rm_element = get_int_element "rm" in
  let fm_element = get_int_element "fm" in
  let pm_element = get_int_element "pm" in

  let a_bonus = get_int_element "a_bonus" in
  let m_bonus = get_int_element "m_bonus" in
  let rm_bonus = get_int_element "rm_bonus" in
  let fm_bonus = get_int_element "fm_bonus" in
  let pm_bonus = get_int_element "pm_bonus" in

  let a = Aoo.Carac.create ~bonus:a_bonus a_element cout_a in
  let m = Aoo.Carac.create ~bonus:m_bonus m_element cout_m in
  let rm = Aoo.Carac.create ~bonus:rm_bonus rm_element cout_rm in
  let fm = Aoo.Carac.create ~bonus:fm_bonus fm_element cout_fm in
  let pm = Aoo.Carac.create ~bonus:pm_bonus pm_element cout_pm in

  let build = Aoo.Build.{ a; m; rm; fm; pm } in

  (* Evaluate the cost for the given upgrades *)
  let cost = Aoo.Build.cost build in

  let fm_oponent = get_int_element "fm_oponent" in
  let env : Aoo.Build.env =
    {
      cost_max = get_int_element "xp" + cost
    ; max_tours = get_int_element "tours"
    ; cout_sort = get_int_element "cost"
    ; degat_sort = get_int_element "dammage"
    ; fm_oponent
    ; frequencies = Aoo.Build.buil_freq_table fm_element fm_oponent
    }
  in
  let upgrades =
    match Aoo.Build.upgrade env build with
    | [] ->
        (* If there is no upgrade available, return the current build as a
           solution instead of nothing. *)
        [ build ]
    | upgrades -> upgrades
  in
  let build =
    Aoo.Build.traverse env
      (Aoo.Build.cost build, Aoo.Build.score env build)
      upgrades
  in

  let () = Aoo.Build.repr env Format.str_formatter build in
  let result = Format.flush_str_formatter () in
  let=? result_element = get_element_by_id "result" in

  El.set_children result_element [ El.txt' result ];

  (* Update the oposition table *)
  let=? div_table = get_element_by_id "tables_div" in
  let difficulties =
    let fm = fm_element + fm_bonus in
    let table = distance_table fm in
    Brr.El.tr
      [
        Brr.El.th [ Brr.El.txt' "Distance" ]
      ; Brr.El.th
          [
            Brr.El.txt' "% de toucher (FM"
          ; Brr.El.txt @@ Jstr.of_int @@ fm
          ; Brr.El.txt' ")"
          ]
      ; Brr.El.th
          [
            Brr.El.txt' "% de toucher (FM"
          ; Brr.El.txt @@ Jstr.of_int @@ (fm + 1)
          ; Brr.El.txt' ")"
          ]
      ; Brr.El.th
          [
            Brr.El.txt' "% de toucher (FM"
          ; Brr.El.txt @@ Jstr.of_int @@ (fm + 2)
          ; Brr.El.txt' ")"
          ]
      ; Brr.El.th
          [
            Brr.El.txt' "% de toucher (FM"
          ; Brr.El.txt @@ Jstr.of_int @@ (fm + 3)
          ; Brr.El.txt' ")"
          ]
      ]
    :: List.init ~len:7 ~f:(fun i ->
           Brr.El.tr
             (Brr.El.td [ Brr.El.txt (Jstr.of_int (i + 5)) ]
             :: List.init ~len:4 ~f:(fun j ->
                    let cell =
                      Jstr.of_float ~frac:2 table.(j).(i) |> Brr.El.txt
                    in
                    Brr.El.td [ cell ])))
  in

  let table_opposition =
    Brr.El.table
    @@ Brr.El.tr
         [
           Brr.El.th [ Brr.El.txt' "FM" ]
         ; Brr.El.th
             [
               Brr.El.txt' "% de toucher l’adversaire"
             ; Brr.El.txt' " (FM "
             ; Brr.El.txt @@ Jstr.of_int env.fm_oponent
             ; Brr.El.txt' ")"
             ]
         ]
       :: List.map env.frequencies ~f:(fun (v, value) ->
              Brr.El.tr
                [
                  Brr.El.td [ Brr.El.txt (Jstr.of_int v) ]
                ; Brr.El.td
                    [ Brr.El.txt (Jstr.of_float ~frac:3 (value *. 100.)) ]
                ])
  and table_distance = Brr.El.table difficulties in

  El.set_children div_table [ table_opposition; table_distance ];

  ()

let main () =
  let=? btn = get_element_by_id "form" in
  let _ =
    Ev.listen Brr_io.Form.Ev.submit
      (fun ev ->
        Ev.prevent_default ev;
        eval ev)
      (El.as_target btn)
  in

  eval ()

let () =
  let open Jv in
  let main = obj [| ("run", repr main) |] in
  set global "lib" main