let open Printf in
let debug = fprintf stderr in

let checkpoint_ray = 600 in

let module Vector = struct
  type t = {
    x : int;
        y : int
  }

  let to_string dst : string =
      (Printf.sprintf "{ x = %d ; y = %d }" dst.x dst.y)

  let create x y = 
    { x ; y }

  let equal dst src = 
      (dst.x = src.x) && (dst.y = src.y)
  
  let diff dst src =
    { x = (dst.x - src.x) ;
          y = (dst.y - src.y)
    }

  let mult src a =
    { x = src.x * a ;
          y = src.y * a 
    }

  let add dst src = 
    { x = (src.x + dst.x) ;
          y = (src.y + dst.y) 
    }

  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

 let is_touching dst src = 
    (distance dst src) < (checkpoint_ray / 2)
    
  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 = {
    pos : Vector.t ;
        dir : Vector.t ;
    }
end in

let module CheckpointList = struct
    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 
            }

    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 parse_line1 () =
  let line = input_line stdin in
  let build_results_fn = (
    fun x y checkpointx checkpointy checkpointdist checkpointangle -> 
    (Vector.create x y), 
    (Vector.create checkpointx checkpointy), 
    checkpointdist, 
    checkpointangle
  ) in
  Scanf.sscanf line "%d %d %d %d %d %d" build_results_fn
in

let parse_line2 () =
  let line = input_line stdin in
  let build_results_fn = (
    fun opponentx opponenty -> 
    (Vector.create opponentx opponenty)
  ) in
  Scanf.sscanf line "%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

(* game loop *)
while true do

  (* nextcheckpointdist: distance to the next checkpoint *)
  (* nextcheckpointangle: angle between your pod orientation and the direction of the next checkpoint *)
  let pod, checkpoint, checkpoint_dist, checkpoint_angle = parse_line1 () in
  let opponent = parse_line2 () in 

  if !first_turn then begin
    old_pod := pod ;
    first_turn := false
  end ;
  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

  printf "%d %d %s\n%!" checkpoint.x checkpoint.y power_str ;

  tick := !tick + 1 ;
  old_pod := pod ;
done;