commit 65a85805223ac60f731f429744137085c40e014b Author: Alexandre Date: Sat Oct 26 16:49:47 2024 +0200 initial commit diff --git a/a.out b/a.out new file mode 100755 index 0000000..5f5b022 Binary files /dev/null and b/a.out differ diff --git a/compil.sh b/compil.sh new file mode 100644 index 0000000..a5fbb7d --- /dev/null +++ b/compil.sh @@ -0,0 +1 @@ +ocamlc main.ml -o main \ No newline at end of file diff --git a/exec.sh b/exec.sh new file mode 100644 index 0000000..3c01fca --- /dev/null +++ b/exec.sh @@ -0,0 +1,2 @@ +ocamlc main.ml -o main +./main main_test ml \ No newline at end of file diff --git a/main b/main new file mode 100755 index 0000000..6742f08 Binary files /dev/null and b/main differ diff --git a/main.cmi b/main.cmi new file mode 100644 index 0000000..b616bc8 Binary files /dev/null and b/main.cmi differ diff --git a/main.cmo b/main.cmo new file mode 100644 index 0000000..79eb727 Binary files /dev/null and b/main.cmo differ diff --git a/main.ml b/main.ml new file mode 100644 index 0000000..9e191bf --- /dev/null +++ b/main.ml @@ -0,0 +1,164 @@ +let __prefixes__ = [|"let"; "rec"; "and"|] ;; +let __keywords__ = [|"let"; "while"; "do"; "done"; "for"; "to"; "begin"; "end"; "try"; "with"; "raise"; "in"|] + +let concat_str (str : string ref) nstr = + let n = String.length nstr in + let i = ref 0 in + while !i < n && nstr.[!i] = ' ' do + incr i + done; + if !i <> n then begin + let cct = String.init (n - !i) (fun k -> nstr.[k + !i]) in + str := (!str)^cct^"\n" + end;; + +let parse_the_whole_thing filename = + let ptr = open_in filename in + let res = ref "" in + try + while true do + let line = input_line ptr in + concat_str res line + (*res := (!res)^line^"\n"*) + done; + "0 factorielle" + with + | End_of_file -> + close_in ptr; + !res ;; + +let is_an_integer ch = + Char.code ch >= 48 && Char.code ch <= 57 ;; + +let fbd = [|' '; '\n'; '('; ')'; '['; ']'; '{'; '}'; ';'; ','; '.'; ':'; '*'; '|'; '-'; '+'; '='; '<'; '>'; '!'|] ;; +let to_list str = + let n = String.length str in + let rec aux acc i = match i with + | k when k >= n -> acc + | k -> + let k1 = ref k + and k2 = ref k in + while !k2 < String.length str && (Array.mem str.[!k2] fbd || is_an_integer str.[!k2]) do + incr k2; + incr k1 + done; + while !k2 < String.length str && not (Array.mem str.[!k2] fbd) do + incr k2 + done; + aux (((0, String.init (!k2 - !k1) (fun i -> str.[!k1 + i])), (!k1, !k2))::acc) (!k2+1) + in + List.rev (aux [] 0) ;; + +let print_to_list (res : ((int * string) * (int * int)) list) = + let rec aux = function + | [] -> () + | ((b, str), (i, j))::t -> + Printf.printf "[%d] %s --> (%d <-> %d)\n" b str i j ; + aux t + in + aux res ;; + +let random_string nmin nmax = + String.init (Random.int (nmax - nmin) + nmin) (fun i -> Char.chr (97 + Random.int 25)) ;; + +let detect_names (res : ((int * string) * (int * int)) list) = + let rec aux isname = function + | [] -> [] + | ((status, str), (i, j))::t when isname -> + if Array.mem str __prefixes__ then + ((status, str), (i, j))::(aux true t) + else + ((1, str), (i, j))::(aux false t) + | ((status, str), (i, j))::t -> + ((status, str), (i, j))::(aux (Array.mem str __prefixes__) t) + in + aux false res ;; + +let str_equal s1 s2 = + if (String.length s1) <> (String.length s2) then + false + else + Array.fold_left (fun acc v -> acc && fst v = snd v) true (Array.init (String.length s1) (fun i -> (s1.[i], s2.[i]))) ;; + +let generate_conversion_hash (res : ((int * string) * (int * int)) list) = + let hash = Hashtbl.create (List.length res +2) in + let rec aux = function + | [] -> () + |((isname, str), (i, j))::t -> + if Hashtbl.find_opt hash str = None then begin + if isname = 1 then + Hashtbl.add hash str (random_string 10 11) + else + Hashtbl.add hash str str ; + end; + (*if Hashtbl.find_opt hash str = None then begin + if not (Array.mem str __prefixes__) then + Hashtbl.add hash str (random_string 10 11) + else + Hashtbl.add hash str str ; + end;*) + aux t + in + aux res ; + hash ;; + +let list_to_array (l : 'a list) = + let hd = List.hd l in + let n = List.length l in + let res = Array.make n hd in + let rec aux i = function + | [] -> () + | h::t -> + res.(i) <- h ; + aux (i+1) t + in + aux 0 l; + res ;; + +let write_out (filename : string) str (ext : string) (words : ((int * string) * (int * int)) list) (hash : (string, string) Hashtbl.t) = + let ptr = open_out ("tests/"^filename^"_improved."^ext) in + + let n = String.length str in + let i = ref 0 in + + let cwords = list_to_array words in + let cindex = ref 0 in + try + while true do + while !i < fst (snd cwords.(!cindex)) do (* write normally *) + Printf.fprintf ptr "%c" str.[!i] ; + incr i; + done; + Printf.fprintf ptr "%s" (Hashtbl.find hash (snd (fst cwords.(!cindex)))) ; + i := (snd (snd cwords.(!cindex))) ; + incr cindex ; + done; + close_out ptr ; + with + | Invalid_argument _ -> + while !i < n do + Printf.fprintf ptr "%c" str.[!i] ; + incr i; + done; + close_out ptr ;; + +let convert filename ext = + let whole = parse_the_whole_thing (filename^"."^ext) in + (*Printf.printf "%s" whole ;*) + let words = to_list whole in + (*print_to_list words ;*) + let fnames = detect_names words in + (*print_to_list fnames ;*) + let conversion_hash = generate_conversion_hash fnames in + Hashtbl.iter (fun k v -> Printf.printf "%s ----> %s\n" k v) conversion_hash ; + write_out filename whole ext fnames conversion_hash ;; + + +let main () = + if Array.length Sys.argv <> 3 then begin + Printf.fprintf stderr "Usage : ./a.out \nNote : filename should not include the <.extension> (e.g. enter 'main' and not 'main.c' or 'main.ml')\n" ; + assert false ; + end else + convert Sys.argv.(1) Sys.argv.(2) ;; + +main () ;; \ No newline at end of file diff --git a/main_test.ml b/main_test.ml new file mode 100644 index 0000000..4b17b4c --- /dev/null +++ b/main_test.ml @@ -0,0 +1,988 @@ +open Graphics ;; + +Random.self_init () ;; + +(* use Ctrl+F with 'WALUIGI_TIME' to look for sections *) + +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Types + Constants *) + +exception ReturnBool of bool ;; +exception ReturnInt of int ;; +exception ReturnIntArr of int array * int ;; + +let __width__ = 1200 +and __height__ = 800 ;; + +let __istr__ = " 1200x800" ;; + +let univ_dt = 0.003 ;; + +type pt_2d = { + mutable x : float ; + mutable y : float ; +} ;; + +type polygon = { + vertexes : pt_2d array ; + rgb : int ; + xmin : float ; + xmax : float ; + ymin : float ; + ymax : float ; + mutable restitution : float ; + score : int ; +} ;; + +type sphere = { + center : pt_2d ; + radius : float ; + rgb : int ; + xmin : float ; + xmax : float ; + ymin : float ; + ymax : float ; + mutable restitution : float ; + score : int ; +} ;; + +type flipper_side = Left | Right ;; +type flipper = { + side : flipper_side ; + xy : pt_2d ; + radius : float ; + length : float ; + mutable theta : float (* in degrees *) ; + mutable dtheta : float ; + agmin : float ; + agmax : float ; + vtxs : polygon +} ;; + +type ball = { + mutable active : bool ; + radius : float ; + mass : float ; + rgb : int ; + xy : pt_2d ; + v : pt_2d ; + a : pt_2d ; + fres : pt_2d ; +} ;; + +(* --- *) + +let default_polygon = { + vertexes = [||] ; + rgb = 0 ; + xmin = 1. ; + xmax = -. 1. ; + ymin = 1. ; + ymax = -. 1. ; + restitution = 0. ; + score = 0 ; +} ;; + +let default_sphere = { + center = {x = 0. ; y = 0.} ; + rgb = 0 ; + radius = -. 1. ; + xmin = 1. ; + xmax = -. 1. ; + ymin = 1. ; + ymax = -. 1. ; + restitution = 0. ; + score = 0 ; +} ;; + +let default_flipper = { + side = Left ; + xy = {x = 0. ; y = 0.} ; + radius = 0. ; + length = 0. ; + theta = 0. (* in degrees *) ; + dtheta = 0. ; + agmin = 0. ; + agmax = 0. ; + vtxs = default_polygon ; +} ;; + +let univ_g = 750.0 ;; +let pi = 3.14159265358979343 ;; +let epsilon = (1. /. 131072.) ;; + +let winBL = { + x = 0. ; + y = 0. ; +} ;; + +let winTR = { + x = 1200. ; + y = 800. ; +} + +let winball = { + x = 750. ; + y = 500. ; +} + +let gforce = {x = 0. ; y = -. univ_g} ;; + +let remaining = ref 8 ;; +let score = ref 0 ;; + +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Threads *) + +let n_threads = 8 ;; + +let beep_boop = Array.make n_threads false ;; +let beep_id = ref 0 ;; + +let playbeep id = + while false do + if beep_boop.(id) then begin + ignore (Unix.system "./sound wah/scored_hit.wav") ; + beep_boop.(id) <- false ; + end; + Unix.sleepf univ_dt ; + done;; + +let beep_list = Array.init n_threads (fun k -> Thread.create playbeep k) ;; + +(**) + +let play_music () = + while false do + ignore (Unix.system "./sound wah/wah_metal.wav") ; + ignore (Unix.system "./sound wah/wah_eurobeat.wav") ; + ignore (Unix.system "./sound wah/wah_hardcore.wav") ; + done;; + +let theme_thr = Thread.create play_music () ;; + +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Arithmetical operations *) + +let rec pw x n = match n with + | 0 -> 1 + | 1 -> x + | k when k mod 2 = 0 -> pw (x*x) (n/2) + | k -> x * (pw (x*x) (n/2)) ;; + +let rec pwf x n = match n with + | 0 -> 1. + | 1 -> x + | k when k mod 2 = 0 -> pwf (x *. x) (n/2) + | k -> x *. (pwf (x *. x) (n/2)) ;; + +let rec ln10 n = match n with + | k when k < 0 -> failwith "Are you sure about that ?" + | k when k < 10 -> 0 + | k -> 1 + ln10 (k/10) ;; + +let convexf x y theta = + (1.0 -. theta) *. x +. theta *. y ;; + +let absf = function + | x when x < 0.0 -> -. x + | x -> x ;; + +let rec expand_fl = function + | k when float_of_int (int_of_float k) = k -> int_of_float k + | k -> expand_fl (10.0 *. k) ;; + +let incree = function + | k when k < 10 -> 0 + | _ -> 1 ;; + +let round x n = + float_of_int (int_of_float (x *. pwf 10. n)) /. (pwf 10. n);; + +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Dynamic Arrays *) + +type 'a dynamic = { + mutable len : int ; + mutable memlen : int ; + mutable tab : 'a array +} ;; + +let dyn_create (elt : 'a) = + { + len = 0 ; + memlen = 16 ; + tab = Array.make 16 elt + } ;; + +let dyn_add (dyn : 'a dynamic) (elt : 'a) = + if dyn.len = dyn.memlen then begin + let _new = Array.make (2 * dyn.memlen) dyn.tab.(0) in + for i = 0 to dyn.memlen -1 do + _new.(i) <- dyn.tab.(i) + done; + dyn.tab <- _new ; + dyn.memlen <- dyn.memlen * 2 ; + end; + dyn.tab.(dyn.len) <- elt ; + dyn.len <- dyn.len +1 ;; + +let dyn_remove (dyn : 'a dynamic) (elt : 'a) = + try + for i = 0 to dyn.len -1 do + if dyn.tab.(i) = elt then + raise (ReturnInt i) + done; + raise (ReturnInt (-1)) + with + | ReturnInt (-1) -> () + | ReturnInt k -> + for i = k to dyn.len -2 do + dyn.tab.(i) <- dyn.tab.(i+1) + done; + dyn.len <- dyn.len -1 ; + if (dyn.memlen >= 32) && (dyn.len * 4 <= dyn.memlen) then begin + let _new = Array.make (dyn.memlen/2) dyn.tab.(0) in + for i = 0 to dyn.len -1 do + _new.(i) <- dyn.tab.(i) + done; + dyn.tab <- _new ; + dyn.memlen <- dyn.memlen/2 ; + end ;; + +let dyn_fold_left (f : 'b -> 'a -> 'b) (acc0 : 'b) (dyn : 'a dynamic) = + let acc = ref acc0 in + for i = 0 to dyn.len -1 do + acc := f !acc dyn.tab.(i) + done; + !acc ;; + +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Arithmetical operations *) + +let vect_convexf (px : pt_2d) (py : pt_2d) theta = + { + x = convexf px.x py.x theta ; + y = convexf px.y py.y theta ; + } ;; + + +let vect_sum_2D (p1 : pt_2d) (p2 : pt_2d) = + { + x = p1.x +. p2.x ; + y = p1.y +. p2.y ; + } ;; + +let vect_diff_2D (p1 : pt_2d) (p2 : pt_2d) = + { + x = p1.x -. p2.x ; + y = p1.y -. p2.y ; + } ;; + +let vect_mult_2D (p1 : pt_2d) (lambda : float) = + { + x = p1.x *. lambda ; + y = p1.y *. lambda ; + } ;; + +let vect_midpoint_2D (p1 : pt_2d) (p2 : pt_2d) = + { + x = (p1.x +. p2.x) /. 2.0 ; + y = (p1.y +. p2.y) /. 2.0 ; + } ;; + +let vect_normal_2D (p1 : pt_2d) (p2 : pt_2d) = + { + x = -. (p2.y -. p1.y) ; + y = (p2.x -. p1.x) ; + } ;; + +let return_proj_of_point (m : pt_2d) (spt : pt_2d) (ept : pt_2d) = + match (-. ((ept.x -. spt.x) *. (spt.x -. m.x) +. (ept.y -. spt.y) *. (spt.y -. m.y)) /. ((ept.x -. spt.x) *. (ept.x -. spt.x) +. (ept.y -. spt.y) *. (ept.y -. spt.y))) with + | k when k >= 0. && k <= 1. -> (vect_convexf spt ept k) + | k when k < 0. -> spt + | k -> ept ;; + +let return_proj_of_point_D (m : pt_2d) (spt : pt_2d) (ept : pt_2d) = + let theta = (-. ((ept.x -. spt.x) *. (spt.x -. m.x) +. (ept.y -. spt.y) *. (spt.y -. m.y)) /. ((ept.x -. spt.x) *. (ept.x -. spt.x) +. (ept.y -. spt.y) *. (ept.y -. spt.y))) in + (vect_convexf spt ept theta) ;; + +let vect_dot_product_2D (p1 : pt_2d) (p2 : pt_2d) = + p1.x *. p2.x +. p1.y *. p2.y ;; + +let vect_norm_2D (p1 : pt_2d) = + Float.sqrt (vect_dot_product_2D p1 p1) ;; + +let vect_dist_2D (p1 : pt_2d) (p2 : pt_2d) = + vect_norm_2D (vect_diff_2D p1 p2) ;; + +let vect_scale_2D (v1 : pt_2d) (v2 : pt_2d) = + vect_mult_2D v1 ((vect_norm_2D v2) /. (vect_norm_2D v1)) ;; + +let vect_normalize_2D (v1 : pt_2d) = + vect_mult_2D v1 (1.0 /. (vect_norm_2D v1)) ;; + +let vect_symmetry (m : pt_2d) (p1 : pt_2d) (p2 : pt_2d) = + let proj = return_proj_of_point_D m p1 p2 in + let ortho = vect_diff_2D proj m in + vect_sum_2D (vect_sum_2D ortho ortho) m ;; + +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Physics functions *) + +let step_one_ball (b : ball) (dt : float) = + { + x = b.xy.x +. b.v.x *. dt ; + y = b.xy.y +. b.v.y *. dt ; + } ;; + +let is_in_bounding_box_p (b : ball) (poly : polygon) = + (b.xy.x +. b.radius >= poly.xmin) && (b.xy.x -. b.radius <= poly.xmax) && + (b.xy.y +. b.radius >= poly.ymin) && (b.xy.y -. b.radius <= poly.ymax) ;; + +let is_in_bounding_box_s (b : ball) (s : sphere) = + (b.xy.x +. b.radius >= s.xmin) && (b.xy.x -. b.radius <= s.xmax) && + (b.xy.y +. b.radius >= s.ymin) && (b.xy.y -. b.radius <= s.ymax) ;; + +let distance_line_segment (m : pt_2d) (spt : pt_2d) (ept : pt_2d) = + match (-. ((ept.x -. spt.x) *. (spt.x -. m.x) +. (ept.y -. spt.y) *. (spt.y -. m.y)) /. ((ept.x -. spt.x) *. (ept.x -. spt.x) +. (ept.y -. spt.y) *. (ept.y -. spt.y))) with + | k when k >= 0. && k <= 1. -> vect_dist_2D (vect_convexf spt ept k) m + | k when k < 0. -> vect_dist_2D spt m + | k -> vect_dist_2D ept m ;; + +let distance_infinite_segment (m : pt_2d) (spt : pt_2d) (ept : pt_2d) = + let theta = (-. ((ept.x -. spt.x) *. (spt.x -. m.x) +. (ept.y -. spt.y) *. (spt.y -. m.y)) /. ((ept.x -. spt.x) *. (ept.x -. spt.x) +. (ept.y -. spt.y) *. (ept.y -. spt.y))) in + vect_dist_2D (vect_convexf spt ept theta) m ;; + +let is_collision_p (b : ball) (poly : polygon) (dt : float) = + if not (is_in_bounding_box_p b poly) then + ([||], 0) + else begin + try + let mind = ref b.radius + and minidx = Array.make 3 (-1) + and minarrid = ref 0 in + for i = 0 to Array.length poly.vertexes - 1 do + let dst = (distance_line_segment (step_one_ball b dt) poly.vertexes.(i) poly.vertexes.((i+1) mod Array.length poly.vertexes)) in + if dst <= !mind -. epsilon then begin + mind := dst ; + minidx.(0) <- i ; + minidx.(1) <- (-1) ; + minidx.(2) <- (-1) ; + minarrid := 1; + end + else if dst <= !mind then begin + minidx.(!minarrid) <- i ; + incr minarrid ; + end + done; + raise (ReturnIntArr (minidx, !minarrid)) + with + | ReturnIntArr (a, b) -> (a, b) + | Invalid_argument _ -> failwith "ok then" + end ;; + +let playbeep () = + beep_boop.(!beep_id) <- true ; + beep_id := (!beep_id+1) mod n_threads ;; + +let is_collision_s (b : ball) (s : sphere) (dt : float) = + if not (is_in_bounding_box_s b s) then + false + else + vect_dist_2D (step_one_ball b dt) (s.center) <= (s.radius +. b.radius) ;; + +let update_ball_data (b : ball) (polys : polygon array) (spheres : sphere array) (flips : flipper dynamic) (dt : float) = + b.fres.x <- 0. ; + b.fres.y <- 0. ; + + for p = 0 to (Array.length polys -1) do + let (hitarr, hitlen) = (is_collision_p b polys.(p) dt) in + if hitlen > 0 then begin + for h = 0 to hitlen -1 do + let hit = hitarr.(h) in + score := !score + polys.(p).score ; + + if h = 0 && polys.(p).score > 0 then + playbeep () ; + if polys.(p).restitution = 0. then begin + b.active <- false ; + decr remaining ; + end; + + (* apply normal reaction force *) + let hit2 = (hit +1) mod (Array.length polys.(p).vertexes) in + let proj = return_proj_of_point b.xy polys.(p).vertexes.(hit) polys.(p).vertexes.(hit2) in + let proj_n = vect_normalize_2D (vect_diff_2D b.xy proj) in + let scal = (vect_dot_product_2D (vect_normalize_2D gforce) proj_n) in + if scal > 0. then begin + let reaction_force_2 = vect_mult_2D proj_n (univ_g *. b.mass *. scal) in + b.fres.x <- b.fres.x +. reaction_force_2.x *. polys.(p).restitution /. float_of_int hitlen ; + b.fres.y <- b.fres.y +. reaction_force_2.y *. polys.(p).restitution /. float_of_int hitlen ; + end; + + (* change velocity according to angle *) + if hitlen = 1 then begin + let director = vect_diff_2D polys.(p).vertexes.(hit2) polys.(p).vertexes.(hit) in + let symmetric = vect_symmetry b.v {x = 0. ; y = 0.} director in + + b.v.x <- symmetric.x ; + b.v.y <- symmetric.y ; + end + else begin + let newv = vect_mult_2D (vect_normalize_2D (vect_diff_2D b.xy proj)) (vect_norm_2D b.v) in + + b.v.x <- newv.x ; + b.v.y <- newv.y ; + end + done + end + done ; + + for s = 0 to (Array.length spheres -1) do + if is_collision_s b spheres.(s) dt then begin + score := !score + spheres.(s).score ; + + if spheres.(s).score > 0 then + playbeep () ; + if spheres.(s).restitution = 0. then begin + b.active <- false ; + decr remaining ; + end; + + (* apply normal reaction force *) + let proj_n = vect_normalize_2D (vect_diff_2D b.xy spheres.(s).center) in + let scal = (vect_dot_product_2D (vect_normalize_2D gforce) proj_n) in + if scal > 0. then begin + let reaction_force_2 = vect_mult_2D proj_n (univ_g *. b.mass *. scal) in + b.fres.x <- b.fres.x +. reaction_force_2.x *. spheres.(s).restitution *. 1.1 ; + b.fres.y <- b.fres.y +. reaction_force_2.y *. spheres.(s).restitution *. 1.1 ; + end; + + (* change velocity according to angle *) + let theta = b.radius /. (vect_norm_2D (vect_diff_2D b.xy spheres.(s).center)) in + let intersection = (vect_convexf b.xy spheres.(s).center theta) in + let director = vect_normal_2D intersection (vect_sum_2D intersection proj_n) in + let symmetric = vect_symmetry b.v {x = 0. ; y = 0.} director in + + b.v.x <- symmetric.x ; + b.v.y <- symmetric.y ; + end + done ; + + for f = 0 to flips.len -1 do + let (hitarr, hitlen) = (is_collision_p b flips.tab.(f).vtxs dt) in + if hitlen > 0 then begin + for h = 0 to hitlen -1 do + let hit = hitarr.(h) in + + (* apply normal reaction force *) + let hit2 = (hit +1) mod (Array.length flips.tab.(f).vtxs.vertexes) in + let proj = return_proj_of_point b.xy flips.tab.(f).vtxs.vertexes.(hit) flips.tab.(f).vtxs.vertexes.(hit2) in + let proj_n = vect_normalize_2D (vect_diff_2D b.xy proj) in + let scal = (vect_dot_product_2D (vect_normalize_2D gforce) proj_n) in + if scal > 0. then begin + let reaction_force_2 = vect_mult_2D proj_n (univ_g *. b.mass *. scal) in + b.fres.x <- b.fres.x +. reaction_force_2.x *. flips.tab.(f).vtxs.restitution /. float_of_int hitlen ; + b.fres.y <- b.fres.y +. reaction_force_2.y *. flips.tab.(f).vtxs.restitution /. float_of_int hitlen ; + end; + + (* change velocity according to angle *) + if hitlen = 1 then begin + let director = vect_diff_2D flips.tab.(f).vtxs.vertexes.(hit2) flips.tab.(f).vtxs.vertexes.(hit) in + let symmetric = vect_symmetry b.v {x = 0. ; y = 0.} director in + + b.v.x <- symmetric.x ; + b.v.y <- symmetric.y ; + end + else begin + let newv = vect_mult_2D (vect_normalize_2D (vect_diff_2D b.xy proj)) (vect_norm_2D b.v) in + + b.v.x <- newv.x ; + b.v.y <- newv.y ; + end; + + (* add relative velocity [disabled for physical reasons] *) + if false && ((flips.tab.(f).side = Left && flips.tab.(f).dtheta > 0.) || (flips.tab.(f).side = Right && flips.tab.(f).dtheta < 0.)) then begin + b.v.x <- 0.5 *. b.v.x +. flips.tab.(f).dtheta *. 3.14159 /. 180. *. (vect_dist_2D flips.tab.(f).xy b.xy) *. (cos (flips.tab.(f).theta *. 3.14159 /. 180.)); + b.v.y <- 0.5 *. b.v.y +. flips.tab.(f).dtheta *. 3.14159 /. 180. *. (vect_dist_2D flips.tab.(f).xy b.xy) *. (sin (flips.tab.(f).theta *. 3.14159 /. 180.)); + end + done + end + done; + + (* P = mg *) + b.fres.y <- b.fres.y -. univ_g *. b.mass ; + + (* PFD : ma = sum(F) *) + b.a.x <- b.fres.x /. b.mass ; + b.a.y <- b.fres.y /. b.mass ; + + b.v.x <- b.v.x +. b.a.x *. dt ; + b.v.y <- b.v.y +. b.a.y *. dt ; + + b.xy.x <- b.xy.x +. b.v.x *. dt ; + b.xy.y <- b.xy.y +. b.v.y *. dt ;; + +let update_balls (bl : ball array) (polys : polygon array) (spheres : sphere array) (flips : flipper dynamic) (dt : float) = + for b = 0 to Array.length bl -1 do + if bl.(b).active then + update_ball_data bl.(b) polys spheres flips dt + done ;; + +let update_flippers (flips : flipper dynamic) (dt : float) = + for fl = 0 to flips.len -1 do + if flips.tab.(fl).dtheta <> 0. then begin + let x0 = flips.tab.(fl).xy.x + and y0 = flips.tab.(fl).xy.y + and rd = flips.tab.(fl).radius + and len = flips.tab.(fl).length + and theta0 = flips.tab.(fl).theta in + match flips.tab.(fl).side with + | Left -> + let theta_dt = flips.tab.(fl).theta +. flips.tab.(fl).dtheta *. dt in + if theta_dt > flips.tab.(fl).agmax then + flips.tab.(fl).dtheta <- -.(flips.tab.(fl).dtheta) ; + + if theta_dt < flips.tab.(fl).agmin then + flips.tab.(fl).dtheta <- 0. ; + + flips.tab.(fl).theta <- theta_dt ; + + flips.tab.(fl).vtxs.vertexes.(0) <- { + x = x0 +. len *. (cos (theta0 *. 3.14159 /. 180.)); + y = y0 +. len *. (sin (theta0 *. 3.14159 /. 180.)) + }; + flips.tab.(fl).vtxs.vertexes.(1) <- { + x = x0 +. rd *. (cos ((theta0 +. 90.) *. 3.14159 /. 180.)); + y = y0 +. rd *. (sin ((theta0 +. 90.) *. 3.14159 /. 180.)) + }; + flips.tab.(fl).vtxs.vertexes.(2) <- { + x = x0 +. rd *. (cos ((theta0 -. 90.) *. 3.14159 /. 180.)); + y = y0 +. rd *. (sin ((theta0 -. 90.) *. 3.14159 /. 180.)) + }; + + | Right -> + let theta_dt = flips.tab.(fl).theta +. flips.tab.(fl).dtheta *. dt in + if theta_dt > flips.tab.(fl).agmax then + flips.tab.(fl).dtheta <- 0. ; + + if theta_dt < flips.tab.(fl).agmin then + flips.tab.(fl).dtheta <- -.(flips.tab.(fl).dtheta) ; + + flips.tab.(fl).theta <- theta_dt ; + + flips.tab.(fl).vtxs.vertexes.(0) <- { + x = x0 +. len *. (cos (theta0 *. 3.14159 /. 180.)); + y = y0 +. len *. (sin (theta0 *. 3.14159 /. 180.)) + }; + flips.tab.(fl).vtxs.vertexes.(1) <- { + x = x0 +. rd *. (cos ((theta0 +. 90.) *. 3.14159 /. 180.)); + y = y0 +. rd *. (sin ((theta0 +. 90.) *. 3.14159 /. 180.)) + }; + flips.tab.(fl).vtxs.vertexes.(2) <- { + x = x0 +. rd *. (cos ((theta0 -. 90.) *. 3.14159 /. 180.)); + y = y0 +. rd *. (sin ((theta0 -. 90.) *. 3.14159 /. 180.)) + }; + end + done ;; + +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Graphics fcts *) + +let draw_integer x0 y n0 r = + (* 7-seg display *) + let n = ref n0 in + let size = ln10 n0 in + let len = r/3 in + let offset = size*(len*11/7)/2 in + for i = 0 to size do + let x = x0 + offset - i*(len*11/7) in + if Array.mem (!n mod 10) [|0; 4; 5; 6; 7; 8; 9|] then + draw_poly_line [|(x-len/2, y+len); (x-len/2, y)|]; + + if Array.mem (!n mod 10) [|0; 2; 3; 5; 6; 7; 8; 9|] then + draw_poly_line [|(x-len/2, y+len); (x+len/2, y+len)|]; + + if Array.mem (!n mod 10) [|0; 1; 2; 3; 4; 7; 8; 9|] then + draw_poly_line [|(x+len/2, y+len); (x+len/2, y)|]; + + if Array.mem (!n mod 10) [|2; 3; 4; 5; 6; 8; 9|] then + draw_poly_line [|(x-len/2, y); (x+len/2, y)|]; + + if Array.mem (!n mod 10) [|0; 1; 3; 4; 5; 6; 7; 8; 9|] then + draw_poly_line [|(x+len/2, y-len); (x+len/2, y)|]; + + if Array.mem (!n mod 10) [|0; 2; 3; 5; 6; 8; 9|] then + draw_poly_line [|(x-len/2, y-len); (x+len/2, y-len)|]; + + if Array.mem (!n mod 10) [|0; 2; 6; 8|] then + draw_poly_line [|(x-len/2, y-len); (x-len/2, y)|]; + + n := !n/10; + done ;; + +let draw_integer_alignedleft x0 y n0 len = + (* 7-seg display 2 *) + set_line_width (max 1 (len/4)); + let n = ref n0 in + let size = ln10 (abs n0) in + + let cur_x = ref (x0 + size*(len*11/7)) in + + if !n < 0 then begin + n := !n * (-1); + draw_poly_line [|(x0, y); (x0+len, y)|]; + cur_x := !cur_x + (len*11/7) + end; + + for i = 0 to size do + let x = !cur_x in + if Array.mem (!n mod 10) [|0; 4; 5; 6; 7; 8; 9|] then + draw_poly_line [|(x, y+len); (x, y)|]; + + if Array.mem (!n mod 10) [|0; 2; 3; 5; 6; 7; 8; 9|] then + draw_poly_line [|(x, y+len); (x+len, y+len)|]; + + if Array.mem (!n mod 10) [|0; 1; 2; 3; 4; 7; 8; 9|] then + draw_poly_line [|(x+len, y+len); (x+len, y)|]; + + if Array.mem (!n mod 10) [|2; 3; 4; 5; 6; 8; 9|] then + draw_poly_line [|(x, y); (x+len, y)|]; + + if Array.mem (!n mod 10) [|0; 1; 3; 4; 5; 6; 7; 8; 9|] then + draw_poly_line [|(x+len, y-len); (x+len, y)|]; + + if Array.mem (!n mod 10) [|0; 2; 3; 5; 6; 8; 9|] then + draw_poly_line [|(x, y-len); (x+len, y-len)|]; + + if Array.mem (!n mod 10) [|0; 2; 6; 8|] then + draw_poly_line [|(x, y-len); (x, y)|]; + + n := !n/10; + cur_x := !cur_x - (len*11/7); +done ;; + +let draw_float x y n0 r = + let n = absf n0 in + let ent = int_of_float n in + let frac = expand_fl (n -. float_of_int ent) in + draw_integer_alignedleft x y ent r ; + fill_circle (x + (ln10 ent) * r * 11/7 + 3*r/2) (y - r) 3 ; + draw_integer_alignedleft (x + 3*r/5 + (ln10 ent + 1)*r*11/7) y ((100 * frac) / (pw 10 (1+ ln10 frac))) r ;; + +let draw_polygon (poly : polygon) = + set_color (rgb (poly.rgb mod 256) ((poly.rgb / 256) mod 256) ((poly.rgb / (256*256)) mod 256)) ; + fill_poly (Array.init (Array.length poly.vertexes) (fun i -> (int_of_float poly.vertexes.(i).x, int_of_float poly.vertexes.(i).y))) ;; + +let draw_sphere (s : sphere) = + set_color (rgb (s.rgb mod 256) ((s.rgb / 256) mod 256) ((s.rgb / (256*256)) mod 256)) ; + fill_circle (int_of_float s.center.x) (int_of_float s.center.y) (int_of_float s.radius) ;; + +let draw_flipper (f : flipper) = + set_color (rgb 64 64 64) ; + fill_circle (int_of_float f.xy.x) (int_of_float f.xy.y) (int_of_float f.radius) ; + draw_polygon f.vtxs ;; + +let draw_ball (b : ball) = + set_color (rgb (b.rgb mod 256) ((b.rgb / 256) mod 256) ((b.rgb / (256*256)) mod 256)) ; + fill_circle (int_of_float b.xy.x) (int_of_float b.xy.y) (int_of_float b.radius) ; + set_line_width 4 ; + draw_circle (int_of_float b.xy.x) (int_of_float b.xy.y) (int_of_float b.radius) ;; + +let draw_all_balls (bs : ball array) = + for k = 0 to Array.length bs -1 do + if bs.(k).active then + draw_ball bs.(k) + done ;; + +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Misc fcts *) + +let get1char_plus () = + if key_pressed () then + read_key () + else + '@' ;; + +let control_flippers (flips : flipper dynamic) = + match get1char_plus () with + | 'q' -> + for fl = 0 to flips.len -1 do + if flips.tab.(fl).side = Left && flips.tab.(fl).dtheta = 0. then + flips.tab.(fl).dtheta <- 600. ; + done + | 'd' -> + for fl = 0 to flips.len -1 do + if flips.tab.(fl).side = Right && flips.tab.(fl).dtheta = 0. then + flips.tab.(fl).dtheta <- -. 600. ; + done + | _ -> () ;; + +let create_ball (r : float) (x0 : int) (y0 : int) (m : float) (red : int) (green : int) (blue : int) = + { + active = true ; + radius = r ; + rgb = red + 256 * green + 256 * 256 * blue ; + mass = m; + xy = {x = float_of_int x0 +. (Random.float 30.0 -. 15.0); y = float_of_int y0 +. (Random.float 30.0 -. 15.0)} ; + v = {x = 0. ; y = 0.} ; + a = {x = 0. ; y = 0.} ; + fres = {x = 0. ; y = 0.} ; + } ;; + +let create_polygon (arr : (int * int) array) (rest : float) (pts : int) (red : int) (green : int) (blue : int) = + { + vertexes = Array.init (Array.length arr) (fun k -> {x = float_of_int (fst arr.(k)); y = float_of_int (snd arr.(k))}) ; + rgb = red + 256 * green + 256 * 256 * blue ; + xmin = float_of_int (Array.fold_left (fun acc k -> min acc (fst k)) 99999 arr) ; + xmax = float_of_int (Array.fold_left (fun acc k -> max acc (fst k)) (-99999) arr) ; + ymin = float_of_int (Array.fold_left (fun acc k -> min acc (snd k)) 99999 arr) ; + ymax = float_of_int (Array.fold_left (fun acc k -> max acc (snd k)) (-99999) arr) ; + restitution = rest ; + score = pts ; + } ;; + +let create_sphere (x00 : int) (y00 : int) (rd : float) (rest : float) (pts : int) (red : int) (green : int) (blue : int) = + let x0 = float_of_int x00 and y0 = float_of_int y00 in + { + center = {x = x0 ; y = y0}; + rgb = red + 256 * green + 256 * 256 * blue ; + radius = rd ; + xmin = x0 -. rd ; + xmax = x0 +. rd ; + ymin = y0 -. rd ; + ymax = y0 +. rd ; + restitution = rest ; + score = pts ; + } ;; + +let create_flipper (side : flipper_side) (x0 : int) (y0 : int) (rd : float) (len : float) (theta0 : float) (thmin : float) (thmax : float) = + { + side = side ; + xy = {x = float_of_int x0 ; y = float_of_int y0} ; + radius = rd ; + length = len ; + theta = theta0 (* in degrees *) ; + dtheta = 0. ; + agmin = thmin ; + agmax = thmax ; + vtxs = create_polygon [| + (x0 + int_of_float (len *. (cos (theta0 *. 3.14159 /. 180.))) , y0 + int_of_float (len *. (sin (theta0 *. 3.14159 /. 180.)))); + (x0 + int_of_float (rd *. (cos ((theta0 -. 90.) *. 3.14159 /. 180.))), y0 + int_of_float (rd *. (sin ((theta0 -. 90.) *. 3.14159 /. 180.)))); + (x0 + int_of_float (rd *. (cos ((theta0 +. 90.) *. 3.14159 /. 180.))), y0 + int_of_float (rd *. (sin ((theta0 +. 90.) *. 3.14159 /. 180.)))) + |] 1. 0 128 128 128 + } ;; + +let generate_pinballs (count : int) (r : float) (x0 : int) (y0 : int) (m : float) (red : int) (green : int) (blue : int) = + Array.init count (fun k -> create_ball r x0 y0 m red green blue) ;; + +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Edition functions *) + +let customize lvl_name = + open_graph __istr__ ; + set_window_title "WAH" ; + + let (res : polygon dynamic) = dyn_create default_polygon in + let stopped = ref false in + let refresh = ref true in + + let (cpoly : pt_2d dynamic) = dyn_create {x = 0. ; y = 0.} in + + while not !stopped do + Unix.sleepf univ_dt ; + + if !refresh then begin + auto_synchronize false ; + clear_graph () ; + refresh := false ; + for p = 0 to res.len -1 do + draw_polygon res.tab.(p) + done; + auto_synchronize true ; + end; + + match (get1char_plus ()) with + | 'a' -> (* add current polygon *) + (*Printf.printf "+polygon\n" ;*) + if cpoly.len >= 2 then begin + refresh := true ; + let newVTX = Array.init cpoly.len (fun k -> cpoly.tab.(k)) in + dyn_add res { + vertexes = newVTX ; + rgb = 128 + 255*128 + 255*255*128 ; + xmin = Array.fold_left (fun acc k -> min acc k.x) (999999.) newVTX ; + xmax = Array.fold_left (fun acc k -> max acc k.x) (-.999999.) newVTX ; + ymin = Array.fold_left (fun acc k -> min acc k.y) (999999.) newVTX ; + ymax = Array.fold_left (fun acc k -> max acc k.y) (-.999999.) newVTX ; + restitution = 1. ; + score = 0 ; + } ; + cpoly.len <- 0 ; + end + | 'v' -> (* add a vertex *) + (*Printf.printf "+vertex\n" ;*) + let (mx, my) = mouse_pos () in + dyn_add cpoly {x = float_of_int mx ; y = float_of_int my} ; + | 'c' -> (* clear current polygon *) + (*Printf.printf "cleared\n" ;*) + cpoly.len <- 0 ; + | 'h' -> + stopped := true ; + | _ -> () + done; + close_graph (); + res ;; + +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Main *) + +let simulate (data : polygon dynamic) (dats : sphere dynamic) (flips : flipper dynamic) = + open_graph __istr__ ; + set_window_title "WAH" ; + + let pinballs = generate_pinballs 8 10.0 600 800 0.15 255 255 0 in + let stime = Unix.gettimeofday () in + let ctime = ref (Unix.gettimeofday ()) in + + while true do + let __start = Unix.gettimeofday () in + auto_synchronize false ; + clear_graph () ; + + set_line_width 4 ; + draw_integer 600 100 !remaining 40 ; + + set_line_width 1 ; + for d = 0 to dats.len -1 do + draw_sphere dats.tab.(d) + done; + for d = 0 to data.len -1 do + draw_polygon data.tab.(d) + done; + for d = 0 to flips.len -1 do + draw_flipper flips.tab.(d) + done; + draw_all_balls pinballs ; + + set_color (rgb 128 128 32) ; + draw_float 25 770 (round (!ctime -. stime) 3) 25 ; + + set_color black ; + set_line_width 4 ; + draw_integer 600 770 !score 50 ; + + auto_synchronize true ; + + control_flippers flips ; + + Unix.sleepf univ_dt ; + + let __end = Unix.gettimeofday () in + ctime := !ctime +. (__end -. __start) ; + update_balls pinballs data.tab dats.tab flips (__end -. __start) ; + update_flippers flips (__end -. __start) ; + done; + + close_graph () ;; + +let polygons = dyn_create default_polygon ;; +let spheres = dyn_create default_sphere ;; +let flippers = dyn_create default_flipper ;; + +(* |-------------------------------------------------------------------------------------------------------| *) +(* kill platform *) +dyn_add polygons (create_polygon [|(700, -20); (500, -20); (500, 1); (700, 1)|] 0. 0 255 32 32) ;; + +(* outer walls *) +dyn_add polygons (create_polygon [|(0, 0); (500, 0); (500, 20); (0, 20)|] 1. 0 32 32 32) ;; +dyn_add polygons (create_polygon [|(700, 0); (1200, 0); (1200, 20); (700, 20)|] 1. 0 32 32 32) ;; +dyn_add polygons (create_polygon [|(0, 800); (500, 800); (500, 780); (0, 780)|] 1. 0 32 32 32) ;; +dyn_add polygons (create_polygon [|(700, 800); (1200, 800); (1200, 780); (700, 780)|] 1. 0 32 32 32) ;; +dyn_add polygons (create_polygon [|(1180, 0); (1200, 0); (1200, 800); (1180, 800)|] 1. 0 32 32 32) ;; +dyn_add polygons (create_polygon [|(0, 0); (20, 0); (20, 800); (0, 800)|] 1. 0 32 32 32) ;; + +(* side ramps *) +dyn_add polygons (create_polygon [|(20, 20); (20, 300); (420, 150); (420, 20)|] 1. 0 32 32 32) ;; +dyn_add polygons (create_polygon [|(1200, 20); (1200, 300); (780, 150); (780, 20)|] 1. 0 32 32 32) ;; + +(* starting platform *) +dyn_add polygons (create_polygon [|(600, 700); (400, 550); (800, 550)|] 1. 0 32 32 32) ;; + +(* |-------------------------------------------------------------------------------------------------------| *) +(* corner scoring spots *) +dyn_add spheres (create_sphere 20 780 30. 1. 50 128 128 32) ;; +dyn_add spheres (create_sphere 1180 780 30. 1. 50 128 128 32) ;; + +(* under the starting platform *) +dyn_add spheres (create_sphere 440 550 20. 1. 5 32 128 32) ;; +dyn_add spheres (create_sphere 520 550 20. 1. 5 32 192 32) ;; +dyn_add spheres (create_sphere 600 550 20. 1. 5 32 255 32) ;; +dyn_add spheres (create_sphere 680 550 20. 1. 5 32 192 32) ;; +dyn_add spheres (create_sphere 760 550 20. 1. 5 32 128 32) ;; + +dyn_add spheres (create_sphere 480 450 20. 1. 3 32 156 32) ;; +dyn_add spheres (create_sphere 560 450 20. 1. 3 32 220 32) ;; +dyn_add spheres (create_sphere 640 450 20. 1. 3 32 220 32) ;; +dyn_add spheres (create_sphere 720 450 20. 1. 3 32 156 32) ;; + +dyn_add spheres (create_sphere 520 350 20. 1. 1 32 192 32) ;; +dyn_add spheres (create_sphere 600 350 20. 1. 1 32 255 32) ;; +dyn_add spheres (create_sphere 680 350 20. 1. 1 32 192 32) ;; + +(* left side *) +dyn_add spheres (create_sphere 20 480 10. 1. 3 32 32 192) ;; +dyn_add spheres (create_sphere 95 555 10. 1. 3 32 32 192) ;; +dyn_add spheres (create_sphere 170 630 10. 1. 3 32 32 192) ;; +dyn_add spheres (create_sphere 245 705 10. 1. 3 32 32 192) ;; +dyn_add spheres (create_sphere 320 780 10. 1. 3 32 32 192) ;; + +dyn_add spheres (create_sphere 20 630 15. 1. 5 32 32 255) ;; +dyn_add spheres (create_sphere 95 705 15. 1. 5 32 32 255) ;; +dyn_add spheres (create_sphere 170 780 15. 1. 5 32 32 255) ;; + +dyn_add spheres (create_sphere 300 300 15. 1. 5 128 128 128) ;; + +(* right side *) +dyn_add spheres (create_sphere 1180 480 10. 1. 3 32 32 192) ;; +dyn_add spheres (create_sphere 1105 555 10. 1. 3 32 32 192) ;; +dyn_add spheres (create_sphere 1030 630 10. 1. 3 32 32 192) ;; +dyn_add spheres (create_sphere 965 705 10. 1. 3 32 32 192) ;; +dyn_add spheres (create_sphere 890 780 10. 1. 3 32 32 192) ;; + +dyn_add spheres (create_sphere 1180 630 15. 1. 5 32 32 255) ;; +dyn_add spheres (create_sphere 1105 705 15. 1. 5 32 32 255) ;; +dyn_add spheres (create_sphere 1030 780 15. 1. 5 32 32 255) ;; + +dyn_add spheres (create_sphere 900 300 15. 1. 5 128 128 128) ;; + +(* on the ramps *) +dyn_add spheres (create_sphere 20 300 20. 1. 7 128 128 128) ;; +dyn_add spheres (create_sphere 1180 300 20. 1. 7 128 128 128) ;; + +(* |-------------------------------------------------------------------------------------------------------| *) + +dyn_add flippers (create_flipper Left 420 125 20. 160. (-. 20.) (-. 20.) 20.) ;; +dyn_add flippers (create_flipper Right 780 125 20. 160. 200. 160. 200.) ;; + +(* |-------------------------------------------------------------------------------------------------------| *) + +simulate polygons spheres flippers ;; +(* +let create_polygon (arr : (int * int) array) (rest : float) (pts : int) (red : int) (green : int) (blue : int) +let create_sphere (x00 : int) (y00 : int) (radius : float) (rest : float) (pts : int) red green blue +let create_flipper (x0 : int) (y0 : int) (rd : float) (len : float) (theta0 : float) (thmin : float) (thmax : float) +*) + +(* ocamlfind ocamlopt -linkpkg -package unix -linkpkg -package graphics -thread -package threads -linkpkg main.ml *) \ No newline at end of file diff --git a/tests/a.out b/tests/a.out new file mode 100755 index 0000000..5f5b022 Binary files /dev/null and b/tests/a.out differ diff --git a/tests/main_test_improved.cmi b/tests/main_test_improved.cmi new file mode 100644 index 0000000..c08acc8 Binary files /dev/null and b/tests/main_test_improved.cmi differ diff --git a/tests/main_test_improved.cmx b/tests/main_test_improved.cmx new file mode 100644 index 0000000..3787ea9 Binary files /dev/null and b/tests/main_test_improved.cmx differ diff --git a/tests/main_test_improved.ml b/tests/main_test_improved.ml new file mode 100644 index 0000000..9fb4812 --- /dev/null +++ b/tests/main_test_improved.ml @@ -0,0 +1,812 @@ +open Graphics ;; +Random.self_init () ;; +(* use Ctrl+F with 'WALUIGI_TIME' to look for sections *) +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Types + Constants *) +exception ReturnBool of bool ;; +exception ReturnInt of int ;; +exception ReturnIntArr of int array * int ;; +let khqoaeuvur = 1200 +and ydpmbgdtos = 800 ;; +let xxtvdauymf = " 1200x800" ;; +let hwwkinuyju = 0.003 ;; +type pt_2d = { +mutable x : float ; +mutable y : float ; +} ;; +type polygon = { +vertexes : pt_2d array ; +rgb : int ; +xmin : float ; +xmax : float ; +ymin : float ; +ymax : float ; +mutable restitution : float ; +score : int ; +} ;; +type sphere = { +center : pt_2d ; +radius : float ; +rgb : int ; +xmin : float ; +xmax : float ; +ymin : float ; +ymax : float ; +mutable restitution : float ; +score : int ; +} ;; +type flipper_side = Left | Right ;; +type flipper = { +side : flipper_side ; +xy : pt_2d ; +radius : float ; +length : float ; +mutable theta : float (* in degrees *) ; +mutable dtheta : float ; +agmin : float ; +agmax : float ; +vtxs : polygon +} ;; +type ball = { +mutable active : bool ; +radius : float ; +mass : float ; +rgb : int ; +xy : pt_2d ; +v : pt_2d ; +a : pt_2d ; +fres : pt_2d ; +} ;; +(* --- *) +let suvesniybj = { +vertexes = [||] ; +rgb = 0 ; +xmin = 1. ; +xmax = -. 1. ; +ymin = 1. ; +ymax = -. 1. ; +restitution = 0. ; +score = 0 ; +} ;; +let blnwpctihp = { +center = {x = 0. ; y = 0.} ; +rgb = 0 ; +radius = -. 1. ; +xmin = 1. ; +xmax = -. 1. ; +ymin = 1. ; +ymax = -. 1. ; +restitution = 0. ; +score = 0 ; +} ;; +let klqsywgkdl = { +side = Left ; +xy = {x = 0. ; y = 0.} ; +radius = 0. ; +length = 0. ; +theta = 0. (* in degrees *) ; +dtheta = 0. ; +agmin = 0. ; +agmax = 0. ; +vtxs = suvesniybj ; +} ;; +let dvtuhryvdi = 750.0 ;; +let ouisbgnena = 3.14159265358979343 ;; +let lvyxllvhpy = (1. /. 131072.) ;; +let atimibvjlv = { +x = 0. ; +y = 0. ; +} ;; +let gwibfgeoyo = { +x = 1200. ; +y = 800. ; +} +let rsmybvbsus = { +x = 750. ; +y = 500. ; +} +let mxlcxxplnb = {x = 0. ; y = -. dvtuhryvdi} ;; +let ufmnpkhbse = ref 8 ;; +let score = ref 0 ;; +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Threads *) +let slhhdrhgid = 8 ;; +let pkuqrbeauq = Array.make slhhdrhgid false ;; +let rkgsirelms = ref 0 ;; +let ghutvewblg id = +while false do +if pkuqrbeauq.(id) then begin +ignore (Unix.system "./sound wah/scored_hit.wav") ; +pkuqrbeauq.(id) <- false ; +end; +Unix.sleepf hwwkinuyju ; +done;; +let apchekncnf = Array.init slhhdrhgid (fun k -> Thread.create ghutvewblg k) ;; +(**) +let sfpqqquwvd () = +while false do +ignore (Unix.system "./sound wah/wah_metal.wav") ; +ignore (Unix.system "./sound wah/wah_eurobeat.wav") ; +ignore (Unix.system "./sound wah/wah_hardcore.wav") ; +done;; +let rynmlxnnea = Thread.create sfpqqquwvd () ;; +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Arithmetical operations *) +let rec pqouljlqnm x n = match n with +| 0 -> 1 +| 1 -> x +| k when k mod 2 = 0 -> pqouljlqnm (x*x) (n/2) +| k -> x * (pqouljlqnm (x*x) (n/2)) ;; +let rec venfkchenr x n = match n with +| 0 -> 1. +| 1 -> x +| k when k mod 2 = 0 -> venfkchenr (x *. x) (n/2) +| k -> x *. (venfkchenr (x *. x) (n/2)) ;; +let rec ewmqlkcvwl n = match n with +| k when k < 0 -> failwith "Are you sure about that ?" +| k when k < 10 -> 0 +| k -> 1 + ewmqlkcvwl (k/10) ;; +let hutnqtagjr x y theta = +(1.0 -. theta) *. x +. theta *. y ;; +let pmodmwkwvl = function +| x when x < 0.0 -> -. x +| x -> x ;; +let rec jcgvonjvkf = function +| k when float_of_int (int_of_float k) = k -> int_of_float k +| k -> jcgvonjvkf (10.0 *. k) ;; +let fbjwjbsrbx = function +| k when k < 10 -> 0 +| _ -> 1 ;; +let gvhsmpxpat x n = +float_of_int (int_of_float (x *. venfkchenr 10. n)) /. (venfkchenr 10. n);; +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Dynamic Arrays *) +type 'a dynamic = { +mutable len : int ; +mutable memlen : int ; +mutable tab : 'a array +} ;; +let infhrfotum (elt : 'a) = +{ +len = 0 ; +memlen = 16 ; +tab = Array.make 16 elt +} ;; +let vyvjbxvwlb (dyn : 'a dynamic) (elt : 'a) = +if dyn.len = dyn.memlen then begin +let nbpuggglmq = Array.make (2 * dyn.memlen) dyn.tab.(0) in +for i = 0 to dyn.memlen -1 do +nbpuggglmq.(i) <- dyn.tab.(i) +done; +dyn.tab <- nbpuggglmq ; +dyn.memlen <- dyn.memlen * 2 ; +end; +dyn.tab.(dyn.len) <- elt ; +dyn.len <- dyn.len +1 ;; +let ylxpvecdry (dyn : 'a dynamic) (elt : 'a) = +try +for i = 0 to dyn.len -1 do +if dyn.tab.(i) = elt then +raise (ReturnInt i) +done; +raise (ReturnInt (-1)) +with +| ReturnInt (-1) -> () +| ReturnInt k -> +for i = k to dyn.len -2 do +dyn.tab.(i) <- dyn.tab.(i+1) +done; +dyn.len <- dyn.len -1 ; +if (dyn.memlen >= 32) && (dyn.len * 4 <= dyn.memlen) then begin +let nbpuggglmq = Array.make (dyn.memlen/2) dyn.tab.(0) in +for i = 0 to dyn.len -1 do +nbpuggglmq.(i) <- dyn.tab.(i) +done; +dyn.tab <- nbpuggglmq ; +dyn.memlen <- dyn.memlen/2 ; +end ;; +let vevglnifxn (f : 'b -> 'a -> 'b) (acc0 : 'b) (dyn : 'a dynamic) = +let dnofdwvumy = ref acc0 in +for i = 0 to dyn.len -1 do +dnofdwvumy := f !dnofdwvumy dyn.tab.(i) +done; +!dnofdwvumy ;; +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Arithmetical operations *) +let snohtmrgum (px : pt_2d) (py : pt_2d) theta = +{ +x = hutnqtagjr px.x py.x theta ; +y = hutnqtagjr px.y py.y theta ; +} ;; +let bejecdgusu (p1 : pt_2d) (p2 : pt_2d) = +{ +x = p1.x +. p2.x ; +y = p1.y +. p2.y ; +} ;; +let igjujhpadn (p1 : pt_2d) (p2 : pt_2d) = +{ +x = p1.x -. p2.x ; +y = p1.y -. p2.y ; +} ;; +let pfjkjpqxed (p1 : pt_2d) (lambda : float) = +{ +x = p1.x *. lambda ; +y = p1.y *. lambda ; +} ;; +let ucukbrjotn (p1 : pt_2d) (p2 : pt_2d) = +{ +x = (p1.x +. p2.x) /. 2.0 ; +y = (p1.y +. p2.y) /. 2.0 ; +} ;; +let maapulttqm (p1 : pt_2d) (p2 : pt_2d) = +{ +x = -. (p2.y -. p1.y) ; +y = (p2.x -. p1.x) ; +} ;; +let mmqdncmyvk (m : pt_2d) (spt : pt_2d) (ept : pt_2d) = +match (-. ((ept.x -. spt.x) *. (spt.x -. m.x) +. (ept.y -. spt.y) *. (spt.y -. m.y)) /. ((ept.x -. spt.x) *. (ept.x -. spt.x) +. (ept.y -. spt.y) *. (ept.y -. spt.y))) with +| k when k >= 0. && k <= 1. -> (snohtmrgum spt ept k) +| k when k < 0. -> spt +| k -> ept ;; +let dtbxywqphy (m : pt_2d) (spt : pt_2d) (ept : pt_2d) = +let theta = (-. ((ept.x -. spt.x) *. (spt.x -. m.x) +. (ept.y -. spt.y) *. (spt.y -. m.y)) /. ((ept.x -. spt.x) *. (ept.x -. spt.x) +. (ept.y -. spt.y) *. (ept.y -. spt.y))) in +(snohtmrgum spt ept theta) ;; +let quuxfwmgkd (p1 : pt_2d) (p2 : pt_2d) = +p1.x *. p2.x +. p1.y *. p2.y ;; +let yfvqjtmemd (p1 : pt_2d) = +Float.sqrt (quuxfwmgkd p1 p1) ;; +let uaqehictpv (p1 : pt_2d) (p2 : pt_2d) = +yfvqjtmemd (igjujhpadn p1 p2) ;; +let pbrftxxxjk (v1 : pt_2d) (v2 : pt_2d) = +pfjkjpqxed v1 ((yfvqjtmemd v2) /. (yfvqjtmemd v1)) ;; +let aerhhxwwcs (v1 : pt_2d) = +pfjkjpqxed v1 (1.0 /. (yfvqjtmemd v1)) ;; +let kyqufjbqgy (m : pt_2d) (p1 : pt_2d) (p2 : pt_2d) = +let cqvkfwkyhr = dtbxywqphy m p1 p2 in +let pladpdsips = igjujhpadn cqvkfwkyhr m in +bejecdgusu (bejecdgusu pladpdsips pladpdsips) m ;; +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Physics functions *) +let acscetgpxy (b : ball) (dt : float) = +{ +x = b.xy.x +. b.v.x *. dt ; +y = b.xy.y +. b.v.y *. dt ; +} ;; +let ocboipiffc (b : ball) (poly : polygon) = +(b.xy.x +. b.radius >= poly.xmin) && (b.xy.x -. b.radius <= poly.xmax) && +(b.xy.y +. b.radius >= poly.ymin) && (b.xy.y -. b.radius <= poly.ymax) ;; +let sbemaxpbld (b : ball) (s : sphere) = +(b.xy.x +. b.radius >= s.xmin) && (b.xy.x -. b.radius <= s.xmax) && +(b.xy.y +. b.radius >= s.ymin) && (b.xy.y -. b.radius <= s.ymax) ;; +let fllowoegnu (m : pt_2d) (spt : pt_2d) (ept : pt_2d) = +match (-. ((ept.x -. spt.x) *. (spt.x -. m.x) +. (ept.y -. spt.y) *. (spt.y -. m.y)) /. ((ept.x -. spt.x) *. (ept.x -. spt.x) +. (ept.y -. spt.y) *. (ept.y -. spt.y))) with +| k when k >= 0. && k <= 1. -> uaqehictpv (snohtmrgum spt ept k) m +| k when k < 0. -> uaqehictpv spt m +| k -> uaqehictpv ept m ;; +let cxmkmqyagv (m : pt_2d) (spt : pt_2d) (ept : pt_2d) = +let theta = (-. ((ept.x -. spt.x) *. (spt.x -. m.x) +. (ept.y -. spt.y) *. (spt.y -. m.y)) /. ((ept.x -. spt.x) *. (ept.x -. spt.x) +. (ept.y -. spt.y) *. (ept.y -. spt.y))) in +uaqehictpv (snohtmrgum spt ept theta) m ;; +let tbxypwjsph (b : ball) (poly : polygon) (dt : float) = +if not (ocboipiffc b poly) then +([||], 0) +else begin +try +let tprvaqtfxn = ref b.radius +and guqrrsswri = Array.make 3 (-1) +and qxcksafkpf = ref 0 in +for i = 0 to Array.length poly.vertexes - 1 do +let qxdpdgqebc = (fllowoegnu (acscetgpxy b dt) poly.vertexes.(i) poly.vertexes.((i+1) mod Array.length poly.vertexes)) in +if qxdpdgqebc <= !tprvaqtfxn -. lvyxllvhpy then begin +tprvaqtfxn := qxdpdgqebc ; +guqrrsswri.(0) <- i ; +guqrrsswri.(1) <- (-1) ; +guqrrsswri.(2) <- (-1) ; +qxcksafkpf := 1; +end +else if qxdpdgqebc <= !tprvaqtfxn then begin +guqrrsswri.(!qxcksafkpf) <- i ; +incr qxcksafkpf ; +end +done; +raise (ReturnIntArr (guqrrsswri, !qxcksafkpf)) +with +| ReturnIntArr (a, b) -> (a, b) +| Invalid_argument _ -> failwith "ok then" +end ;; +let ghutvewblg () = +pkuqrbeauq.(!rkgsirelms) <- true ; +rkgsirelms := (!rkgsirelms+1) mod slhhdrhgid ;; +let aqvohvorvs (b : ball) (s : sphere) (dt : float) = +if not (sbemaxpbld b s) then +false +else +uaqehictpv (acscetgpxy b dt) (s.center) <= (s.radius +. b.radius) ;; +let ffmvmahtvp (b : ball) (polys : polygon array) (spheres : sphere array) (flips : flipper dynamic) (dt : float) = +b.fres.x <- 0. ; +b.fres.y <- 0. ; +for p = 0 to (Array.length polys -1) do +let (ompbdarwgo, hitlen) = (tbxypwjsph b polys.(p) dt) in +if hitlen > 0 then begin +for h = 0 to hitlen -1 do +let iggdpgyaxj = ompbdarwgo.(h) in +score := !score + polys.(p).score ; +if h = 0 && polys.(p).score > 0 then +ghutvewblg () ; +if polys.(p).restitution = 0. then begin +b.active <- false ; +decr ufmnpkhbse ; +end; +(* apply normal reaction force *) +let pxkgfflejm = (iggdpgyaxj +1) mod (Array.length polys.(p).vertexes) in +let cqvkfwkyhr = mmqdncmyvk b.xy polys.(p).vertexes.(iggdpgyaxj) polys.(p).vertexes.(pxkgfflejm) in +let xaqqcssgyu = aerhhxwwcs (igjujhpadn b.xy cqvkfwkyhr) in +let gxyowcywlc = (quuxfwmgkd (aerhhxwwcs mxlcxxplnb) xaqqcssgyu) in +if gxyowcywlc > 0. then begin +let kkoitxjucy = pfjkjpqxed xaqqcssgyu (dvtuhryvdi *. b.mass *. gxyowcywlc) in +b.fres.x <- b.fres.x +. kkoitxjucy.x *. polys.(p).restitution /. float_of_int hitlen ; +b.fres.y <- b.fres.y +. kkoitxjucy.y *. polys.(p).restitution /. float_of_int hitlen ; +end; +(* change velocity according to angle *) +if hitlen = 1 then begin +let rseawtwpni = igjujhpadn polys.(p).vertexes.(pxkgfflejm) polys.(p).vertexes.(iggdpgyaxj) in +let htlsypempr = kyqufjbqgy b.v {x = 0. ; y = 0.} rseawtwpni in +b.v.x <- htlsypempr.x ; +b.v.y <- htlsypempr.y ; +end +else begin +let oysqudbrnj = pfjkjpqxed (aerhhxwwcs (igjujhpadn b.xy cqvkfwkyhr)) (yfvqjtmemd b.v) in +b.v.x <- oysqudbrnj.x ; +b.v.y <- oysqudbrnj.y ; +end +done +end +done ; +for s = 0 to (Array.length spheres -1) do +if aqvohvorvs b spheres.(s) dt then begin +score := !score + spheres.(s).score ; +if spheres.(s).score > 0 then +ghutvewblg () ; +if spheres.(s).restitution = 0. then begin +b.active <- false ; +decr ufmnpkhbse ; +end; +(* apply normal reaction force *) +let xaqqcssgyu = aerhhxwwcs (igjujhpadn b.xy spheres.(s).center) in +let gxyowcywlc = (quuxfwmgkd (aerhhxwwcs mxlcxxplnb) xaqqcssgyu) in +if gxyowcywlc > 0. then begin +let kkoitxjucy = pfjkjpqxed xaqqcssgyu (dvtuhryvdi *. b.mass *. gxyowcywlc) in +b.fres.x <- b.fres.x +. kkoitxjucy.x *. spheres.(s).restitution *. 1.1 ; +b.fres.y <- b.fres.y +. kkoitxjucy.y *. spheres.(s).restitution *. 1.1 ; +end; +(* change velocity according to angle *) +let theta = b.radius /. (yfvqjtmemd (igjujhpadn b.xy spheres.(s).center)) in +let uvvfdexeuk = (snohtmrgum b.xy spheres.(s).center theta) in +let rseawtwpni = maapulttqm uvvfdexeuk (bejecdgusu uvvfdexeuk xaqqcssgyu) in +let htlsypempr = kyqufjbqgy b.v {x = 0. ; y = 0.} rseawtwpni in +b.v.x <- htlsypempr.x ; +b.v.y <- htlsypempr.y ; +end +done ; +for f = 0 to flips.len -1 do +let (ompbdarwgo, hitlen) = (tbxypwjsph b flips.tab.(f).vtxs dt) in +if hitlen > 0 then begin +for h = 0 to hitlen -1 do +let iggdpgyaxj = ompbdarwgo.(h) in +(* apply normal reaction force *) +let pxkgfflejm = (iggdpgyaxj +1) mod (Array.length flips.tab.(f).vtxs.vertexes) in +let cqvkfwkyhr = mmqdncmyvk b.xy flips.tab.(f).vtxs.vertexes.(iggdpgyaxj) flips.tab.(f).vtxs.vertexes.(pxkgfflejm) in +let xaqqcssgyu = aerhhxwwcs (igjujhpadn b.xy cqvkfwkyhr) in +let gxyowcywlc = (quuxfwmgkd (aerhhxwwcs mxlcxxplnb) xaqqcssgyu) in +if gxyowcywlc > 0. then begin +let kkoitxjucy = pfjkjpqxed xaqqcssgyu (dvtuhryvdi *. b.mass *. gxyowcywlc) in +b.fres.x <- b.fres.x +. kkoitxjucy.x *. flips.tab.(f).vtxs.restitution /. float_of_int hitlen ; +b.fres.y <- b.fres.y +. kkoitxjucy.y *. flips.tab.(f).vtxs.restitution /. float_of_int hitlen ; +end; +(* change velocity according to angle *) +if hitlen = 1 then begin +let rseawtwpni = igjujhpadn flips.tab.(f).vtxs.vertexes.(pxkgfflejm) flips.tab.(f).vtxs.vertexes.(iggdpgyaxj) in +let htlsypempr = kyqufjbqgy b.v {x = 0. ; y = 0.} rseawtwpni in +b.v.x <- htlsypempr.x ; +b.v.y <- htlsypempr.y ; +end +else begin +let oysqudbrnj = pfjkjpqxed (aerhhxwwcs (igjujhpadn b.xy cqvkfwkyhr)) (yfvqjtmemd b.v) in +b.v.x <- oysqudbrnj.x ; +b.v.y <- oysqudbrnj.y ; +end; +(* add relative velocity [disabled for physical reasons] *) +if false && ((flips.tab.(f).side = Left && flips.tab.(f).dtheta > 0.) || (flips.tab.(f).side = Right && flips.tab.(f).dtheta < 0.)) then begin +b.v.x <- 0.5 *. b.v.x +. flips.tab.(f).dtheta *. 3.14159 /. 180. *. (uaqehictpv flips.tab.(f).xy b.xy) *. (cos (flips.tab.(f).theta *. 3.14159 /. 180.)); +b.v.y <- 0.5 *. b.v.y +. flips.tab.(f).dtheta *. 3.14159 /. 180. *. (uaqehictpv flips.tab.(f).xy b.xy) *. (sin (flips.tab.(f).theta *. 3.14159 /. 180.)); +end +done +end +done; +(* P = mg *) +b.fres.y <- b.fres.y -. dvtuhryvdi *. b.mass ; +(* PFD : ma = sum(F) *) +b.a.x <- b.fres.x /. b.mass ; +b.a.y <- b.fres.y /. b.mass ; +b.v.x <- b.v.x +. b.a.x *. dt ; +b.v.y <- b.v.y +. b.a.y *. dt ; +b.xy.x <- b.xy.x +. b.v.x *. dt ; +b.xy.y <- b.xy.y +. b.v.y *. dt ;; +let xspdkspljw (bl : ball array) (polys : polygon array) (spheres : sphere array) (flips : flipper dynamic) (dt : float) = +for b = 0 to Array.length bl -1 do +if bl.(b).active then +ffmvmahtvp bl.(b) polys spheres flips dt +done ;; +let qgewwkqbap (flips : flipper dynamic) (dt : float) = +for fl = 0 to flips.len -1 do +if flips.tab.(fl).dtheta <> 0. then begin +let hxwgbulfmm = flips.tab.(fl).xy.x +and ijqcdxblfh = flips.tab.(fl).xy.y +and brumryeefp = flips.tab.(fl).radius +and len = flips.tab.(fl).length +and ortmvyuadt = flips.tab.(fl).theta in +match flips.tab.(fl).side with +| Left -> +let lfeiwkypud = flips.tab.(fl).theta +. flips.tab.(fl).dtheta *. dt in +if lfeiwkypud > flips.tab.(fl).agmax then +flips.tab.(fl).dtheta <- -.(flips.tab.(fl).dtheta) ; +if lfeiwkypud < flips.tab.(fl).agmin then +flips.tab.(fl).dtheta <- 0. ; +flips.tab.(fl).theta <- lfeiwkypud ; +flips.tab.(fl).vtxs.vertexes.(0) <- { +x = hxwgbulfmm +. len *. (cos (ortmvyuadt *. 3.14159 /. 180.)); +y = ijqcdxblfh +. len *. (sin (ortmvyuadt *. 3.14159 /. 180.)) +}; +flips.tab.(fl).vtxs.vertexes.(1) <- { +x = hxwgbulfmm +. brumryeefp *. (cos ((ortmvyuadt +. 90.) *. 3.14159 /. 180.)); +y = ijqcdxblfh +. brumryeefp *. (sin ((ortmvyuadt +. 90.) *. 3.14159 /. 180.)) +}; +flips.tab.(fl).vtxs.vertexes.(2) <- { +x = hxwgbulfmm +. brumryeefp *. (cos ((ortmvyuadt -. 90.) *. 3.14159 /. 180.)); +y = ijqcdxblfh +. brumryeefp *. (sin ((ortmvyuadt -. 90.) *. 3.14159 /. 180.)) +}; +| Right -> +let lfeiwkypud = flips.tab.(fl).theta +. flips.tab.(fl).dtheta *. dt in +if lfeiwkypud > flips.tab.(fl).agmax then +flips.tab.(fl).dtheta <- 0. ; +if lfeiwkypud < flips.tab.(fl).agmin then +flips.tab.(fl).dtheta <- -.(flips.tab.(fl).dtheta) ; +flips.tab.(fl).theta <- lfeiwkypud ; +flips.tab.(fl).vtxs.vertexes.(0) <- { +x = hxwgbulfmm +. len *. (cos (ortmvyuadt *. 3.14159 /. 180.)); +y = ijqcdxblfh +. len *. (sin (ortmvyuadt *. 3.14159 /. 180.)) +}; +flips.tab.(fl).vtxs.vertexes.(1) <- { +x = hxwgbulfmm +. brumryeefp *. (cos ((ortmvyuadt +. 90.) *. 3.14159 /. 180.)); +y = ijqcdxblfh +. brumryeefp *. (sin ((ortmvyuadt +. 90.) *. 3.14159 /. 180.)) +}; +flips.tab.(fl).vtxs.vertexes.(2) <- { +x = hxwgbulfmm +. brumryeefp *. (cos ((ortmvyuadt -. 90.) *. 3.14159 /. 180.)); +y = ijqcdxblfh +. brumryeefp *. (sin ((ortmvyuadt -. 90.) *. 3.14159 /. 180.)) +}; +end +done ;; +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Graphics fcts *) +let akksmqshhj hxwgbulfmm y n0 r = +(* 7-seg display *) +let n = ref n0 in +let micgxbkxot = ewmqlkcvwl n0 in +let len = r/3 in +let gunvxnxkeu = micgxbkxot*(len*11/7)/2 in +for i = 0 to micgxbkxot do +let x = hxwgbulfmm + gunvxnxkeu - i*(len*11/7) in +if Array.mem (!n mod 10) [|0; 4; 5; 6; 7; 8; 9|] then +draw_poly_line [|(x-len/2, y+len); (x-len/2, y)|]; +if Array.mem (!n mod 10) [|0; 2; 3; 5; 6; 7; 8; 9|] then +draw_poly_line [|(x-len/2, y+len); (x+len/2, y+len)|]; +if Array.mem (!n mod 10) [|0; 1; 2; 3; 4; 7; 8; 9|] then +draw_poly_line [|(x+len/2, y+len); (x+len/2, y)|]; +if Array.mem (!n mod 10) [|2; 3; 4; 5; 6; 8; 9|] then +draw_poly_line [|(x-len/2, y); (x+len/2, y)|]; +if Array.mem (!n mod 10) [|0; 1; 3; 4; 5; 6; 7; 8; 9|] then +draw_poly_line [|(x+len/2, y-len); (x+len/2, y)|]; +if Array.mem (!n mod 10) [|0; 2; 3; 5; 6; 8; 9|] then +draw_poly_line [|(x-len/2, y-len); (x+len/2, y-len)|]; +if Array.mem (!n mod 10) [|0; 2; 6; 8|] then +draw_poly_line [|(x-len/2, y-len); (x-len/2, y)|]; +n := !n/10; +done ;; +let nkktxxoumg hxwgbulfmm y n0 len = +(* 7-seg display 2 *) +set_line_width (max 1 (len/4)); +let n = ref n0 in +let micgxbkxot = ewmqlkcvwl (abs n0) in +let vvielwjcau = ref (hxwgbulfmm + micgxbkxot*(len*11/7)) in +if !n < 0 then begin +n := !n * (-1); +draw_poly_line [|(hxwgbulfmm, y); (hxwgbulfmm+len, y)|]; +vvielwjcau := !vvielwjcau + (len*11/7) +end; +for i = 0 to micgxbkxot do +let x = !vvielwjcau in +if Array.mem (!n mod 10) [|0; 4; 5; 6; 7; 8; 9|] then +draw_poly_line [|(x, y+len); (x, y)|]; +if Array.mem (!n mod 10) [|0; 2; 3; 5; 6; 7; 8; 9|] then +draw_poly_line [|(x, y+len); (x+len, y+len)|]; +if Array.mem (!n mod 10) [|0; 1; 2; 3; 4; 7; 8; 9|] then +draw_poly_line [|(x+len, y+len); (x+len, y)|]; +if Array.mem (!n mod 10) [|2; 3; 4; 5; 6; 8; 9|] then +draw_poly_line [|(x, y); (x+len, y)|]; +if Array.mem (!n mod 10) [|0; 1; 3; 4; 5; 6; 7; 8; 9|] then +draw_poly_line [|(x+len, y-len); (x+len, y)|]; +if Array.mem (!n mod 10) [|0; 2; 3; 5; 6; 8; 9|] then +draw_poly_line [|(x, y-len); (x+len, y-len)|]; +if Array.mem (!n mod 10) [|0; 2; 6; 8|] then +draw_poly_line [|(x, y-len); (x, y)|]; +n := !n/10; +vvielwjcau := !vvielwjcau - (len*11/7); +done ;; +let cedssxkuuc x y n0 r = +let n = pmodmwkwvl n0 in +let yaaxjbqqjx = int_of_float n in +let wkqbyygdvn = jcgvonjvkf (n -. float_of_int yaaxjbqqjx) in +nkktxxoumg x y yaaxjbqqjx r ; +fill_circle (x + (ewmqlkcvwl yaaxjbqqjx) * r * 11/7 + 3*r/2) (y - r) 3 ; +nkktxxoumg (x + 3*r/5 + (ewmqlkcvwl yaaxjbqqjx + 1)*r*11/7) y ((100 * wkqbyygdvn) / (pqouljlqnm 10 (1+ ewmqlkcvwl wkqbyygdvn))) r ;; +let eijhhwwbqm (poly : polygon) = +set_color (rgb (poly.rgb mod 256) ((poly.rgb / 256) mod 256) ((poly.rgb / (256*256)) mod 256)) ; +fill_poly (Array.init (Array.length poly.vertexes) (fun i -> (int_of_float poly.vertexes.(i).x, int_of_float poly.vertexes.(i).y))) ;; +let dwhfllwgax (s : sphere) = +set_color (rgb (s.rgb mod 256) ((s.rgb / 256) mod 256) ((s.rgb / (256*256)) mod 256)) ; +fill_circle (int_of_float s.center.x) (int_of_float s.center.y) (int_of_float s.radius) ;; +let uqvgbvmfqp (f : flipper) = +set_color (rgb 64 64 64) ; +fill_circle (int_of_float f.xy.x) (int_of_float f.xy.y) (int_of_float f.radius) ; +eijhhwwbqm f.vtxs ;; +let waisadxkmv (b : ball) = +set_color (rgb (b.rgb mod 256) ((b.rgb / 256) mod 256) ((b.rgb / (256*256)) mod 256)) ; +fill_circle (int_of_float b.xy.x) (int_of_float b.xy.y) (int_of_float b.radius) ; +set_line_width 4 ; +draw_circle (int_of_float b.xy.x) (int_of_float b.xy.y) (int_of_float b.radius) ;; +let aiiilcgctu (bs : ball array) = +for k = 0 to Array.length bs -1 do +if bs.(k).active then +waisadxkmv bs.(k) +done ;; +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Misc fcts *) +let bkicytmgfd () = +if key_pressed () then +read_key () +else +'@' ;; +let wgqkvaivry (flips : flipper dynamic) = +match bkicytmgfd () with +| 'q' -> +for fl = 0 to flips.len -1 do +if flips.tab.(fl).side = Left && flips.tab.(fl).dtheta = 0. then +flips.tab.(fl).dtheta <- 600. ; +done +| 'd' -> +for fl = 0 to flips.len -1 do +if flips.tab.(fl).side = Right && flips.tab.(fl).dtheta = 0. then +flips.tab.(fl).dtheta <- -. 600. ; +done +| _ -> () ;; +let lhbcpmtcyh (r : float) (hxwgbulfmm : int) (ijqcdxblfh : int) (m : float) (red : int) (green : int) (blue : int) = +{ +active = true ; +radius = r ; +rgb = red + 256 * green + 256 * 256 * blue ; +mass = m; +xy = {x = float_of_int hxwgbulfmm +. (Random.float 30.0 -. 15.0); y = float_of_int ijqcdxblfh +. (Random.float 30.0 -. 15.0)} ; +v = {x = 0. ; y = 0.} ; +a = {x = 0. ; y = 0.} ; +fres = {x = 0. ; y = 0.} ; +} ;; +let xmlrntccqv (arr : (int * int) array) (rest : float) (pts : int) (red : int) (green : int) (blue : int) = +{ +vertexes = Array.init (Array.length arr) (fun k -> {x = float_of_int (fst arr.(k)); y = float_of_int (snd arr.(k))}) ; +rgb = red + 256 * green + 256 * 256 * blue ; +xmin = float_of_int (Array.fold_left (fun dnofdwvumy k -> min dnofdwvumy (fst k)) 99999 arr) ; +xmax = float_of_int (Array.fold_left (fun dnofdwvumy k -> max dnofdwvumy (fst k)) (-99999) arr) ; +ymin = float_of_int (Array.fold_left (fun dnofdwvumy k -> min dnofdwvumy (snd k)) 99999 arr) ; +ymax = float_of_int (Array.fold_left (fun dnofdwvumy k -> max dnofdwvumy (snd k)) (-99999) arr) ; +restitution = rest ; +score = pts ; +} ;; +let endykgqsgx (x00 : int) (y00 : int) (brumryeefp : float) (rest : float) (pts : int) (red : int) (green : int) (blue : int) = +let hxwgbulfmm = float_of_int x00 and ijqcdxblfh = float_of_int y00 in +{ +center = {x = hxwgbulfmm ; y = ijqcdxblfh}; +rgb = red + 256 * green + 256 * 256 * blue ; +radius = brumryeefp ; +xmin = hxwgbulfmm -. brumryeefp ; +xmax = hxwgbulfmm +. brumryeefp ; +ymin = ijqcdxblfh -. brumryeefp ; +ymax = ijqcdxblfh +. brumryeefp ; +restitution = rest ; +score = pts ; +} ;; +let jyyiilwnkr (side : flipper_side) (hxwgbulfmm : int) (ijqcdxblfh : int) (brumryeefp : float) (len : float) (ortmvyuadt : float) (thmin : float) (thmax : float) = +{ +side = side ; +xy = {x = float_of_int hxwgbulfmm ; y = float_of_int ijqcdxblfh} ; +radius = brumryeefp ; +length = len ; +theta = ortmvyuadt (* in degrees *) ; +dtheta = 0. ; +agmin = thmin ; +agmax = thmax ; +vtxs = xmlrntccqv [| +(hxwgbulfmm + int_of_float (len *. (cos (ortmvyuadt *. 3.14159 /. 180.))) , ijqcdxblfh + int_of_float (len *. (sin (ortmvyuadt *. 3.14159 /. 180.)))); +(hxwgbulfmm + int_of_float (brumryeefp *. (cos ((ortmvyuadt -. 90.) *. 3.14159 /. 180.))), ijqcdxblfh + int_of_float (brumryeefp *. (sin ((ortmvyuadt -. 90.) *. 3.14159 /. 180.)))); +(hxwgbulfmm + int_of_float (brumryeefp *. (cos ((ortmvyuadt +. 90.) *. 3.14159 /. 180.))), ijqcdxblfh + int_of_float (brumryeefp *. (sin ((ortmvyuadt +. 90.) *. 3.14159 /. 180.)))) +|] 1. 0 128 128 128 +} ;; +let qsmxalwtqk (count : int) (r : float) (hxwgbulfmm : int) (ijqcdxblfh : int) (m : float) (red : int) (green : int) (blue : int) = +Array.init count (fun k -> lhbcpmtcyh r hxwgbulfmm ijqcdxblfh m red green blue) ;; +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Edition functions *) +let owrndhnbxi lvl_name = +open_graph xxtvdauymf ; +set_window_title "WAH" ; +let (onyoeqlwhk : polygon dynamic) = infhrfotum suvesniybj in +let vbemgygrbn = ref false in +let ajkuxrtmii = ref true in +let (vvuwhvgjnw : pt_2d dynamic) = infhrfotum {x = 0. ; y = 0.} in +while not !vbemgygrbn do +Unix.sleepf hwwkinuyju ; +if !ajkuxrtmii then begin +auto_synchronize false ; +clear_graph () ; +ajkuxrtmii := false ; +for p = 0 to onyoeqlwhk.len -1 do +eijhhwwbqm onyoeqlwhk.tab.(p) +done; +auto_synchronize true ; +end; +match (bkicytmgfd ()) with +| 'a' -> (* add current polygon *) +(*Printf.printf "+polygon\n" ;*) +if vvuwhvgjnw.len >= 2 then begin +ajkuxrtmii := true ; +let tmworeidqu = Array.init vvuwhvgjnw.len (fun k -> vvuwhvgjnw.tab.(k)) in +vyvjbxvwlb onyoeqlwhk { +vertexes = tmworeidqu ; +rgb = 128 + 255*128 + 255*255*128 ; +xmin = Array.fold_left (fun dnofdwvumy k -> min dnofdwvumy k.x) (999999.) tmworeidqu ; +xmax = Array.fold_left (fun dnofdwvumy k -> max dnofdwvumy k.x) (-.999999.) tmworeidqu ; +ymin = Array.fold_left (fun dnofdwvumy k -> min dnofdwvumy k.y) (999999.) tmworeidqu ; +ymax = Array.fold_left (fun dnofdwvumy k -> max dnofdwvumy k.y) (-.999999.) tmworeidqu ; +restitution = 1. ; +score = 0 ; +} ; +vvuwhvgjnw.len <- 0 ; +end +| 'v' -> (* add a vertex *) +(*Printf.printf "+vertex\n" ;*) +let (pldswcamqr, my) = mouse_pos () in +vyvjbxvwlb vvuwhvgjnw {x = float_of_int pldswcamqr ; y = float_of_int my} ; +| 'c' -> (* clear current polygon *) +(*Printf.printf "cleared\n" ;*) +vvuwhvgjnw.len <- 0 ; +| 'h' -> +vbemgygrbn := true ; +| _ -> () +done; +close_graph (); +onyoeqlwhk ;; +(* ------------------------------------------------------------------------------------- *) +(* ------------------------------------------------------------------------------------- *) +(* WALUIGI_TIME Main *) +let mxaxilfobj (data : polygon dynamic) (dats : sphere dynamic) (flips : flipper dynamic) = +open_graph xxtvdauymf ; +set_window_title "WAH" ; +let pctksfltxq = qsmxalwtqk 8 10.0 600 800 0.15 255 255 0 in +let fjekplgywk = Unix.gettimeofday () in +let jrtefovmxj = ref (Unix.gettimeofday ()) in +while true do +let omnpcmseyq = Unix.gettimeofday () in +auto_synchronize false ; +clear_graph () ; +set_line_width 4 ; +akksmqshhj 600 100 !ufmnpkhbse 40 ; +set_line_width 1 ; +for d = 0 to dats.len -1 do +dwhfllwgax dats.tab.(d) +done; +for d = 0 to data.len -1 do +eijhhwwbqm data.tab.(d) +done; +for d = 0 to flips.len -1 do +uqvgbvmfqp flips.tab.(d) +done; +aiiilcgctu pctksfltxq ; +set_color (rgb 128 128 32) ; +cedssxkuuc 25 770 (gvhsmpxpat (!jrtefovmxj -. fjekplgywk) 3) 25 ; +set_color black ; +set_line_width 4 ; +akksmqshhj 600 770 !score 50 ; +auto_synchronize true ; +wgqkvaivry flips ; +Unix.sleepf hwwkinuyju ; +let pumwckmhxf = Unix.gettimeofday () in +jrtefovmxj := !jrtefovmxj +. (pumwckmhxf -. omnpcmseyq) ; +xspdkspljw pctksfltxq data.tab dats.tab flips (pumwckmhxf -. omnpcmseyq) ; +qgewwkqbap flips (pumwckmhxf -. omnpcmseyq) ; +done; +close_graph () ;; +let ygjbohpamm = infhrfotum suvesniybj ;; +let spheres = infhrfotum blnwpctihp ;; +let tcodwswtai = infhrfotum klqsywgkdl ;; +(* |-------------------------------------------------------------------------------------------------------| *) +(* kill platform *) +vyvjbxvwlb ygjbohpamm (xmlrntccqv [|(700, -20); (500, -20); (500, 1); (700, 1)|] 0. 0 255 32 32) ;; +(* outer walls *) +vyvjbxvwlb ygjbohpamm (xmlrntccqv [|(0, 0); (500, 0); (500, 20); (0, 20)|] 1. 0 32 32 32) ;; +vyvjbxvwlb ygjbohpamm (xmlrntccqv [|(700, 0); (1200, 0); (1200, 20); (700, 20)|] 1. 0 32 32 32) ;; +vyvjbxvwlb ygjbohpamm (xmlrntccqv [|(0, 800); (500, 800); (500, 780); (0, 780)|] 1. 0 32 32 32) ;; +vyvjbxvwlb ygjbohpamm (xmlrntccqv [|(700, 800); (1200, 800); (1200, 780); (700, 780)|] 1. 0 32 32 32) ;; +vyvjbxvwlb ygjbohpamm (xmlrntccqv [|(1180, 0); (1200, 0); (1200, 800); (1180, 800)|] 1. 0 32 32 32) ;; +vyvjbxvwlb ygjbohpamm (xmlrntccqv [|(0, 0); (20, 0); (20, 800); (0, 800)|] 1. 0 32 32 32) ;; +(* side ramps *) +vyvjbxvwlb ygjbohpamm (xmlrntccqv [|(20, 20); (20, 300); (420, 150); (420, 20)|] 1. 0 32 32 32) ;; +vyvjbxvwlb ygjbohpamm (xmlrntccqv [|(1200, 20); (1200, 300); (780, 150); (780, 20)|] 1. 0 32 32 32) ;; +(* starting platform *) +vyvjbxvwlb ygjbohpamm (xmlrntccqv [|(600, 700); (400, 550); (800, 550)|] 1. 0 32 32 32) ;; +(* |-------------------------------------------------------------------------------------------------------| *) +(* corner scoring spots *) +vyvjbxvwlb spheres (endykgqsgx 20 780 30. 1. 50 128 128 32) ;; +vyvjbxvwlb spheres (endykgqsgx 1180 780 30. 1. 50 128 128 32) ;; +(* under the starting platform *) +vyvjbxvwlb spheres (endykgqsgx 440 550 20. 1. 5 32 128 32) ;; +vyvjbxvwlb spheres (endykgqsgx 520 550 20. 1. 5 32 192 32) ;; +vyvjbxvwlb spheres (endykgqsgx 600 550 20. 1. 5 32 255 32) ;; +vyvjbxvwlb spheres (endykgqsgx 680 550 20. 1. 5 32 192 32) ;; +vyvjbxvwlb spheres (endykgqsgx 760 550 20. 1. 5 32 128 32) ;; +vyvjbxvwlb spheres (endykgqsgx 480 450 20. 1. 3 32 156 32) ;; +vyvjbxvwlb spheres (endykgqsgx 560 450 20. 1. 3 32 220 32) ;; +vyvjbxvwlb spheres (endykgqsgx 640 450 20. 1. 3 32 220 32) ;; +vyvjbxvwlb spheres (endykgqsgx 720 450 20. 1. 3 32 156 32) ;; +vyvjbxvwlb spheres (endykgqsgx 520 350 20. 1. 1 32 192 32) ;; +vyvjbxvwlb spheres (endykgqsgx 600 350 20. 1. 1 32 255 32) ;; +vyvjbxvwlb spheres (endykgqsgx 680 350 20. 1. 1 32 192 32) ;; +(* left side *) +vyvjbxvwlb spheres (endykgqsgx 20 480 10. 1. 3 32 32 192) ;; +vyvjbxvwlb spheres (endykgqsgx 95 555 10. 1. 3 32 32 192) ;; +vyvjbxvwlb spheres (endykgqsgx 170 630 10. 1. 3 32 32 192) ;; +vyvjbxvwlb spheres (endykgqsgx 245 705 10. 1. 3 32 32 192) ;; +vyvjbxvwlb spheres (endykgqsgx 320 780 10. 1. 3 32 32 192) ;; +vyvjbxvwlb spheres (endykgqsgx 20 630 15. 1. 5 32 32 255) ;; +vyvjbxvwlb spheres (endykgqsgx 95 705 15. 1. 5 32 32 255) ;; +vyvjbxvwlb spheres (endykgqsgx 170 780 15. 1. 5 32 32 255) ;; +vyvjbxvwlb spheres (endykgqsgx 300 300 15. 1. 5 128 128 128) ;; +(* right side *) +vyvjbxvwlb spheres (endykgqsgx 1180 480 10. 1. 3 32 32 192) ;; +vyvjbxvwlb spheres (endykgqsgx 1105 555 10. 1. 3 32 32 192) ;; +vyvjbxvwlb spheres (endykgqsgx 1030 630 10. 1. 3 32 32 192) ;; +vyvjbxvwlb spheres (endykgqsgx 965 705 10. 1. 3 32 32 192) ;; +vyvjbxvwlb spheres (endykgqsgx 890 780 10. 1. 3 32 32 192) ;; +vyvjbxvwlb spheres (endykgqsgx 1180 630 15. 1. 5 32 32 255) ;; +vyvjbxvwlb spheres (endykgqsgx 1105 705 15. 1. 5 32 32 255) ;; +vyvjbxvwlb spheres (endykgqsgx 1030 780 15. 1. 5 32 32 255) ;; +vyvjbxvwlb spheres (endykgqsgx 900 300 15. 1. 5 128 128 128) ;; +(* on the ramps *) +vyvjbxvwlb spheres (endykgqsgx 20 300 20. 1. 7 128 128 128) ;; +vyvjbxvwlb spheres (endykgqsgx 1180 300 20. 1. 7 128 128 128) ;; +(* |-------------------------------------------------------------------------------------------------------| *) +vyvjbxvwlb tcodwswtai (jyyiilwnkr Left 420 125 20. 160. (-. 20.) (-. 20.) 20.) ;; +vyvjbxvwlb tcodwswtai (jyyiilwnkr Right 780 125 20. 160. 200. 160. 200.) ;; +(* |-------------------------------------------------------------------------------------------------------| *) +mxaxilfobj ygjbohpamm spheres tcodwswtai ;; +(* +let xmlrntccqv (arr : (int * int) array) (rest : float) (pts : int) (red : int) (green : int) (blue : int) +let endykgqsgx (x00 : int) (y00 : int) (radius : float) (rest : float) (pts : int) red green blue +let jyyiilwnkr (hxwgbulfmm : int) (ijqcdxblfh : int) (brumryeefp : float) (len : float) (ortmvyuadt : float) (thmin : float) (thmax : float) +*) +(* ocamlfind ocamlopt -linkpkg -package unix -linkpkg -package graphics -thread -package threads -linkpkg main.ml *) diff --git a/tests/main_test_improved.o b/tests/main_test_improved.o new file mode 100644 index 0000000..ac32b84 Binary files /dev/null and b/tests/main_test_improved.o differ