1
(***********************************************************************)
5
(* Pierre Weis, projet Cristal, INRIA Rocquencourt *)
7
(* Copyright 2001 Institut National de Recherche en Informatique et *)
8
(* en Automatique. All rights reserved. This file is distributed *)
9
(* only by permission. *)
11
(***********************************************************************)
17
auto_synchronize true;;
30
discus : discus option array;
34
let wood_color = black;;
35
let text_color = black;;
37
let pin_width = (size_x () / 5);;
39
let wood_width = 1 + 2 * 5;;
41
let half_pin_width = (pin_width - wood_width) / 2;;
43
let text_size_x s = let x, _ = text_size s in x;;
44
let text_size_y s = let _, y = text_size s in y;;
46
let pin_height, wood_height, baseline, vtab =
47
let y = text_size_y "Graphics" in
49
let pin_height = size_y () - 8 * y in
50
pin_height, pin_height, vtab 5, vtab;;
53
let eps = size_x () / 10 in
54
let h = half_pin_width in
55
eps + h + (i - 1) * (eps + 2 * h);;
57
let empty_pin i nb_discus =
59
discus = Array.make nb_discus None;
64
let colors = [| black; red; green; blue; yellow; cyan; magenta |] in
68
let x = x - ((wood_width - 1) / 2) in
70
fill_rect x y wood_width pin_height;;
72
let make_discus pin nb_discus i =
73
let inc = half_pin_width / nb_discus in
75
let h1 = pin_height / (nb_discus + 1) in
76
min h1 (3 * wood_width) in
79
let inc = half_pin_width / nb_discus in
80
let hwr = (nb_discus - i) * inc in
82
let w = wr + 2 * r0 in
83
let cur_bg = get_image 0 0 w (wood_height) in
85
let bg = get_image 0 0 w h in
86
let c = make_color i in
91
fill_circle (x0 + wr) r0 r0;
92
let fg = get_image 0 0 w h in
93
let x = pin.xt - w / 2 in
94
let y = baseline + i * h in
95
let discus = { x = x; y = y; w = w; h = h; bg = bg; fg = fg} in
96
draw_image cur_bg 0 0;
99
let full_pin i nb_discus =
100
let t = empty_pin i nb_discus in
101
for i = 0 to nb_discus - 1 do
102
t.discus.(i) <- Some (make_discus t nb_discus i)
104
t.summit <- nb_discus - 1;
108
let s = pin.summit in
110
match pin.discus.(s) with
111
| None -> assert false
113
draw_image discus.bg discus.x discus.y;
114
pin.discus.(s) <- None;
118
let push_discus pin discus =
119
pin.summit <- pin.summit + 1;
120
let s = pin.summit in
121
let x = pin.xt - (discus.w / 2) in
123
if s = 0 then baseline else
124
match pin.discus.(s - 1) with
125
| None -> assert false
126
| Some d -> d.y + discus.h in
129
draw_image discus.fg discus.x discus.y;
130
pin.discus.(pin.summit) <- Some discus;;
132
let move (start_name, start) (destination_name, destination) =
133
let discus = pop_discus start in
134
push_discus destination discus;;
137
draw_wood t.xt baseline;
138
let discus = t.discus in
139
for i = t.summit downto 0 do
140
match discus.(i) with
142
| Some d -> draw_image d.fg d.x d.y;
145
let center_text s x y =
146
let trans = text_size_x s / 2 in
147
moveto (x - trans) y;
151
(name_left, left) (name_midle, midle) (name_right, right) =
152
let baseline = vtab 1 in
153
set_color text_color;
154
center_text name_left left.xt baseline;
155
center_text name_midle midle.xt baseline;
156
center_text name_right right.xt baseline;
157
center_text title midle.xt (vtab 3);
163
print_string "Press return to continue"; print_newline ();
164
ignore (read_line ());;
166
let rec hanoi height start temp destination =
169
hanoi (height - 1) start destination temp;
171
Printf.printf "Movement from %s to %s\n" (fst start) (fst destination);
172
move start destination;
173
hanoi (height - 1) temp start destination
178
let left = ("A", full_pin 1 nb_discus)
179
and midle = ("B", empty_pin 2 nb_discus)
180
and right = ("C", empty_pin 3 nb_discus) in
181
print_game "Lucas productions present" left midle right;
182
hanoi nb_discus left midle right;;
184
if !Sys.interactive then () else begin
185
let l = Array.length Sys.argv in
187
prerr_endline "Usage: hanoi <number of discusses>";
189
game (int_of_string (Sys.argv.(1)));