added math formula generation (v1)

This commit is contained in:
Alexandre 2024-12-23 21:23:36 +01:00
parent ad821ca28f
commit 262b48f93f
27 changed files with 174 additions and 21 deletions

View File

@ -1,2 +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
ocamlfind ocamlopt -linkpkg -package unix -linkpkg -package graphics csts.ml dynamic.ml math.ml drawing.ml menus.ml maeth.ml main.ml -o math

BIN
csts.cmi

Binary file not shown.

BIN
csts.cmx

Binary file not shown.

View File

@ -27,4 +27,8 @@ let sleep_d = 0.01 ;;
(* math *)
let difficulty = ref 1 ;;
let calc_length = ref 3 ;;
let time_to_ans = ref 10 ;;
let time_to_ans = ref 10 ;;
let score = ref 0
and combo = ref 0
and max_combo = ref 0 ;;

BIN
csts.o

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,7 @@
open Graphics ;;
let fodder = ref 0 ;;
let draw_integer x0 y n0 r =
let draw_integer ?retval:(rv=fodder) x0 y n0 r =
(* 7-seg display *)
let n = ref n0 in
let size = Math.ln_b 10 n0 in
@ -30,9 +31,10 @@ let draw_integer x0 y n0 r =
draw_poly_line [|(x-len/2 + !(Csts.camx), y-len + !(Csts.camy)); (x-len/2 + !(Csts.camx), y + !(Csts.camy))|];
n := !n/10;
done ;;
done ;
rv := x0 + offset + size*(len*11/7) ;;
let draw_integer_alignedleft x0 y n0 len =
let draw_integer_alignedleft ?retval:(rv=fodder) x0 y n0 len =
(* 7-seg display 2 *)
set_line_width (max 1 (len/4));
let n = ref n0 in
@ -71,7 +73,8 @@ let draw_integer_alignedleft x0 y n0 len =
n := !n/10;
cur_x := !cur_x - (len*11/7);
done ;;
done ;
rv := (x0 + (size+1)*(len*11/7)) ;;
let decode_letter x y len arr =
set_line_width 3;

BIN
drawing.o

Binary file not shown.

Binary file not shown.

BIN
dynamic.o

Binary file not shown.

View File

@ -1,3 +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
ocamlfind ocamlopt -linkpkg -package unix -linkpkg -package graphics csts.ml dynamic.ml math.ml drawing.ml menus.ml maeth.ml main.ml -o math
./math

BIN
maeth.cmi Normal file

Binary file not shown.

BIN
maeth.cmx Normal file

Binary file not shown.

120
maeth.ml Normal file
View File

@ -0,0 +1,120 @@
open Graphics ;;
Random.self_init () ;;
type operation =
Val of int |
Sum of operation * operation |
Diff of operation * operation |
Prod of operation * operation |
Exp of operation * int ;;
let rec calculate = function
| Val k -> k
| Exp (op, k) -> Math.pw (calculate op) k
| Sum (f, g) -> (calculate f) + (calculate g)
| Diff (f, g) -> (calculate f) - (calculate g)
| Prod (f, g) -> (calculate f) * (calculate g) ;;
let generate_random_calc ?plus_w:(pw=10) ?minus_w:(mw=8) ?prod_w:(uw=2) ?exp_w:(ew=0) (length : int) (inf : int) (sup : int) =
let sum = pw + mw + uw + ew in
let rec aux = function
| 0 | 1 ->
Val (inf + Random.int (sup - inf))
| k ->
let r = Random.int sum in
if r < pw then begin
if Random.int 2 = 0 then
Sum(aux 0, aux (k-1))
else
Sum(aux (k-1), aux 0)
end
else if r < pw+mw then begin
if Random.int 2 = 0 then
Diff(aux 0, aux (k-1))
else
Diff(aux (k-1), aux 0)
end
else if r < pw+mw+uw then begin
if Random.int 2 = 0 then
Prod(aux 0, aux (k-1))
else
Prod(aux (k-1), aux 0)
end
else begin
Exp(aux (k-1), 2 + Random.int 2)
end
in
aux length ;;
let draw_bracket_open ?retval:(rv=Drawing.fodder) (x : int) (y : int) (size : int) =
moveto (x + size/4) (y+5*size/4) ;
lineto (x) (y+size/2) ;
lineto (x) (y-size/2) ;
lineto (x + size/4) (y-5*size/4) ;
rv := x + size/4 +6 ;;
let draw_bracket_close ?retval:(rv=Drawing.fodder) (x : int) (y : int) (size : int) =
moveto (x) (y+5*size/4) ;
lineto (x + size/4) (y+size/2) ;
lineto (x + size/4) (y-size/2) ;
lineto (x) (y-5*size/4) ;
rv := x + size/4 +6 ;;
let draw_sign ?retval:(rv=Drawing.fodder) (x : int) (y : int) (len : int) = function
| '+' ->
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)|] ;
| 'x' ->
Drawing.draw_letter x y 'x' len ;
| _ -> failwith "incorrect\n" ;;
let require_bracket = function
| Val _ -> false
| _ -> true ;;
let print_calc (f : operation) (x0 : int) (y0 : int) (size : int) =
set_line_width 3 ;
set_color black ;
let x = ref x0 in
let rec aux = function
| Val k ->
Drawing.draw_integer_alignedleft !x y0 k size ~retval:x ;
(*Printf.printf "%d --> \n" !x ;*)
| Exp (f, k) -> ()
| Sum (f, g) ->
if require_bracket f then draw_bracket_open !x y0 size ~retval:x ;
aux f ;
if require_bracket f then draw_bracket_close !x y0 size ~retval:x ;
draw_sign !x y0 size '+' ~retval:x ;
x := !x + size*10/7 ;
if require_bracket g then draw_bracket_open !x y0 size ~retval:x ;
aux g ;
if require_bracket g then draw_bracket_close !x y0 size ~retval:x ;
| Diff (f, g) ->
if require_bracket f then draw_bracket_open !x y0 size ~retval:x ;
aux f ;
if require_bracket f then draw_bracket_close !x y0 size ~retval:x ;
draw_sign !x y0 size '-' ~retval:x ;
x := !x + size*10/7 ;
if require_bracket g then draw_bracket_open !x y0 size ~retval:x ;
aux g ;
if require_bracket g then draw_bracket_close !x y0 size ~retval:x ;
| Prod (f, g) ->
if require_bracket f then draw_bracket_open !x y0 size ~retval:x ;
aux f ;
if require_bracket f then draw_bracket_close !x y0 size ~retval:x ;
draw_sign !x y0 (size/2) 'x' ~retval:x ;
x := !x + size*10/7 ;
if require_bracket g then draw_bracket_open !x y0 size ~retval:x ;
aux g ;
if require_bracket g then draw_bracket_close !x y0 size ~retval:x ;
in
aux f ;;

