From 1089f6cd494dc4ee165b9f2eff47a9baf7965cc3 Mon Sep 17 00:00:00 2001 From: "Glenn Y. Rolland" Date: Sun, 7 Aug 2016 01:00:26 +0200 Subject: [PATCH] Evolve to mutlipod management. --- coders-strike-back/code5.ml | 127 ++++++++------- coders-strike-back/code6.ml | 304 ++++++++++++++++++++---------------- 2 files changed, 234 insertions(+), 197 deletions(-) diff --git a/coders-strike-back/code5.ml b/coders-strike-back/code5.ml index 3c7aa39..6e0d39c 100644 --- a/coders-strike-back/code5.ml +++ b/coders-strike-back/code5.ml @@ -11,16 +11,16 @@ let module Vector = struct } let to_string dst : string = - (Printf.sprintf "{ x = %d ; y = %d }" dst.x dst.y) + (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 ; @@ -38,9 +38,9 @@ let module Vector = struct |> sqrt |> int_of_float - let is_touching dst src = + let is_touching dst src = (distance dst src) < (checkpoint_ray / 2) - + let is_near dst src = (distance dst src) < (checkpoint_ray * 2) @@ -48,108 +48,107 @@ let module Vector = struct ((distance dst src) >= checkpoint_ray * 6) end in -let module Pod = struct - type t = { - pos : Vector.t ; + let module Pod = struct + type t = { + pos : Vector.t ; dir : Vector.t ; } end in -let module CheckpointList = struct + let module CheckpointList = struct type t = { - mem: Vector.t list ; + mem: Vector.t list ; cur: Vector.t option } - + let add ck_li elem = - match ck_li.cur with + match ck_li.cur with | None -> { - mem = [] ; + mem = [] ; cur = Some elem } | Some cur_elem -> if (Vector.equal cur_elem elem) then - ck_li + ck_li else - { + { mem = cur_elem :: ck_li.mem ; cur = Some elem } let create () = - { mem = [] ; - cur = None - } - + { 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 + (ck_li.mem) + |> List.map (fun cur -> (Vector.equal elem cur)) + |> List.fold_left (fun acc elem -> acc || elem) false + end in -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), + 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 + ) 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 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 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 + let tick = ref 0 in + let checkpoint_list = ref (CheckpointList.create ()) in -(* game loop *) -while true do + (* 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 + (* 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 ; + 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) ; + 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 > -15 && checkpoint_angle <= -2) || (checkpoint_angle >= 2 && checkpoint_angle < 15) in let is_wide_aligned = - (checkpoint_angle > -45 && checkpoint_angle <= -15) || + (checkpoint_angle > -45 && checkpoint_angle <= -15) || (checkpoint_angle >= 15 && checkpoint_angle < 45) in let is_aside = - (checkpoint_angle > -85 && checkpoint_angle <= -45) || + (checkpoint_angle > -85 && checkpoint_angle <= -45) || (checkpoint_angle >= 45 && checkpoint_angle < 85) in let is_behind = checkpoint_angle >= 85 || checkpoint_angle <= -85 in @@ -174,13 +173,13 @@ while true do in let target = - Vector.mult movement (-3) + Vector.mult movement (-3) |> Vector.add checkpoint in - + printf "%d %d %s\n%!" target.x target.y power_str ; tick := !tick + 1 ; old_pod := pod ; -done; + done; diff --git a/coders-strike-back/code6.ml b/coders-strike-back/code6.ml index 6313b6c..27a6344 100644 --- a/coders-strike-back/code6.ml +++ b/coders-strike-back/code6.ml @@ -7,31 +7,31 @@ let checkpoint_ray = 600 in let module Vector = struct type t = { x : int; - y : int + y : int } let to_string dst : string = - (Printf.sprintf "{ x = %d ; y = %d }" dst.x dst.y) + (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) - + (dst.x = src.x) && (dst.y = src.y) + let diff dst src = { x = (dst.x - src.x) ; - y = (dst.y - src.y) + y = (dst.y - src.y) } let mult src a = { x = src.x * a ; - y = src.y * a + y = src.y * a } let add dst src = { x = (src.x + dst.x) ; - y = (src.y + dst.y) + y = (src.y + dst.y) } let distance (dst:t) (src:t) = @@ -40,9 +40,9 @@ let module Vector = struct |> sqrt |> int_of_float - let is_touching dst src = + let is_touching dst src = (distance dst src) < (checkpoint_ray / 2) - + let is_near dst src = (distance dst src) < (checkpoint_ray * 2) @@ -52,71 +52,154 @@ end in let module Pod = struct type t = { + mutable id : int ; mutable pos : Vector.t ; mutable dir : Vector.t ; - } - + mutable has_boost : bool ; + mutable checkpoint_pos : Vector.t ; + mutable checkpoint_dist : int ; + mutable checkpoint_angle : int ; + mutable output_str : string + } + let create () = - { pos = Vector.create 0 0 ; - dir = Vector.create 0 0 + { + 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 = "" } + + 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 + + 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 - } + type t = { + mem: Vector.t list ; + cur: Vector.t option + } - let create () = - { mem = [] ; - cur = None + 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 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 + + 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 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 ; + + +end in + +let parse_pod_line () = 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 + (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 @@ -126,89 +209,44 @@ let checkpoint_list = ref (CheckpointList.create ()) in (* laps : le nombre de tours à effectuer pour finir la course. *) let parse_init () = - let laps = - let line = input_line stdin in - Scanf.sscanf line "%d" (fun x -> x) - in - let checkpoint_count = - let line = input_line stdin in - Scanf.sscanf line "%d" (fun x -> x) - in - let parse_checkpoint () = - let line = input_line stdin in - Scanf.sscanf line "%d %d" (fun x y -> - Vector.create x y - ) - in - for i = 1 to checkpoint_count do - let checkpoint = parse_checkpoint () in - checkpoint_list := CheckpointList.add !checkpoint_list checkpoint ; - () - done + let laps = + let line = input_line stdin in + Scanf.sscanf line "%d" (fun x -> x) + in + let checkpoint_count = + let line = input_line stdin in + Scanf.sscanf line "%d" (fun x -> x) + in + let parse_checkpoint () = + let line = input_line stdin in + Scanf.sscanf line "%d %d" (fun x y -> + Vector.create x y + ) + in + for i = 1 to checkpoint_count do + let checkpoint = parse_checkpoint () in + checkpoint_list := CheckpointList.add !checkpoint_list checkpoint ; + () + done in - -let pods = Array.create 2 (Pod.create ()) in + +let pods = Array.make 2 (Pod.create ()) in +let game = Game.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 ; - let movement = Vector.diff pod !old_pod in + (* 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) ; - 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 ; + for i = 0 to 1 do + game.pods.(i) + |> Pod.update pod1_data + |> Strategy.apply + |> fun pod -> print_endline pod.output_str ; + done tick := !tick + 1 ; old_pod := pod ;