[full rework]

This commit is contained in:
Alexandre 2024-12-23 15:48:39 +01:00
parent 4f37301325
commit c53fd564a2
31 changed files with 496 additions and 507 deletions

View File

@ -1,4 +0,0 @@
This is a less broken version of the Math Game
The way you play this : an arithmetic equation is shown on the screen, answer fast to earn more points
[Right now the core game function hasn't been implemented so please wait]

BIN
a.out

Binary file not shown.

2
compilation.sh Normal file
View File

@ -0,0 +1,2 @@
rm *.cmi *.cmx
ocamlfind ocamlopt -linkpkg -package unix -linkpkg -package graphics csts.ml dynamic.ml math.ml drawing.ml menus.ml main.ml -o math

BIN
constants.o Normal file

Binary file not shown.

BIN
csts.cmi Normal file

Binary file not shown.

BIN
csts.cmx Normal file

Binary file not shown.

22
csts.ml Normal file
View File

@ -0,0 +1,22 @@
type rect = {
x : int ;
y : int ;
w : int ;
h : int ;
} ;;
let default_rect = {
x = 0 ;
y = 0 ;
w = 0 ;
h = 0 ;
} ;;
let __width__ = 1200
and __height__ = 900 ;;
let open_string = " 1200x900" ;;
let camx = ref 0
and camy = ref 0 ;;
let sleep_d = 0.01 ;;

BIN
csts.o Normal file

Binary file not shown.

BIN
drawing.cmi Normal file

Binary file not shown.

BIN
drawing.cmx Normal file

Binary file not shown.

135
drawing.ml Normal file
View File

@ -0,0 +1,135 @@
open Graphics ;;
let draw_integer x0 y n0 r =
(* 7-seg display *)
let n = ref n0 in
let size = Math.ln_b 10 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 + !(Csts.camx), y+len + !(Csts.camy)); (x-len/2 + !(Csts.camx), y + !(Csts.camy))|];
if Array.mem (!n mod 10) [|0; 2; 3; 5; 6; 7; 8; 9|] then
draw_poly_line [|(x-len/2 + !(Csts.camx), y+len + !(Csts.camy)); (x+len/2 + !(Csts.camx), y+len + !(Csts.camy))|];
if Array.mem (!n mod 10) [|0; 1; 2; 3; 4; 7; 8; 9|] then
draw_poly_line [|(x+len/2 + !(Csts.camx), y+len + !(Csts.camy)); (x+len/2 + !(Csts.camx), y + !(Csts.camy))|];
if Array.mem (!n mod 10) [|2; 3; 4; 5; 6; 8; 9|] then
draw_poly_line [|(x-len/2 + !(Csts.camx), y + !(Csts.camy)); (x+len/2 + !(Csts.camx), y + !(Csts.camy))|];
if Array.mem (!n mod 10) [|0; 1; 3; 4; 5; 6; 7; 8; 9|] then
draw_poly_line [|(x+len/2 + !(Csts.camx), y-len + !(Csts.camy)); (x+len/2 + !(Csts.camx), y + !(Csts.camy))|];
if Array.mem (!n mod 10) [|0; 2; 3; 5; 6; 8; 9|] then
draw_poly_line [|(x-len/2 + !(Csts.camx), y-len + !(Csts.camy)); (x+len/2 + !(Csts.camx), y-len + !(Csts.camy))|];
if Array.mem (!n mod 10) [|0; 2; 6; 8|] then
draw_poly_line [|(x-len/2 + !(Csts.camx), y-len + !(Csts.camy)); (x-len/2 + !(Csts.camx), y + !(Csts.camy))|];
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 = Math.ln_b 10 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 + !(Csts.camx), y+len + !(Csts.camy)); (x + !(Csts.camx), y + !(Csts.camy))|];
if Array.mem (!n mod 10) [|0; 2; 3; 5; 6; 7; 8; 9|] then
draw_poly_line [|(x + !(Csts.camx), y+len + !(Csts.camy)); (x+len + !(Csts.camx), y+len + !(Csts.camy))|];
if Array.mem (!n mod 10) [|0; 1; 2; 3; 4; 7; 8; 9|] then
draw_poly_line [|(x+len + !(Csts.camx), y+len + !(Csts.camy)); (x+len + !(Csts.camx), y + !(Csts.camy))|];
if Array.mem (!n mod 10) [|2; 3; 4; 5; 6; 8; 9|] then
draw_poly_line [|(x + !(Csts.camx), y + !(Csts.camy)); (x+len + !(Csts.camx), y + !(Csts.camy))|];
if Array.mem (!n mod 10) [|0; 1; 3; 4; 5; 6; 7; 8; 9|] then
draw_poly_line [|(x+len + !(Csts.camx), y-len + !(Csts.camy)); (x+len + !(Csts.camx), y + !(Csts.camy))|];
if Array.mem (!n mod 10) [|0; 2; 3; 5; 6; 8; 9|] then
draw_poly_line [|(x + !(Csts.camx), y-len + !(Csts.camy)); (x+len + !(Csts.camx), y-len + !(Csts.camy))|];
if Array.mem (!n mod 10) [|0; 2; 6; 8|] then
draw_poly_line [|(x + !(Csts.camx), y-len + !(Csts.camy)); (x + !(Csts.camx), y + !(Csts.camy))|];
n := !n/10;
cur_x := !cur_x - (len*11/7);
done ;;
let decode_letter x y len arr =
set_line_width 3;
if arr.(0) = 1 then
draw_poly_line [|(x, y+len); (x, y)|];
if arr.(1) = 1 then
draw_poly_line [|(x, y-len); (x, y)|];
if arr.(2) = 1 then
draw_poly_line [|(x, y+len); (x+len, y+len)|];
if arr.(3) = 1 then
draw_poly_line [|(x, y+len); (x+len, y)|];
if arr.(4) = 1 then
draw_poly_line [|(x, y); (x+len, y+len)|];
if arr.(5) = 1 then
draw_poly_line [|(x, y); (x+len, y)|];
if arr.(6) = 1 then
draw_poly_line [|(x, y); (x+len, y-len)|];
if arr.(7) = 1 then
draw_poly_line [|(x, y-len); (x+len, y)|];
if arr.(8) = 1 then
draw_poly_line [|(x+len, y-len); (x, y-len)|];
if arr.(9) = 1 then
draw_poly_line [|(x+len, y+len); (x+len, y)|];
if arr.(10) = 1 then
draw_poly_line [|(x+len, y-len); (x+len, y)|];;
let draw_letter x y c len = match c with
|'a'|'A' -> decode_letter x y len [|1; 1; 1; 0; 0; 1; 0; 0; 0; 1; 1|]
|'b'|'B' -> decode_letter x y len [|1; 1; 0; 0; 0; 1; 0; 0; 1; 0; 1|]
|'c'|'C' -> decode_letter x y len [|1; 1; 1; 0; 0; 0; 0; 0; 1; 0; 0|]
|'d'|'D' -> decode_letter x y len [|0; 0; 1; 0; 0; 0; 0; 0; 1; 1; 1|]; draw_poly_line [|(x+len/2, y+len); (x+len/2, y-len)|]
|'e'|'E' -> decode_letter x y len [|1; 1; 1; 0; 0; 1; 0; 0; 1; 0; 0|]
|'f'|'F' -> decode_letter x y len [|1; 1; 1; 0; 0; 1; 0; 0; 0; 0; 0|]
|'g'|'G' -> decode_letter x y len [|1; 1; 1; 0; 0; 0; 0; 0; 1; 0; 1|]
|'h'|'H' -> decode_letter x y len [|1; 1; 0; 0; 0; 1; 0; 0; 0; 1; 1|]
|'i'|'I' -> draw_poly_line [|(x+len/2, y+len); (x+len/2, y-len)|];
|'j'|'J' -> decode_letter x y len [|0; 1; 0; 0; 0; 0; 0; 0; 1; 1; 1|]
|'k'|'K' -> decode_letter x y len [|1; 1; 0; 0; 1; 0; 1; 0; 0; 0; 0|]
|'l'|'L' -> decode_letter x y len [|1; 1; 0; 0; 0; 0; 0; 0; 1; 0; 0|]
|'m'|'M' -> decode_letter x y len [|1; 1; 0; 0; 0; 0; 0; 0; 0; 1; 1|]; draw_poly_line [|(x, y+len); (x+len/2, y)|]; draw_poly_line [|(x+len/2, y); (x+len, y+len)|]
|'n'|'N' -> decode_letter x y len [|1; 1; 0; 1; 0; 0; 0; 0; 0; 1; 1|]
|'o'|'O' -> decode_letter x y len [|1; 1; 1; 0; 0; 0; 0; 0; 1; 1; 1|]
|'p'|'P' -> decode_letter x y len [|1; 1; 1; 0; 0; 1; 0; 0; 0; 1; 0|]
|'q'|'Q' -> decode_letter x y len [|1; 0; 1; 0; 0; 1; 0; 0; 0; 1; 1|]
|'r'|'R' -> decode_letter x y len [|1; 1; 1; 0; 0; 1; 1; 0; 0; 1; 0|]
|'s'|'S' -> decode_letter x y len [|1; 0; 1; 0; 0; 1; 0; 0; 1; 0; 1|]
|'t'|'T' -> decode_letter x y len [|1; 1; 0; 0; 0; 1; 0; 0; 1; 0; 0|]
|'u'|'U' -> decode_letter x y len [|1; 1; 0; 0; 0; 0; 0; 0; 1; 1; 1|]
|'v'|'V' -> decode_letter x y len [|1; 1; 0; 0; 0; 0; 0; 1; 0; 1; 0|]
|'w'|'W' -> decode_letter x y len [|1; 1; 0; 0; 0; 0; 1; 1; 0; 1; 1|]
|'x'|'X' -> draw_poly_line [|(x, y+len); (x+len, y-len)|]; draw_poly_line [|(x, y-len); (x+len, y+len)|]
|'y'|'Y' -> decode_letter x y len [|1; 0; 0; 0; 0; 1; 0; 1; 0; 1; 0|]
|'z'|'Z' -> decode_letter x y len [|0; 1; 1; 0; 1; 0; 0; 0; 1; 0; 0|]
| _ -> () ;;
let draw_string x0 y s len =
let cur_x = ref x0 in
for i = 0 to String.length s -1 do
draw_letter !cur_x y s.[i] len;
cur_x := !cur_x + (len*10/7)
done;;