BIN
maeth.o Normal file

Binary file not shown.

BIN
main.cmi

Binary file not shown.

BIN
main.cmx

Binary file not shown.

27
main.ml
View File

@ -1,17 +1,26 @@
open Graphics ;;
Random.self_init () ;;
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 ;;
try
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 ;
()
with
| Menus.MenuStart ->
clear_graph () ;
Maeth.print_calc (Maeth.generate_random_calc 8 1 20) (10) (Csts.__height__/2) 20 ;
while true do
Unix.sleepf Csts.sleep_d
done ;;
mainloop () ;;

BIN
main.o

Binary file not shown.

BIN
math

Binary file not shown.

BIN
math.cmx

Binary file not shown.

BIN
math.o

Binary file not shown.

BIN
menus.cmi

Binary file not shown.

BIN
menus.cmx

Binary file not shown.

View File

@ -1,5 +1,6 @@
open Graphics ;;
exception MenuExit ;;
exception MenuStart ;;
let current_button_index = ref 0
and current_interface_index = ref 0 ;;
@ -145,6 +146,12 @@ let add_button_to_current (b_id : int) =
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 draw_closest (r : int) (g : int) (b : int) =
if r+g+b <= 384 then
set_color white
else
set_color black ;;
let print_button (b : button) =
let (mx, my) = mouse_pos () in
if is_within b.pos mx my then begin
@ -153,17 +160,19 @@ let print_button (b : button) =
end;
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)) ;
draw_closest b.red b.green 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 ;
set_color black ;
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 ;
set_color black ;
Drawing.draw_string 20 (Csts.__height__ - 40) interf.title 30 ;;
(* --------------------------------------------------------------------------------------------------------------------------------------------- *)
@ -186,7 +195,7 @@ let move_interface (b : button) = match b.actn with
fill_rect (3*Csts.__width__/10) (3*Csts.__height__/10) (2*Csts.__width__/5) (2*Csts.__height__/5) ;
set_color white ;
Drawing.draw_string_centered (Csts.__width__/2) (13*Csts.__height__/20) b.text 20 ;
Drawing.draw_integer (5+Csts.__width__/2) (Csts.__height__/2) !(val_ptr.ptr) 40 ;
Drawing.draw_integer (5+Csts.__width__/2) (Csts.__height__/2) !(val_ptr.ptr) 60 ;
Drawing.draw_string (5+3*Csts.__width__/10) (11*Csts.__height__/20) "Min" 20 ;
Drawing.draw_integer_alignedleft (5+3*Csts.__width__/10) (Csts.__height__/2) val_ptr.min 18 ;
Drawing.draw_string (7*Csts.__width__/10-5-3*20*10/7) (11*Csts.__height__/20) "Max" 20 ;
@ -200,7 +209,13 @@ let move_interface (b : button) = match b.actn with
| _ -> ()
done
end
| Warp ne -> if ne = -1 then raise MenuExit else current_it_id := ne ;;
| Warp ne ->
if ne = -1 then
raise MenuExit
else if ne = -2 then
raise MenuStart
else
current_it_id := ne ;;
let action_on_button (mox : int) (moy : int) (b : button) =
if is_within b.pos mox moy then begin
@ -237,6 +252,7 @@ let action_on_interface () =
build_empty_interface "Main Menu" 128 128 128 ;;
build_empty_interface "Options " 32 32 32 ;;
build_button "Start" {x = Csts.__width__/2 - 150; y = 270; w = 300; h = 100} 32 255 32 (Warp (-2)) ;;
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 "Length" {x = Csts.__width__/2 - 150; y = 380; w = 300; h = 100} 255 32 32 (Tweak (build_tweak Csts.calc_length 2 20 1)) ;;
@ -247,7 +263,8 @@ build_button "Back" {x = Csts.__width__/2 - 150; y = 50; w = 300; h = 100}
(*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 0 2 ;
add_button_to_interface 1 3 ;
add_button_to_interface 1 4 ;
add_button_to_interface 1 5 ;
add_button_to_interface 1 5 ;
add_button_to_interface 1 6 ;

BIN
menus.o

Binary file not shown.