2016-08-01 13:15:17 +00:00
|
|
|
|
|
|
|
let open Printf in
|
|
|
|
let debug = fprintf stderr in
|
|
|
|
|
|
|
|
let checkpoint_ray = 600 in
|
|
|
|
|
|
|
|
let module Vector = struct
|
|
|
|
type t = {
|
|
|
|
x : int;
|
2016-08-06 23:00:26 +00:00
|
|
|
y : int
|
2016-08-01 13:15:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let to_string dst : string =
|
2016-08-06 23:00:26 +00:00
|
|
|
(Printf.sprintf "{ x = %d ; y = %d }" dst.x dst.y)
|
2016-08-01 13:15:17 +00:00
|
|
|
|
|
|
|
let create x y =
|
|
|
|
{ x ; y }
|
|
|
|
|
|
|
|
let equal dst src =
|
2016-08-06 23:00:26 +00:00
|
|
|
(dst.x = src.x) && (dst.y = src.y)
|
|
|
|
|
2016-08-01 13:15:17 +00:00
|
|
|
let diff dst src =
|
|
|
|
{ x = (dst.x - src.x) ;
|
2016-08-06 23:00:26 +00:00
|
|
|
y = (dst.y - src.y)
|
2016-08-01 13:15:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let mult src a =
|
|
|
|
{ x = src.x * a ;
|
2016-08-06 23:00:26 +00:00
|
|
|
y = src.y * a
|
2016-08-01 13:15:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let add dst src =
|
|
|
|
{ x = (src.x + dst.x) ;
|
2016-08-06 23:00:26 +00:00
|
|
|
y = (src.y + dst.y)
|
2016-08-01 13:15:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let distance (dst:t) (src:t) =
|
|
|
|
(src.x - dst.x) * (src.x - dst.x) + (src.y - dst.y) * (src.y - dst.y)
|
|
|
|
|> float_of_int
|
|
|
|
|> sqrt
|
|
|
|
|> int_of_float
|
|
|
|
|
2016-08-06 23:00:26 +00:00
|
|
|
let is_touching dst src =
|
2016-08-01 13:15:17 +00:00
|
|
|
(distance dst src) < (checkpoint_ray / 2)
|
2016-08-06 23:00:26 +00:00
|
|
|
|
2016-08-01 13:15:17 +00:00
|
|
|
let is_near dst src =
|
|
|
|
(distance dst src) < (checkpoint_ray * 2)
|
|
|
|
|
|
|
|
let is_far dst src =
|
|
|
|
((distance dst src) >= checkpoint_ray * 6)
|
|
|
|
end in
|
|
|
|
|
|
|
|
let module Pod = struct
|
|
|
|
type t = {
|
2016-08-06 23:00:26 +00:00
|
|
|
mutable id : int ;
|
2016-08-01 13:15:17 +00:00
|
|
|
mutable pos : Vector.t ;
|
|
|
|
mutable dir : Vector.t ;
|
2016-08-06 23:00:26 +00:00
|
|
|
mutable has_boost : bool ;
|
|
|
|
mutable checkpoint_pos : Vector.t ;
|
|
|
|
mutable checkpoint_dist : int ;
|
|
|
|
mutable checkpoint_angle : int ;
|
|
|
|
mutable output_str : string
|
|
|
|
}
|
|
|
|
|
2016-08-01 13:15:17 +00:00
|
|
|
let create () =
|
2016-08-06 23:00:26 +00:00
|
|
|
{
|
|
|
|
id = 0 ;
|
|
|
|
pos = Vector.create 0 0 ;
|
|
|
|
dir = Vector.create 0 0 ;
|
|
|
|
has_boost = true ;
|
|
|
|
checkpoint_pos = Vector.create 0 0 ;
|
|
|
|
checkpoint_dist = 0 ;
|
|
|
|
checkpoint_angle = 0 ;
|
|
|
|
output_str = ""
|
2016-08-01 13:15:17 +00:00
|
|
|
}
|
2016-08-06 23:00:26 +00:00
|
|
|
|
|
|
|
let use_boost pod =
|
|
|
|
pod.has_boost <- false
|
|
|
|
|
|
|
|
let update pod (pos, checkpoint_pos, checkpoint_dist, checkpoint_angle) =
|
|
|
|
pod.pos <- pos ;
|
|
|
|
pod.checkpoint_pos <- checkpoint_pos ;
|
|
|
|
pod.checkpoint_dist <- checkpoint_dist ;
|
|
|
|
pod.checkpoint_angle <- checkpoint_angle ;
|
|
|
|
pod
|
|
|
|
|
|
|
|
|
2016-08-01 13:15:17 +00:00
|
|
|
end in
|
|
|
|
|
|
|
|
let module CheckpointList = struct
|
2016-08-06 23:00:26 +00:00
|
|
|
type t = {
|
|
|
|
mem: Vector.t list ;
|
|
|
|
cur: Vector.t option
|
|
|
|
}
|
|
|
|
|
|
|
|
let add ck_li elem =
|
|
|
|
match ck_li.cur with
|
|
|
|
| None ->
|
|
|
|
{
|
|
|
|
mem = [] ;
|
|
|
|
cur = Some elem
|
|
|
|
}
|
|
|
|
| Some cur_elem ->
|
|
|
|
if (Vector.equal cur_elem elem) then
|
|
|
|
ck_li
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mem = cur_elem :: ck_li.mem ;
|
|
|
|
cur = Some elem
|
2016-08-01 13:15:17 +00:00
|
|
|
}
|
2016-08-06 23:00:26 +00:00
|
|
|
|
|
|
|
let create () =
|
|
|
|
{ mem = [] ;
|
|
|
|
cur = None
|
|
|
|
}
|
|
|
|
|
|
|
|
let inc (ck_li:t) elem =
|
|
|
|
(ck_li.mem)
|
|
|
|
|> List.map (fun cur -> (Vector.equal elem cur))
|
|
|
|
|> List.fold_left (fun acc elem -> acc || elem) false
|
|
|
|
|
|
|
|
end in
|
|
|
|
|
|
|
|
let module Game = struct
|
|
|
|
type t = {
|
|
|
|
pods : Pod.t array ;
|
|
|
|
opponents : Pod.t array ;
|
|
|
|
ticks : int ;
|
|
|
|
}
|
|
|
|
end in
|
|
|
|
|
|
|
|
let module Strategy = struct
|
|
|
|
let apply game pod =
|
|
|
|
if !first_turn then begin
|
|
|
|
old_pod := pod ;
|
|
|
|
first_turn := false
|
|
|
|
end ;
|
|
|
|
let movement = Vector.diff pod !old_pod in
|
|
|
|
|
|
|
|
if (CheckpointList.inc !checkpoint_list checkpoint) then begin
|
|
|
|
prerr_endline "List already includes this checkpoint" ;
|
|
|
|
end else begin
|
|
|
|
checkpoint_list := (CheckpointList.add !checkpoint_list checkpoint) ;
|
|
|
|
fprintf stderr "New checkpoint : %s\n%!" (Vector.to_string checkpoint);
|
|
|
|
end ;
|
|
|
|
|
|
|
|
(* output "x y thrust" : the target position + the power *)
|
|
|
|
let is_aligned = checkpoint_angle > -2 && checkpoint_angle < 2 in
|
|
|
|
let is_near_aligned =
|
|
|
|
(checkpoint_angle > -15 && checkpoint_angle <= -2) ||
|
|
|
|
(checkpoint_angle >= 2 && checkpoint_angle < 15)
|
|
|
|
in
|
|
|
|
let is_wide_aligned =
|
|
|
|
(checkpoint_angle > -45 && checkpoint_angle <= -15) ||
|
|
|
|
(checkpoint_angle >= 15 && checkpoint_angle < 45)
|
|
|
|
in
|
|
|
|
let is_aside =
|
|
|
|
(checkpoint_angle > -85 && checkpoint_angle <= -45) ||
|
|
|
|
(checkpoint_angle >= 45 && checkpoint_angle < 85)
|
|
|
|
in
|
|
|
|
let is_behind = checkpoint_angle >= 85 || checkpoint_angle <= -85 in
|
|
|
|
let use_boost =
|
|
|
|
(!tick > 100) && is_aligned && (Vector.is_far pod checkpoint)
|
|
|
|
in
|
|
|
|
|
|
|
|
debug "angle = %d\n%!" checkpoint_angle ;
|
|
|
|
|
|
|
|
let thrust =
|
|
|
|
(* droit devant *)
|
|
|
|
if is_behind && (Vector.is_touching pod opponent) then 20
|
|
|
|
else if is_aside && (Vector.is_touching pod opponent) then 20
|
|
|
|
else if is_behind then 6
|
|
|
|
else if is_aside && (Vector.is_near checkpoint pod) then 10
|
|
|
|
else if is_wide_aligned && (Vector.is_near checkpoint pod) then 20
|
|
|
|
else if is_near_aligned && (Vector.is_near checkpoint pod) then 40
|
|
|
|
else 100
|
|
|
|
in
|
|
|
|
|
|
|
|
let power_str = match use_boost with
|
|
|
|
| false -> string_of_int thrust
|
|
|
|
| true -> "BOOST"
|
|
|
|
in
|
|
|
|
|
|
|
|
let target = Vector.add checkpoint (Vector.mult movement (-3)) in
|
|
|
|
|
|
|
|
printf "%d %d %s\n%!" target.x target.y power_str ;
|
|
|
|
|
2016-08-01 13:15:17 +00:00
|
|
|
|
|
|
|
end in
|
|
|
|
|
2016-08-06 23:00:26 +00:00
|
|
|
let parse_pod_line () =
|
2016-08-01 13:15:17 +00:00
|
|
|
let line = input_line stdin in
|
|
|
|
let build_results_fn = (
|
|
|
|
fun x y checkpointx checkpointy checkpointdist checkpointangle ->
|
2016-08-06 23:00:26 +00:00
|
|
|
(Vector.create x y),
|
|
|
|
(Vector.create checkpointx checkpointy),
|
|
|
|
checkpointdist,
|
|
|
|
checkpointangle
|
2016-08-01 13:15:17 +00:00
|
|
|
) in
|
|
|
|
Scanf.sscanf line "%d %d %d %d %d %d" build_results_fn
|
|
|
|
in
|
|
|
|
|
|
|
|
let map_center = Vector.create (16000 / 2) (9000 / 2) in
|
|
|
|
let first_turn = ref true in
|
|
|
|
let old_pod = ref (Vector.create 0 0) in
|
|
|
|
|
|
|
|
let tick = ref 0 in
|
|
|
|
let checkpoint_list = ref (CheckpointList.create ()) in
|
|
|
|
|
|
|
|
(* laps : le nombre de tours à effectuer pour finir la course. *)
|
|
|
|
let parse_init () =
|
2016-08-06 23:00:26 +00:00
|
|
|
let laps =
|
|
|
|
let line = input_line stdin in
|
|
|
|
Scanf.sscanf line "%d" (fun x -> x)
|
2016-08-01 13:15:17 +00:00
|
|
|
in
|
2016-08-06 23:00:26 +00:00
|
|
|
let checkpoint_count =
|
|
|
|
let line = input_line stdin in
|
|
|
|
Scanf.sscanf line "%d" (fun x -> x)
|
2016-08-01 13:15:17 +00:00
|
|
|
in
|
2016-08-06 23:00:26 +00:00
|
|
|
let parse_checkpoint () =
|
|
|
|
let line = input_line stdin in
|
|
|
|
Scanf.sscanf line "%d %d" (fun x y ->
|
|
|
|
Vector.create x y
|
|
|
|
)
|
2016-08-01 13:15:17 +00:00
|
|
|
in
|
2016-08-06 23:00:26 +00:00
|
|
|
for i = 1 to checkpoint_count do
|
|
|
|
let checkpoint = parse_checkpoint () in
|
|
|
|
checkpoint_list := CheckpointList.add !checkpoint_list checkpoint ;
|
|
|
|
()
|
|
|
|
done
|
|
|
|
in
|
2016-08-01 13:15:17 +00:00
|
|
|
|
2016-08-06 23:00:26 +00:00
|
|
|
let pods = Array.make 2 (Pod.create ()) in
|
|
|
|
let game = Game.create () in
|
2016-08-01 13:15:17 +00:00
|
|
|
|
2016-08-06 23:00:26 +00:00
|
|
|
(* game loop *)
|
|
|
|
while true do
|
|
|
|
(* read pod1 line & update game data *)
|
|
|
|
parse_pod_line () |> Pod.update game.pods.(0) ;
|
|
|
|
parse_pod_line () |> Pod.update game.pods.(1) ;
|
|
|
|
parse_pod_line () |> Pod.update game.opponents.(0) ;
|
|
|
|
parse_pod_line () |> Pod.update game.opponents.(1) ;
|
2016-08-01 13:15:17 +00:00
|
|
|
|
2016-08-06 23:00:26 +00:00
|
|
|
for i = 0 to 1 do
|
|
|
|
game.pods.(i)
|
|
|
|
|> Pod.update pod1_data
|
|
|
|
|> Strategy.apply
|
|
|
|
|> fun pod -> print_endline pod.output_str ;
|
|
|
|
done
|
2016-08-01 13:15:17 +00:00
|
|
|
|
|
|
|
tick := !tick + 1 ;
|
|
|
|
old_pod := pod ;
|
|
|
|
done;
|
|
|
|
|
|
|
|
|