144 lines
3.6 KiB
OCaml
144 lines
3.6 KiB
OCaml
|
|
||
|
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_capturable dst src = (distance dst src) < 220
|
||
|
|
||
|
(*
|
||
|
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 EntityCtx = struct
|
||
|
|
||
|
type buster_state_t =
|
||
|
| Idle
|
||
|
| Carrying of int
|
||
|
|
||
|
type entity_t = {
|
||
|
id : int ;
|
||
|
pos : Vector.t ;
|
||
|
pos_old : Vector.t ;
|
||
|
}
|
||
|
|
||
|
type ghost_t = {
|
||
|
entity : entity_t ;
|
||
|
hunters : int
|
||
|
}
|
||
|
|
||
|
type buster_t = {
|
||
|
entity : entity_t ;
|
||
|
state : buster_state_t ;
|
||
|
team : int
|
||
|
}
|
||
|
|
||
|
type t =
|
||
|
| Buster of buster_t
|
||
|
| Ghost of ghost_t
|
||
|
|
||
|
let create entitytype entityid x y state value =
|
||
|
let create_entity entityid x y = {
|
||
|
id = entityid ;
|
||
|
pos = Vector.create x y ;
|
||
|
pos_old = Vector.create x y
|
||
|
} in
|
||
|
|
||
|
let create_ghost entity value = { entity ; hunters = value } in
|
||
|
|
||
|
let create_buster entity state value =
|
||
|
let state = match state with
|
||
|
| 0 -> Idle
|
||
|
| _ -> Carrying value
|
||
|
in
|
||
|
{
|
||
|
entity ;
|
||
|
state ;
|
||
|
team = entitytype
|
||
|
}
|
||
|
in
|
||
|
|
||
|
(* common properties *)
|
||
|
let entity = create_entity entityid x y in
|
||
|
|
||
|
match entitytype with
|
||
|
| -1 -> Ghost (create_ghost entity value)
|
||
|
| _ -> Buster (create_buster entity state value)
|
||
|
|
||
|
end in
|
||
|
|
||
|
|
||
|
(* entityid: buster id or ghost id *)
|
||
|
(* y: position of this buster / ghost *)
|
||
|
(* entitytype: the team id if it is a buster, -1 if it is a ghost. *)
|
||
|
(* state: For busters: 0=idle, 1=carrying a ghost. *)
|
||
|
(* value: For busters: Ghost id being carried. For ghosts: number of busters attempting to trap this ghost. *)
|
||
|
let parse_entity () =
|
||
|
let line = input_line stdin in
|
||
|
let parse_fn = (fun entityid x y entitytype state value ->
|
||
|
EntityCtx.create entitytype entityid x y state value)
|
||
|
in
|
||
|
Scanf.sscanf line "%d %d %d %d %d %d" parse_fn
|
||
|
in
|
||
|
|
||
|
(* Send your busters out into the fog to trap ghosts and bring them home! *)
|
||
|
|
||
|
let bustersperplayer = int_of_string (input_line stdin) in (* the amount of busters you control *)
|
||
|
let ghostcount = int_of_string (input_line stdin) in (* the amount of ghosts on the map *)
|
||
|
let myteamid = int_of_string (input_line stdin) in (* if this is 0, your base is on the top left of the map, if it is one, on the bottom right *)
|
||
|
|
||
|
(* initialize buster ctx array *)
|
||
|
|
||
|
(* game loop *)
|
||
|
while true do
|
||
|
let entities = int_of_string (input_line stdin) in (* the number of busters and ghosts visible to you *)
|
||
|
for i = 0 to entities - 1 do
|
||
|
let entity = parse_entity () in
|
||
|
ignore entity ;
|
||
|
done;
|
||
|
|
||
|
(* in buster id asc order *)
|
||
|
for i = 0 to bustersperplayer - 1 do
|
||
|
Printf.printf "MOVE 8000 4500\n%!" ; (* MOVE x y | BUST id | RELEASE *)
|
||
|
done;
|
||
|
|
||
|
();
|
||
|
done;
|
||
|
|