191 lines
5.2 KiB
OCaml
191 lines
5.2 KiB
OCaml
exception PT of int * int ;;
|
|
Random.self_init () ;;
|
|
|
|
(* parsing output.txt *)
|
|
type player = {
|
|
chx : int; (* X chunk, is in [0, lines[ *)
|
|
chy : int; (* Y chunk, is in [0, cols[ *)
|
|
posx : float; (* X coord, is in [0, roomSize[ *)
|
|
posy : float; (* Y coord, is in [0, roomSize[ *)
|
|
} ;;
|
|
|
|
let rec ln b = function | k when k < b -> 0 | k -> 1+ln b (k/b) in
|
|
let isDigit c = match (Char.code c) with | k when k >= 48 && k <= 57 -> true | _ -> false in
|
|
let rec pw x = function | 0 -> 1 | 1 -> x | n when n mod 2 = 0 -> pw (x*x) (n/2) | n -> x*pw (x*x) ((n-1)/2) in
|
|
let read_int (str : string) (i : int ref) =
|
|
let buf = ref 0 in
|
|
while !i < String.length str && not (isDigit str.[!i]) do
|
|
incr i;
|
|
done;
|
|
|
|
while !i < String.length str && isDigit str.[!i] do
|
|
buf := 10 * !buf + (Char.code str.[!i] - 48);
|
|
incr i
|
|
done;
|
|
!buf
|
|
in
|
|
let read_float (str : string) (i : int ref) =
|
|
let ent = read_int str i in
|
|
let frac = read_int str i in
|
|
(*Printf.printf "-> %d %d <-\n" ent frac;*)
|
|
(float_of_int ent +. (float_of_int frac) /. (float_of_int (pw 10 (1+ ln 10 frac))))
|
|
in
|
|
|
|
let file = open_in "output.txt" in
|
|
|
|
let nPlayers = int_of_string (input_line file) in
|
|
|
|
(*Printf.printf "np : %d\n" nPlayers;*)
|
|
|
|
let players = Array.make nPlayers {chx=0;chy=0;posx=0.;posy=0.} in
|
|
for i = 0 to nPlayers -1 do
|
|
let data = input_line file in
|
|
let i = ref 0 in
|
|
let idPlayer = read_int data i in
|
|
let chy = read_int data i in
|
|
let chx = read_int data i in
|
|
let posx = read_float data i in
|
|
let posy = read_float data i in
|
|
players.(idPlayer) <- {chx = chx; chy = chy; posx = posx; posy = posy}
|
|
done;
|
|
|
|
(*Printf.printf "players done\n";*)
|
|
|
|
let you = int_of_string (input_line file) in
|
|
ignore (input_line file);
|
|
|
|
let wdht = input_line file in
|
|
let whi = ref 0 in
|
|
let lines = read_int wdht whi in
|
|
let cols = read_int wdht whi in
|
|
|
|
(*Printf.printf "dims : %d %d\n" lines cols;*)
|
|
|
|
let map = Array.make_matrix lines cols '.' in
|
|
for i= 0 to lines-1 do
|
|
String.iteri (fun j ch -> map.(i).(j) <- ch) (input_line file)
|
|
|
|
done;
|
|
ignore (input_line file);
|
|
|
|
let meta = input_line file in
|
|
let metai = ref 0 in
|
|
|
|
(* metadata (constants relative to the map) *)
|
|
let roomSize = read_int meta metai in (* integer (meters) *)
|
|
let maximumSpeed = read_int meta metai in (* integer (meters/seconds) *)
|
|
let playerRadius = read_int meta metai in (* integer *)
|
|
let friction = read_float meta metai in (* float (between 0.0 and 1.0) *)
|
|
let restitutionFactor = read_float meta metai in (* float (between 0.0 and 1.0) *)
|
|
let trackDistance = read_float meta metai in (*
|
|
float (between 0.0 and 0.5) - this is the width of the black area on both side of the tracks
|
|
in other words, the width of the track is (except for start and finish) roomSize*(1-2*trackDistance)
|
|
*)
|
|
let magneticField = read_float meta metai in (* workd just like in induction : v ^ B is added to the speed each tick *)
|
|
|
|
close_in file ;
|
|
(*Printf.printf "%d %d %d %f %f %f\n" roomSize maximumSpeed playerRadius friction restitutionFactor trackDistance ;;*)
|
|
|
|
(*
|
|
VARIABLES :
|
|
nPlayers : number of players in the match
|
|
players : list containing data relative to all players (struct is defined at the top of the code)
|
|
you : integer telling you who you are
|
|
(lines, cols) : the dimension of the map
|
|
map : a char array array containing each tile as an integer
|
|
metadata : see above
|
|
*)
|
|
|
|
let getDirs = function
|
|
| '0' -> 5
|
|
| '1' -> 10
|
|
| '2' -> 3
|
|
| '3' -> 6
|
|
| '4' -> 12
|
|
| '5' -> 9
|
|
| '6' -> 5
|
|
| '7' -> 10
|
|
| 'S' -> 15
|
|
| _ -> 0
|
|
in
|
|
|
|
let getS () =
|
|
try
|
|
for i = 0 to lines -1 do
|
|
for j = 0 to cols -1 do
|
|
if map.(i).(j) = 'S' then
|
|
raise (PT (i,j))
|
|
done
|
|
done;
|
|
failwith "no start ?"
|
|
with
|
|
| PT (x,y) -> (x,y)
|
|
|
|
in
|
|
|
|
let getPath mp =
|
|
let path = Array.make_matrix lines cols '.' in
|
|
let vstd = Hashtbl.create 100 in
|
|
let halt = ref false in
|
|
let rec aux (i,j) =
|
|
if i >= 0 && j >= 0 && i < lines && j < cols then begin
|
|
if mp.(i).(j) = 'E' then
|
|
halt := true
|
|
else if not !halt && path.(i).(j) <> ',' && Hashtbl.find_opt vstd (i,j) = None then begin
|
|
Hashtbl.add vstd (i,j) 1;
|
|
|
|
let ds = getDirs mp.(i).(j) in
|
|
|
|
if not !halt && ds mod 2 = 1 then begin
|
|
path.(i).(j) <- '^';
|
|
aux (i-1,j);
|
|
end;
|
|
|
|
if not !halt && (ds/2) mod 2 = 1 then begin
|
|
path.(i).(j) <- '>';
|
|
aux (i,j+1);
|
|
end;
|
|
|
|
if not !halt && (ds/4) mod 2 = 1 then begin
|
|
path.(i).(j) <- 'v';
|
|
aux (i+1,j);
|
|
end;
|
|
|
|
if not !halt && (ds/8) mod 2 = 1 then begin
|
|
path.(i).(j) <- '<';
|
|
aux (i,j-1);
|
|
end;
|
|
|
|
if not !halt then path.(i).(j) <- ','
|
|
end
|
|
end
|
|
in aux (getS ());
|
|
path
|
|
in
|
|
|
|
let pth = getPath map in
|
|
|
|
(*
|
|
Array.iter (
|
|
fun ln -> Array.iter (
|
|
fun c -> print_char c;
|
|
) ln;
|
|
print_endline ""
|
|
) pth;
|
|
*)
|
|
|
|
let ans = open_out "answer.txt" in
|
|
|
|
match pth.(players.(you).chx).(players.(you).chy) with
|
|
| '>' -> Printf.fprintf ans "0 100\n"
|
|
| 'v' -> Printf.fprintf ans "90 100\n"
|
|
| '<' -> Printf.fprintf ans "180 100\n"
|
|
| '^' -> Printf.fprintf ans "270 100\n"
|
|
| _ -> Printf.fprintf ans "%d 100\n" (Random.int 360)
|
|
;
|
|
|
|
close_out ans ;;
|
|
|
|
(*
|
|
write two integers (angle (0-360, integer) and power (0-100, integer)) to answer.txt
|
|
*) |