BIN
drawing.o Normal file

Binary file not shown.

BIN
dynamic.cmi Normal file

Binary file not shown.

BIN
dynamic.cmx Normal file

Binary file not shown.

78
dynamic.ml Normal file
View File

@ -0,0 +1,78 @@
exception ReturnInt of int ;;
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_mem (dyn : 'a dynamic) (id : int) =
if id < 0 || id >= dyn.len then begin
Printf.fprintf stderr "(at index %d with len %d) \n" id dyn.len;
failwith "ERROR : invalid access" ;
end;
dyn.tab.(id) ;;
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_remove_id (dyn : 'a dynamic) (id : int) =
assert (id >= 0 && id < dyn.len) ;
let temp = dyn.tab.(dyn.len -1) in
dyn.tab.(dyn.len -1) <- dyn.tab.(id) ;
dyn.tab.(id) <- temp ;
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 ;;

BIN
dynamic.o Normal file

Binary file not shown.

3
execution.sh Normal file
View File

@ -0,0 +1,3 @@
rm *.cmi *.cmx
ocamlfind ocamlopt -linkpkg -package unix -linkpkg -package graphics csts.ml dynamic.ml math.ml drawing.ml menus.ml main.ml -o math
./math

BIN
main.cmi

Binary file not shown.

BIN
main.cmo

Binary file not shown.

BIN
main.cmx Normal file

Binary file not shown.

516
main.ml
View File

@ -2,506 +2,16 @@ open Graphics ;;
Random.self_init () ;;
(* Dynamic getchar function *)
let get1char () =
let termio = Unix.tcgetattr Unix.stdin in
let () =
Unix.tcsetattr Unix.stdin Unix.TCSADRAIN
{ termio with Unix.c_icanon = false } in
let res = input_char stdin in
Unix.tcsetattr Unix.stdin Unix.TCSADRAIN termio;
res
(* Some digit display functions *)
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 delta i j =
if i = j then 1 else 0 ;;
let abs n =
if n > 0 then n else -n ;;
let draw_integer x0 y n0 len =
(* 7-seg display *)
set_line_width (max 1 (len/4));
let n = ref n0 in
let size = ln10 (abs n0) in
let offset = ref (size*(len*11/7)/2) in
let initial_i = ref 1 in
if !n < 0 then begin
offset := (size+1)*(len*11/7)/2;
let x = x0 + !offset - (size+1)*(len*11/7) in
draw_poly_line [|(x-len/2, y); (x+len/2, y)|];
n := !n * (-1);
decr initial_i ;
end;
for i = !initial_i to (size + !initial_i) 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 decode_letter x y len arr =
set_line_width 3;
if arr.(0) = 1 then
draw_poly_line [|(x, y+len); (x, y)|];
if arr.(1) = 1 then
draw_poly_line [|(x, y-len); (x, y)|];
if arr.(2) = 1 then
draw_poly_line [|(x, y+len); (x+len, y+len)|];
if arr.(3) = 1 then
draw_poly_line [|(x, y+len); (x+len, y)|];
if arr.(4) = 1 then
draw_poly_line [|(x, y); (x+len, y+len)|];
if arr.(5) = 1 then
draw_poly_line [|(x, y); (x+len, y)|];
if arr.(6) = 1 then
draw_poly_line [|(x, y); (x+len, y-len)|];
if arr.(7) = 1 then
draw_poly_line [|(x, y-len); (x+len, y)|];
if arr.(8) = 1 then
draw_poly_line [|(x+len, y-len); (x, y-len)|];
if arr.(9) = 1 then
draw_poly_line [|(x+len, y+len); (x+len, y)|];
if arr.(10) = 1 then
draw_poly_line [|(x+len, y-len); (x+len, y)|];;
let draw_letter x y c len = match c with
|'a'|'A' -> decode_letter x y len [|1; 1; 1; 0; 0; 1; 0; 0; 0; 1; 1|]
|'b'|'B' -> decode_letter x y len [|1; 1; 0; 0; 0; 1; 0; 0; 1; 0; 1|]
|'c'|'C' -> decode_letter x y len [|1; 1; 1; 0; 0; 0; 0; 0; 1; 0; 0|]
|'d'|'D' -> decode_letter x y len [|0; 0; 1; 0; 0; 0; 0; 0; 1; 1; 1|]; draw_poly_line [|(x+len/2, y+len); (x+len/2, y-len)|]
|'e'|'E' -> decode_letter x y len [|1; 1; 1; 0; 0; 1; 0; 0; 1; 0; 0|]
|'f'|'F' -> decode_letter x y len [|1; 1; 1; 0; 0; 1; 0; 0; 0; 0; 0|]
|'g'|'G' -> decode_letter x y len [|1; 1; 1; 0; 0; 0; 0; 0; 1; 0; 1|]
|'h'|'H' -> decode_letter x y len [|1; 1; 0; 0; 0; 1; 0; 0; 0; 1; 1|]
|'i'|'I' -> draw_poly_line [|(x+len/2, y+len); (x+len/2, y-len)|];
|'j'|'J' -> decode_letter x y len [|0; 1; 0; 0; 0; 0; 0; 0; 1; 1; 1|]
|'k'|'K' -> decode_letter x y len [|1; 1; 0; 0; 1; 0; 1; 0; 0; 0; 0|]
|'l'|'L' -> decode_letter x y len [|1; 1; 0; 0; 0; 0; 0; 0; 1; 0; 0|]
|'m'|'M' -> decode_letter x y len [|1; 1; 0; 0; 0; 0; 0; 0; 0; 1; 1|]; draw_poly_line [|(x, y+len); (x+len/2, y)|]; draw_poly_line [|(x+len/2, y); (x+len, y+len)|]
|'n'|'N' -> decode_letter x y len [|1; 1; 0; 1; 0; 0; 0; 0; 0; 1; 1|]
|'o'|'O' -> decode_letter x y len [|1; 1; 1; 0; 0; 0; 0; 0; 1; 1; 1|]
|'p'|'P' -> decode_letter x y len [|1; 1; 1; 0; 0; 1; 0; 0; 0; 1; 0|]
|'q'|'Q' -> decode_letter x y len [|1; 0; 1; 0; 0; 1; 0; 0; 0; 1; 1|]
|'r'|'R' -> decode_letter x y len [|1; 1; 1; 0; 0; 1; 1; 0; 0; 1; 0|]
|'s'|'S' -> decode_letter x y len [|1; 0; 1; 0; 0; 1; 0; 0; 1; 0; 1|]
|'t'|'T' -> decode_letter x y len [|1; 1; 0; 0; 0; 1; 0; 0; 1; 0; 0|]
|'u'|'U' -> decode_letter x y len [|1; 1; 0; 0; 0; 0; 0; 0; 1; 1; 1|]
|'v'|'V' -> decode_letter x y len [|1; 1; 0; 0; 0; 0; 0; 1; 0; 1; 0|]
|'w'|'W' -> decode_letter x y len [|1; 1; 0; 0; 0; 0; 1; 1; 0; 1; 1|]
|'x'|'X' -> draw_poly_line [|(x, y+len); (x+len, y-len)|]; draw_poly_line [|(x, y-len); (x+len, y+len)|]
|'y'|'Y' -> decode_letter x y len [|1; 0; 0; 0; 0; 1; 0; 1; 0; 1; 0|]
|'z'|'Z' -> decode_letter x y len [|0; 1; 1; 0; 1; 0; 0; 0; 1; 0; 0|]
| _ -> () ;;
let draw_string x0 y s len =
let cur_x = ref x0 in
for i = 0 to String.length s -1 do
draw_letter !cur_x y s.[i] len;
cur_x := !cur_x + (len*10/7)
done;;
(* Arithmetical functions *)
type calcul =
Val of int |
Plus of calcul * calcul |
Minus of calcul * calcul |
Exp of calcul * int | (* u^n *)
Multiply of calcul * calcul ;;
let print_sign c x y len = match c with
| '+' -> draw_poly_line [|(x, y); (x+len, y)|]; draw_poly_line [|(x+len/2, y+len/2); (x+len/2, y-len/2)|]
| '-' -> draw_poly_line [|(x, y); (x+len, y)|]
| '*' -> draw_poly_line [|(x+len/4, y+len/2); (x+3*len/4, y-len/2)|]; draw_poly_line [|(x+len/4, y-len/2); (x+3*len/4, y+len/2)|]
| '^' -> () (* TODO *)
| '(' ->
moveto (x+len) (y+len+len/5);
set_line_width (max 1 (len/4));
set_color black ;
curveto (x+len/2, y) (x+len/2, y) (x+len, y-len-len/5)
| ')' ->
moveto (x) (y+len+len/5);
set_line_width (max 1 (len/4));
set_color black ;
curveto (x+len/2, y) (x+len/2, y) (x, y-len-len/5)
| _ -> () ;;
let print_math fm x0 y0 size =
let current_x = ref x0 in
let current_y = ref y0 in
let rec aux f = match f with
| Val x ->
current_x := !current_x + size/3;
draw_integer_alignedleft (!current_x) !current_y x size;
current_x := !current_x + (size*(2 + ln10 (abs x)));
current_x := !current_x + size/3
| Plus (a, b) ->
aux a;
print_sign '+' !current_x !current_y size;
current_x := !current_x + size*11/7;
aux b
| Minus (a, b) ->
aux a;
print_sign '-' !current_x !current_y size;
current_x := !current_x + size*11/7;
aux b
| Multiply (a, b) ->
aux a;
print_sign '*' !current_x !current_y size;
current_x := !current_x + size*11/7;
aux b
| Exp (a, n) ->
()
in aux fm ;;
let generate_tier_1 length inf sup =
let rec aux n = match (Random.int 2) with
| 0 -> begin
match n with
| 0 -> Val (1 + Random.int (sup-inf) + inf)
| 1 -> Val (1 + Random.int (sup-inf) + inf)
| k -> Plus (aux (k-1), Val (1 + Random.int (sup-inf) + inf))
end
| 1 -> begin
match n with
| 0 -> Val (1 + Random.int (sup-inf) + inf)
| 1 -> Val (1 + Random.int (sup-inf) + inf)
| k -> Minus (aux (k-1), Val (1 + Random.int (sup-inf) + inf))
end
| _ -> failwith "Never happen"
in aux length ;;
let generate_tier_2 length inf sup mreduction =
let rec aux n = match (Random.int 3) with
| 0 -> begin
match n with
| 0 -> Val (1 + Random.int (sup-inf) + inf)
| 1 -> Val (1 + Random.int (sup-inf) + inf)
| k -> Plus (aux (k-1), Val (1 + Random.int (sup-inf) + inf))
end
| 1 -> begin
match n with
| 0 -> Val (1 + Random.int (sup-inf) + inf)
| 1 -> Val (1 + Random.int (sup-inf) + inf)
| k -> Minus (aux (k-1), Val (1 + Random.int (sup-inf) + inf))
end
| 2 -> begin
match n with
| 0 -> Val (1 + Random.int (sup-inf) + inf)
| 1 -> Val (1 + Random.int (sup-inf) + inf)
| k -> Plus (Multiply (Val ((1 + Random.int (sup-inf) + inf)/mreduction), Val ((1 + Random.int (sup-inf) + inf)/mreduction)), aux (k-2))
end
| _ -> failwith "Never happen"
in aux length ;;
let rec pw x n = match n with
| 0 -> 1
| 1 -> x
| k when k mod 2 = 0 -> let res = pw x (n/2) in res*res
| k -> let res = pw x (n/2) in res*res*x ;;
(* Boi *)
let rec eval_exp fm = match fm with
| Plus (a, b) -> Plus (eval_exp a, eval_exp b)
| Minus (a, b) -> Minus (eval_exp a, eval_exp b)
| Multiply (a, b) -> Multiply (eval_exp a, eval_exp b)
| Val x -> Val x
| Exp (a, n) -> Val (pw (evaluate a) n)
and eval_mult fm = match fm with
| Plus (a, b) -> Plus (eval_mult a, eval_mult b)
| Minus (a, b) -> Minus (eval_mult a, eval_mult b)
| Val x -> Val x
| Exp (a, n) -> Exp(eval_mult a, n)
| Multiply (a, b) -> Val ((evaluate a) * (evaluate b))
and eval_plus fm = match fm with
| Val x -> x
| Plus (a, b) -> (evaluate a) + (evaluate b)
| Minus (a, b) -> (evaluate a) - (evaluate b)
| Exp (a, n) -> failwith "_Impossible"
| Multiply (a, b) -> failwith "Impossible_"
and evaluate fm =
eval_plus (eval_mult (eval_exp fm)) ;;
(* Game config *)
exception Exit ;;
let update_char_settings code buf pointer ndiff = match code with
| k when k >= 48 && k <= 57 ->
(* Integer *)
if !buf >= 0 then begin
buf := !buf * 10;
buf := !buf + code - 48;
end
else begin
buf := !buf * (-1);
buf := !buf * 10;
buf := !buf + code - 48;
buf := !buf * (-1);
end;
true
| 10 ->
raise Exit
| 115 ->
(* s *)
set_color white;
fill_circle 20 (800 - !pointer * 90) 10;
pointer := (!pointer + 1) mod ndiff;
set_color (rgb 32 192 32);
fill_circle 20 (800 - !pointer * 90) 10;
false
| 122 ->
(* z *)
set_color white;
fill_circle 20 (800 - !pointer * 90) 10;
decr pointer;
if !pointer < 0 then pointer := ndiff -1;
set_color (rgb 32 192 32);
fill_circle 20 (800 - !pointer * 90) 10;
false
| 127 ->
(* Delete *)
if !buf >= 0 then begin
buf := !buf / 10
end
else begin
buf := !buf * (-1);
buf := !buf / 10;
buf := !buf * (-1);
end;
true
| _ -> false ;;
type game_setting = {mutable inf : int; mutable sup : int; mutable diff : int; mutable count : int} ;;
type modifiers = {mutable brackets : bool; mutable timed : bool} ;;
let settings_menu () =
open_graph " 1000x1000";
set_window_title "Math";
let setting = {inf = 1 ; sup = 100 ; diff = 1; count = 8} in
let ft = ref true in
try
Stdlib.print_endline "-------------------------";
let ptr = ref 0 in
let buffer = ref 0 in
while true do
let c = get1char () in
let code = Char.code c in
if !ft || update_char_settings code buffer ptr 4 then begin
ft := false;
if !ptr = 0 then
setting.inf <- !buffer
else if !ptr = 1 then
setting.sup <- !buffer
else if !ptr = 2 then
setting.diff <- !buffer
else if !ptr = 3 then
setting.count <- !buffer;
open_graph " 1000x1000";
set_window_title "Math";
set_color (rgb 32 192 32);
fill_circle 20 (800 - !ptr * 90) 10;
set_color black;
(*draw_string 10 950 "abcdefghijklmnopqrstuvwxyz" 20; *)
draw_string 40 800 "min value" 20;
draw_integer_alignedleft 400 800 setting.inf 20;
draw_string 40 710 "max value" 20;
draw_integer_alignedleft 400 710 setting.sup 20;
draw_string 40 620 "difficulty" 20;
draw_integer_alignedleft 400 620 setting.diff 20;
draw_string 40 530 "num count" 20;
draw_integer_alignedleft 400 530 setting.count 20;
end;
set_color black;
done;
failwith "Not possible"
with
| Exit -> setting ;;
(* Core functions *)
(* Main *)
let update_char_main code buf = match code with
| k when k >= 48 && k <= 57 ->
(* Integer *)
if !buf >= 0 then begin
buf := !buf * 10;
buf := !buf + code - 48;
end
else begin
buf := !buf * (-1);
buf := !buf * 10;
buf := !buf + code - 48;
buf := !buf * (-1);
end;
true
| 45 ->
(* Minus sign *)
buf := !buf * (-1); true
| 127 ->
(* Delete *)
if !buf >= 0 then begin
buf := !buf / 10
end
else begin
buf := !buf * (-1);
buf := !buf / 10;
buf := !buf * (-1);
end;
true
| _ ->
false ;;
let main stng =
open_graph " 1000x1000";
set_window_title "Math";
let buffer = ref 0 in
let ft = ref true in
try
let math = ref (generate_tier_2 stng.count stng.inf stng.sup 5) in
let answer = ref (evaluate !math) in
let clock = ref 0 in
let frames = ref 0 in
while true do
let ch = get1char () in
let chint = Char.code ch in
if !ft || update_char_main chint buffer then begin
ft := false;
open_graph " 1000x1000";
set_window_title "Math";
if !answer = !buffer then begin
math := (generate_tier_2 6 1 100 5);
answer := evaluate !math;
buffer := 0;
end;
print_math !math 10 900 15;
draw_integer_alignedleft 10 800 !answer 15;
draw_integer_alignedleft 10 300 !buffer 20;
end;
Unix.sleepf 0.025;
incr frames;
if !frames >= 40 then begin
Stdlib.print_endline "EEE";
frames := 0;
incr clock;
set_color white;
draw_poly_line [|(0, 0); (1000, 0); (1000, 60); (0, 60)|];
set_color black;
draw_integer 500 30 !clock 30;
end;
done;
with
| exn -> close_graph (); raise exn ;;
let setting = settings_menu () ;;
main setting ;;
(* ocamlfind ocamlc -linkpkg -package unix -linkpkg -package graphics main.ml *)
let mainloop () =
open_graph Csts.open_string ;
set_window_title "Maeth";
while true do
auto_synchronize false ;
clear_graph () ;
Menus.print_current_interface () ;
auto_synchronize true ;
Menus.action_on_interface () ;
Unix.sleepf Csts.sleep_d
done ;;
mainloop () ;;

BIN
main.o Normal file

Binary file not shown.

BIN
math Executable file

Binary file not shown.

BIN
math.cmi Normal file

Binary file not shown.

BIN
math.cmx Normal file

Binary file not shown.

34
math.ml Normal file
View File

@ -0,0 +1,34 @@
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 ln_b b n = match n with
| k when k < 0 -> failwith "Are you sure about that ?"
| k when k < b -> 0
| k -> 1 + ln_b b (k/b) ;;
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);;

BIN
math.o Normal file

Binary file not shown.

BIN
menus.cmi Normal file

Binary file not shown.

BIN
menus.cmx Normal file

Binary file not shown.

209
menus.ml Normal file
View File

@ -0,0 +1,209 @@
open Graphics ;;
exception MenuExit ;;
let current_button_index = ref 0
and current_interface_index = ref 0 ;;
type 'a value_changer = {
ptr : 'a ref ;
min : 'a ;
max : 'a ;
pad : 'a ;
} ;;
type action = Nothing | Tweak of int value_changer | Warp of int
and button = {
id : int ;
text : string ;
pos : Csts.rect ;
red : int ;
green : int ;
blue : int ;
actn : action
}
and interface = {
index : int ;
title : string ;
red : int ;
green : int ;
blue : int ;
mutable bts : button list ;
} ;; (* circular definitions goes brrr *)
let default_button = {
id = -1 ;
text = "Empty" ;
pos = Csts.default_rect ;
red = 128 ;
green = 128 ;
blue = 128 ;
actn = Nothing ;
} ;;
let default_interface = {
index = -1 ;
title = "Empty" ;
red = 128 ;
green = 128 ;
blue = 128 ;
bts = []
} ;;
(* --------------------------------------------------------------------------------------------------------------------------------------------- *)
let arr_buttons = Dynamic.dyn_create default_button ;;
let arr_interfaces = Dynamic.dyn_create default_interface ;;
(* --------------------------------------------------------------------------------------------------------------------------------------------- *)
(* init *)
let init_button () =
let res = {
id = !current_button_index ;
text = "Empty" ;
pos = Csts.default_rect ;
red = 128 ;
green = 128 ;
blue = 128 ;
actn = Nothing ;
} in
Dynamic.dyn_add arr_buttons res ;
incr current_button_index ;;
let build_button (text : string) (r : Csts.rect) (red : int) (green : int) (blue : int) (ac : action) =
let res = {
id = !current_button_index ;
text = text ;
pos = r ;
red = red ;
green = green ;
blue = blue ;
actn = ac
} in
Dynamic.dyn_add arr_buttons res ;
incr current_button_index ;;
let init_interface () =
let res = {
index = -1 ;
title = "Empty" ;
red = 128 ;
green = 128 ;
blue = 128 ;
bts = []
} in
Dynamic.dyn_add arr_interfaces res ;
incr current_interface_index ;;
let build_empty_interface (title : string) (red : int) (green : int) (blue : int) =
let res = {
index = !current_interface_index ;
title = title ;
red = 128 ;
green = 128 ;
blue = 128 ;
bts = []
} in
Dynamic.dyn_add arr_interfaces res ;
incr current_interface_index ;;
let build_interface (title : string) (red : int) (green : int) (blue : int) (butts : button list) =
let res = {
index = !current_interface_index ;
title = title ;
red = 128 ;
green = 128 ;
blue = 128 ;
bts = butts ; (* please *)
} in
Dynamic.dyn_add arr_interfaces res ;
incr current_interface_index ;;
(* --------------------------------------------------------------------------------------------------------------------------------------------- *)
let current_it_id = ref 0 ;;
(* --------------------------------------------------------------------------------------------------------------------------------------------- *)
(* additions *)
let add_button_to_interface (it : int) (b_id : int) =
let interf = Dynamic.dyn_mem arr_interfaces it in
interf.bts <- (Dynamic.dyn_mem arr_buttons b_id)::(interf.bts) ;;
let add_button_to_current (b_id : int) =
let interf = Dynamic.dyn_mem arr_interfaces !current_it_id in
interf.bts <- (Dynamic.dyn_mem arr_buttons b_id)::(interf.bts) ;;
(* --------------------------------------------------------------------------------------------------------------------------------------------- *)
(* printing *)
let print_button (b : button) =
set_color (rgb b.red b.green b.blue) ;
fill_rect b.pos.x b.pos.y b.pos.w b.pos.h ;
set_color (rgb (255 - b.red) (255 - b.green) (255 - b.blue)) ;
set_line_width 2 ;
Drawing.draw_string (b.pos.x+3) (b.pos.y + b.pos.h/2) b.text (min (3*b.pos.h/4-2) ((7*(b.pos.w*3/4-4)/(max 1 (String.length b.text)))/10)) ;;
let print_interface (it : interface) =
List.iter print_button it.bts ;
Drawing.draw_string 20 (Csts.__height__ - 40) it.title 30 ;;
let print_current_interface () =
let interf = Dynamic.dyn_mem arr_interfaces !current_it_id in
List.iter print_button interf.bts ;
Drawing.draw_string 20 (Csts.__height__ - 40) interf.title 30 ;;
(* --------------------------------------------------------------------------------------------------------------------------------------------- *)
(* actions *)
let is_within (r : Csts.rect) (x : int) (y : int) =
r.x <= x && r.y < y && x <= r.x + r.w && y <= r.y + r.h ;;
let move_interface (b : button) = match b.actn with
| Nothing -> ()
| Tweak (vc) -> begin
let halted = ref false in
while not !halted do
(* todo *)()
done
end
| Warp ne -> if ne = -1 then raise MenuExit else current_it_id := ne ;;
let action_on_button (mox : int) (moy : int) (b : button) =
if is_within b.pos mox moy then begin
(*Printf.printf "clicked\n" ;*)
move_interface b ;
true
end
else
false ;;
let action_on_interface () =
if button_down () then begin
let (mox, moy) = mouse_pos () in
let rec aux = function
| [] -> ()
| b::t ->
if action_on_button mox moy b then () else aux t
in
aux (Dynamic.dyn_mem arr_interfaces !current_it_id).bts
end ;;
(* --------------------------------------------------------------------------------------------------------------------------------------------- *)
(* Define the menu there *)
build_empty_interface "Main Menu" 128 128 128 ;;
build_empty_interface "Options " 32 32 32 ;;
build_button "Options" {x = Csts.__width__/2 - 150; y = 160; w = 300; h = 100} 255 32 255 (Warp 1) ;;
build_button "Exit" {x = Csts.__width__/2 - 150; y = 50; w = 300; h = 100} 1 1 1 (Warp (-1)) ;;
build_button "Operations" {x = Csts.__width__/2 - 150; y = 380; w = 300; h = 100} 255 32 32 Nothing ;;
build_button "Time" {x = Csts.__width__/2 - 150; y = 270; w = 300; h = 100} 32 255 32 Nothing ;;
build_button "Difficulty" {x = Csts.__width__/2 - 150; y = 160; w = 300; h = 100} 32 32 255 Nothing ;;
build_button "Back" {x = Csts.__width__/2 - 150; y = 50; w = 300; h = 100} 32 32 32 (Warp 0) ;;
(*Printf.printf "(B : %d ; I : %d)\n" arr_buttons.len arr_interfaces.len ;;*)
add_button_to_interface 0 0 ;
add_button_to_interface 0 1 ;
add_button_to_interface 1 2 ;
add_button_to_interface 1 3 ;
add_button_to_interface 1 4 ;
add_button_to_interface 1 5 ;

BIN
menus.o Normal file

Binary file not shown.