diff --git a/again b/again index d3d4952..d61c94f 100755 Binary files a/again and b/again differ diff --git a/again.cmi b/again.cmi index 7ace879..e86252e 100644 Binary files a/again.cmi and b/again.cmi differ diff --git a/again.cmo b/again.cmo index b3c5c66..553a8bc 100644 Binary files a/again.cmo and b/again.cmo differ diff --git a/again.ml b/again.ml index 8a8a415..4ae34a5 100644 --- a/again.ml +++ b/again.ml @@ -402,6 +402,32 @@ let build_danger_map (gd : game_data) = done; res ;; +let generate_gain_map (gd : game_data) = + let lines = Array.length gd.laby + and cols = Array.length gd.laby.(0) in + let bsize = gd.players.(gd.player_id).bomb_radius in + let res = Array.make_matrix lines cols 0 in + for l = 0 to lines -1 do + for c = 0 to cols -1 do + if (gd.laby.(l).(c) >= 3) || gd.laby.(l).(c) = 0 then begin + for dir = 0 to 3 do + for w = 0 to bsize do + if (w > 0) || dir = 0 then begin + let nx = l + w * (fst order.(dir)) + and ny = c + w * (snd order.(dir)) in + if is_valid nx ny lines cols then begin + res.(nx).(ny) <- res.(nx).(ny) + 1; + if (gd.laby.(l).(c) >= 3) then + res.(nx).(ny) <- res.(nx).(ny) + 1; + end + end + done + done + end + done + done; + res ;; + (* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) (* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) @@ -449,6 +475,78 @@ let simulate_bomb_deconstruct (dgs : danger_map) (bx : int) (by : int) (bsize : (* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) (* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) +let exists_opt f (arr : 'a array) = + if Array.length arr = 0 then + false + else + Array.exists f arr ;; + +let amt_free_adj_spaces (gd : game_data) (x : int) (y : int) = + let lines = Array.length gd.laby + and cols = Array.length gd.laby.(0) in + Array.fold_left + (fun acc (ox, oy) -> + if (is_valid (x+ox) (y+oy) lines cols && gd.laby.(x+ox).(y+oy) <> 1 && gd.laby.(x+ox).(y+oy) <> 2) then acc+1 else acc + ) + 0 + order ;; + +let max_depth = 4 ;; +let is_player_nearby (gd : game_data) = + let lines = Array.length gd.laby + and cols = Array.length gd.laby.(0) in + (* DFS to find whether or not there are nearby players *) + let visited = Hashtbl.create 40 in + Hashtbl.add visited ((gd.players.(gd.player_id).xy.x), (gd.players.(gd.player_id).xy.y)) 1 ; + let rec dfs x y depth = + if Hashtbl.find_opt visited (x, y) = None && depth <= max_depth && (is_valid x y lines cols && gd.laby.(x).(y) <> 1 && gd.laby.(x).(y) <> 2) then begin + Hashtbl.add visited (x, y) 1; + if Array.exists (fun (p : player) -> p.xy.x = x && p.xy.y = y) gd.players then + raise (ReturnBool true) + else begin + for dir = 0 to 3 do + dfs (x + fst order.(dir)) (y + snd order.(dir)) (depth+1) + done + end + end + in + try + dfs (gd.players.(gd.player_id).xy.x +1) (gd.players.(gd.player_id).xy.y) 0; + dfs (gd.players.(gd.player_id).xy.x -1) (gd.players.(gd.player_id).xy.y) 0; + dfs (gd.players.(gd.player_id).xy.x) (gd.players.(gd.player_id).xy.y +1) 0; + dfs (gd.players.(gd.player_id).xy.x) (gd.players.(gd.player_id).xy.y -1) 0; + false + with + | ReturnBool b -> b ;; + +let is_dead_end (gd : game_data) (xstart : int) (ystart : int) (xban : int) (yban : int) = + if not (is_player_nearby gd) then + false (* if no one is nearby, it's safe to go there (hopefully) *) + else begin + let lines = Array.length gd.laby + and cols = Array.length gd.laby.(0) in + let visited = Hashtbl.create 50 in + Hashtbl.add visited (xban, yban) 1 ; + let rec aux x y = + if Hashtbl.find_opt visited (x, y) = None then begin + Hashtbl.add visited (x, y) 1; + if (is_valid x y lines cols && gd.laby.(x).(y) <> 1 && gd.laby.(x).(y) <> 2) then begin + match (amt_free_adj_spaces gd x y) with + | 0 -> failwith "wtf john" + | 1 | 2 -> for dir = 0 to 3 do + aux (x + fst order.(dir)) (y + snd order.(dir)) + done + | _ -> raise (ReturnBool false) + end + end + in + try + aux xstart ystart; + true ; + with + | ReturnBool b -> b + end ;; + let reverse_simulate_bomb (dgs : danger_map) (save : (int * int, float) Hashtbl.t) = Hashtbl.iter (fun (x, y) dt -> @@ -554,6 +652,7 @@ let bfs_for_crate (gd : game_data) (dgs : danger_map) (x0 : int) (y0 : int) (sti let visited = Hashtbl.create 100 in let q = Queue.create () in let interval = Float.pow (0.9) (float_of_int gd.players.(gd.player_id).nspeed) in + let pid = gd.player_id in Queue.add (x0, y0, stime +. interval, 4, 1) q ; @@ -576,6 +675,7 @@ let bfs_for_crate (gd : game_data) (dgs : danger_map) (x0 : int) (y0 : int) (sti if (ct >= stime +. (float_of_int minDist) *. interval) && (is_empty_lst dgs.explosionTimes.(x).(y)) && (* safe *) + (*(not searchCrate || direction = 4 || not (is_dead_end gd (gd.players.(pid).xy.x + fst order.(direction)) (gd.players.(pid).xy.y + snd order.(direction)) gd.players.(pid).xy.x gd.players.(pid).xy.y)) &&*) (not searchCrate || (sees_a_crate gd dgs x y && not dgs.explodedCrates.(x).(y))) && (* sees a crate *) (not searchBonus || dgs.bonusMap.(x).(y)) (* is a bonus *) then begin @@ -635,9 +735,15 @@ let move_crate (gd : game_data) (dgs : danger_map) = (* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) (* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) + + +(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) +(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) + let game_map = parse_input "entrees.txt" ;; if debug_all then print_game_data game_map ;; let danger_data = build_danger_map game_map ;; +let gain_map = generate_gain_map game_map ;; (*Printf.fprintf stderr "\n" ;; print_dangers danger_data ;;*) diff --git a/entrees.txt b/entrees.txt index 7179547..aba0b51 100644 --- a/entrees.txt +++ b/entrees.txt @@ -1,27 +1,25 @@ -6.0 +142.0 3 13 21 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 0 0 2 2 2 2 0 2 2 2 2 2 0 2 2 2 2 0 0 1 -1 0 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 0 1 -1 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 -1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 0 1 2 1 2 1 -1 2 0 2 0 0 2 2 2 0 2 2 0 2 2 2 2 2 2 2 1 -1 0 1 2 1 2 1 2 1 0 1 2 1 2 1 2 1 2 1 2 1 -1 2 2 0 2 2 2 2 2 2 2 2 2 0 2 0 2 2 2 2 1 -1 2 1 2 1 2 1 2 1 2 1 0 1 2 1 2 1 2 1 2 1 -1 2 2 2 2 2 0 0 0 2 2 2 2 2 2 2 2 2 2 2 1 -1 0 1 2 1 0 1 2 1 0 1 2 1 2 1 2 1 2 1 0 1 -1 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 1 +1 3 3 0 0 6 0 2 2 2 2 2 2 2 0 2 0 5 5 5 1 +1 3 1 3 1 6 1 2 1 2 1 2 1 2 1 0 1 5 1 5 1 +1 3 3 3 3 6 6 0 2 2 2 0 2 2 0 5 5 5 5 5 1 +1 3 1 3 1 6 1 2 1 2 1 0 1 2 1 0 1 5 1 5 1 +1 3 3 3 6 6 6 0 0 0 2 2 2 2 0 0 5 5 5 5 1 +1 3 1 3 1 6 1 2 1 3 1 2 1 0 1 5 1 4 1 0 1 +1 3 3 3 3 3 3 3 3 3 3 0 0 4 4 5 5 4 4 0 1 +1 3 1 3 1 3 1 3 1 3 1 2 1 4 1 5 1 4 1 4 1 +1 3 3 3 3 3 3 3 3 3 3 0 0 5 5 5 5 4 4 4 1 +1 3 1 6 1 3 1 3 1 3 1 0 1 5 1 5 1 4 1 4 1 +1 6 6 3 3 3 3 3 3 3 0 5 5 5 5 4 4 4 4 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -4 -2 1 1 6.5 -10 19 1 6.5 -2 19 1 6.5 -10 1 1 6.5 -4 -1 2 0 0 0 1 0 0 -11 18 1 0 0 1 0 0 -1 18 2 0 0 1 0 0 -11 2 3 0 0 1 0 0 -0 +2 +3 7 1 144.5 +9 11 4 144.80000000000047 +3 +11 10 0 1 3 4 3 1 +8 13 1 1 1 1 2 2 +2 5 3 0 1 1 2 1 +1 +7 12 4 diff --git a/sortie.txt b/sortie.txt index 7cc0f37..e69de29 100644 --- a/sortie.txt +++ b/sortie.txt @@ -1 +0,0 @@ -4 0 \ No newline at end of file