(tried to) make advanced pathfinding more exausti(ng)ve
This commit is contained in:
parent
21f2b79a4b
commit
50a354ea94
152
again.ml
152
again.ml
|
@ -98,7 +98,7 @@ exception ReturnBool of bool ;;
|
|||
|
||||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
let order = [|(-1, 0); (0, 1); (1, 0); (0, -1)|] ;;
|
||||
let order = [|(-1, 0); (0, 1); (1, 0); (0, -1); (0, 0)|] ;;
|
||||
|
||||
let current_status = ref BlowUpCrates ;;
|
||||
let action = ref 0 ;;
|
||||
|
@ -486,28 +486,52 @@ let simulate_bomb_deconstruct (dgs : danger_map) (bx : int) (by : int) (bsize :
|
|||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
|
||||
let tile_distance (gd : game_data) (start_x : int) (start_y : int) (end_x : int) (end_y : int) =
|
||||
let tile_distance (gd : game_data) (x0 : int) (y0 : int) (end_x : int) (end_y : int) =
|
||||
(* returns -1 if the 2 tiles cannot connect *)
|
||||
let lines = Array.length gd.laby
|
||||
and cols = Array.length gd.laby.(0) in
|
||||
let visited = Hashtbl.create 50 in
|
||||
let rec aux x y depth =
|
||||
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 && not (Array.fold_left (fun acc (b : bomb) -> acc || (b.xy.x = x && b.xy.y = y)) false gd.bombs)) then begin
|
||||
if x = end_x && y = end_y then
|
||||
raise (ReturnInt depth) ;
|
||||
for dir = 0 to 3 do
|
||||
aux (x + fst order.(dir)) (y + snd order.(dir)) (depth+1)
|
||||
done
|
||||
end
|
||||
end
|
||||
in
|
||||
let visited = Hashtbl.create 100 in
|
||||
let q = Queue.create () in
|
||||
|
||||
Queue.add (x0, y0, 0) q;
|
||||
|
||||
try
|
||||
aux start_x start_y 0;
|
||||
while not (Queue.is_empty q) do
|
||||
let (x, y, depth) = Queue.pop q in
|
||||
if is_valid x y lines cols && gd.laby.(x).(y) <> 1 && gd.laby.(x).(y) <> 2 && not (Array.fold_left (fun acc (b : bomb) -> acc || (b.xy.x = x && b.xy.y = y)) false gd.bombs) then begin
|
||||
if Hashtbl.find_opt visited (x, y) = None then begin (* has not been visited yet *)
|
||||
Hashtbl.add visited (x, y) 1 ;
|
||||
if (x = end_x && y = end_y) then begin
|
||||
raise (ReturnInt depth)
|
||||
end;
|
||||
if not (x0 == x && y0 == y) then begin
|
||||
for dir = 0 to 3 do
|
||||
Queue.add (x + (fst order.(dir)), y + (snd order.(dir)), depth+1) q ;
|
||||
done;
|
||||
end
|
||||
end
|
||||
end
|
||||
done;
|
||||
(-1) ;
|
||||
with
|
||||
| ReturnInt b -> b ;;
|
||||
| ReturnInt k -> k ;;
|
||||
|
||||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
|
||||
let d_len = 1 ;;
|
||||
let min_dist_from_player (gd : game_data) (x : int) (y : int) =
|
||||
Array.fold_left min 999999 (Array.init
|
||||
(Array.length gd.players)
|
||||
(fun i ->
|
||||
if gd.player_id = gd.players.(i).id then
|
||||
999999
|
||||
else begin
|
||||
let d = tile_distance gd x y (gd.players.(i).xy.x) (gd.players.(i).xy.y) in
|
||||
if d = -1 then 999999 else d
|
||||
end
|
||||
)
|
||||
) ;;
|
||||
|
||||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
|
@ -517,26 +541,29 @@ let amt_free_adj_spaces (gd : game_data) (x : int) (y : int) =
|
|||
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 && not (Array.fold_left (fun acc (b : bomb) -> acc || (b.xy.x = x && b.xy.y = y)) false gd.bombs)) then acc+1 else acc
|
||||
if (is_valid (x+ox) (y+oy) lines cols && gd.laby.(x+ox).(y+oy) <> 1 && gd.laby.(x+ox).(y+oy) <> 2 && not (Array.fold_left (fun acc (b : bomb) -> acc || (b.xy.x = x+ox && b.xy.y = y+oy)) false gd.bombs)) then acc+1 else acc
|
||||
)
|
||||
0
|
||||
order ;;
|
||||
|
||||
let max_depth = 4 ;;
|
||||
let max_spacing = 4 ;;
|
||||
let is_player_nearby (gd : game_data) (res_x : int ref) (res_y : int ref) =
|
||||
let max_depth = 12345 ;;
|
||||
let is_player_nearby (gd : game_data) (x0 : int) (y0 : int) (detect_dist : int) =
|
||||
let pid = gd.player_id in
|
||||
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.(pid).xy.x), (gd.players.(pid).xy.y)) 1 ;
|
||||
Hashtbl.add visited (x0, y0) 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
|
||||
if
|
||||
(Hashtbl.find_opt visited (x, y) = None) &&
|
||||
(depth <= detect_dist) &&
|
||||
(is_valid x y lines cols) &&
|
||||
(gd.laby.(x).(y) <> 1 && gd.laby.(x).(y) <> 2) &&
|
||||
(not (Array.fold_left (fun acc (b : bomb) -> acc || (b.xy.x = x && b.xy.y = y)) false gd.bombs))
|
||||
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 begin
|
||||
res_x := x ;
|
||||
res_y := y ;
|
||||
if Array.exists (fun (p : player) -> p.xy.x = x && p.xy.y = y && p.id <> gd.player_id) gd.players then begin
|
||||
raise (ReturnBool true)
|
||||
end
|
||||
else begin
|
||||
|
@ -559,7 +586,7 @@ let is_player_nearby (gd : game_data) (res_x : int ref) (res_y : int ref) =
|
|||
| ReturnBool b -> b ;;
|
||||
|
||||
let is_dead_end (gd : game_data) (xstart : int) (ystart : int) (xban : int) (yban : int) =
|
||||
if not (is_player_nearby gd fodder_x fodder_y) then
|
||||
if not (is_player_nearby gd gd.players.(gd.player_id).xy.x gd.players.(gd.player_id).xy.y max_depth) then
|
||||
false (* if no one is nearby, it's safe to go there (hopefully) *)
|
||||
else begin
|
||||
let lines = Array.length gd.laby
|
||||
|
@ -587,39 +614,48 @@ let is_dead_end (gd : game_data) (xstart : int) (ystart : int) (xban : int) (yba
|
|||
end ;;
|
||||
|
||||
let has_multiple_escapes (gd : game_data) (xstart : int) (ystart : int) (xban : int) (yban : int) =
|
||||
let pl_x = ref 0
|
||||
and pl_y = ref 0 in
|
||||
if not (is_player_nearby gd pl_x pl_y) 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 && not (Array.fold_left (fun acc (b : bomb) -> acc || (b.xy.x = x && b.xy.y = y)) false gd.bombs)) 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
|
||||
| _ ->
|
||||
if tile_distance gd x y !pl_x !pl_y >= max_spacing then
|
||||
raise (ReturnBool false) ;
|
||||
end
|
||||
end
|
||||
in
|
||||
if not (is_player_nearby gd gd.players.(gd.player_id).xy.x gd.players.(gd.player_id).xy.y max_depth) then
|
||||
false (* if no one is nearby, it's safe to go there (hopefully) *)
|
||||
else begin
|
||||
let visited = Hashtbl.create 100 in
|
||||
let q = Queue.create () in
|
||||
|
||||
Queue.add (xstart, ystart, 0, false) q;
|
||||
|
||||
try
|
||||
aux xstart ystart;
|
||||
true ;
|
||||
while not (Queue.is_empty q) do
|
||||
let (x, y, depth, hasSafe) = Queue.pop q in
|
||||
if is_valid x y lines cols && gd.laby.(x).(y) <> 1 && gd.laby.(x).(y) <> 2 && not (Array.fold_left (fun acc (b : bomb) -> acc || (b.xy.x = x && b.xy.y = y)) false gd.bombs) then begin
|
||||
if Hashtbl.find_opt visited (x, y) = None then begin (* has not been visited yet *)
|
||||
Hashtbl.add visited (x, y) 1 ;
|
||||
if
|
||||
(amt_free_adj_spaces gd x y >= 3) &&
|
||||
(min_dist_from_player gd x y >= depth - d_len || hasSafe)
|
||||
then begin
|
||||
raise (ReturnBool true)
|
||||
end
|
||||
else if (amt_free_adj_spaces gd x y >= 3) then begin
|
||||
for dir = 0 to 3 do
|
||||
Queue.add (x + (fst order.(dir)), y + (snd order.(dir)), depth+1, true) q ;
|
||||
done;
|
||||
end
|
||||
else if (amt_free_adj_spaces gd x y = 2) then begin
|
||||
for dir = 0 to 3 do
|
||||
Queue.add (x + (fst order.(dir)), y + (snd order.(dir)), depth+1, hasSafe) q ;
|
||||
done;
|
||||
end
|
||||
end
|
||||
end
|
||||
done;
|
||||
false ;
|
||||
with
|
||||
| ReturnBool b -> b
|
||||
| ReturnBool k -> k
|
||||
end ;;
|
||||
|
||||
let advanced_pathfind (gd : game_data) (xstart : int) (ystart : int) (xban : int) (yban : int) =
|
||||
(is_dead_end gd xstart ystart xban yban) && (has_multiple_escapes gd xstart ystart xban yban) ;;
|
||||
let advanced_pathfind (gd : game_data) (dgs : danger_map) (xstart : int) (ystart : int) (xban : int) (yban : int) =
|
||||
(not (is_player_nearby gd gd.players.(gd.player_id).xy.x gd.players.(gd.player_id).xy.y max_depth)) || ((*is_dead_end gd xstart ystart xban yban) && *)(has_multiple_escapes gd xstart ystart xban yban)) ;;
|
||||
|
||||
let reverse_simulate_bomb (dgs : danger_map) (save : (int * int, float) Hashtbl.t) =
|
||||
Hashtbl.iter
|
||||
|
@ -689,8 +725,8 @@ let goto_tile (gd : game_data) (dgs : danger_map) (x0 : int) (y0 : int) (end_x :
|
|||
then begin (* is not lethal *)
|
||||
if
|
||||
(is_empty_lst dgs.explosionTimes.(x).(y)) && (* safe *)
|
||||
(not (is_player_nearby gd fodder_x fodder_y && amt_free_adj_spaces gd x y = 1)) && (* is not a dead-end (==> ez kill) *)
|
||||
(direction = 4 || not (advanced_pathfind 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 (is_player_nearby gd x y 3 && amt_free_adj_spaces gd (gd.players.(pid).xy.x + fst order.(direction)) (gd.players.(pid).xy.y + snd order.(direction)) = 1)) &&
|
||||
(direction = 4 || (advanced_pathfind gd dgs (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)) &&
|
||||
(x = end_x && y = end_y)
|
||||
then begin
|
||||
raise (ReturnInt direction)
|
||||
|
@ -802,8 +838,8 @@ let bfs_for_crate (gd : game_data) (dgs : danger_map) (x0 : int) (y0 : int) (sti
|
|||
if
|
||||
(ct >= stime +. (float_of_int minDist) *. interval) && (* not too deep *)
|
||||
(is_empty_lst dgs.explosionTimes.(x).(y)) && (* safe *)
|
||||
(not (is_player_nearby gd fodder_x fodder_y && amt_free_adj_spaces gd x y = 1)) && (* is not a dead-end (==> ez kill) *)
|
||||
(not placedBomb || direction = 4 || not (advanced_pathfind 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 (is_player_nearby gd x y 3 && amt_free_adj_spaces gd (gd.players.(pid).xy.x + fst order.(direction)) (gd.players.(pid).xy.y + snd order.(direction)) = 1)) && (* is not a dead-end (==> ez kill) *)
|
||||
((advanced_pathfind gd dgs (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
|
||||
|
|
|
@ -1 +1 @@
|
|||
ocamlc again.ml -o again
|
||||
ocamlfind ocamlopt -linkpkg -package unix again.ml -o again
|
47
entrees.txt
47
entrees.txt
|
@ -1,31 +1,26 @@
|
|||
457.50401999999656
|
||||
3
|
||||
187.24208499999915
|
||||
2
|
||||
13 21
|
||||
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|
||||
1 3 3 0 6 3 3 3 3 3 3 3 3 3 5 5 5 5 5 6 1
|
||||
1 3 1 0 1 6 1 3 1 3 1 3 1 3 1 5 1 5 1 5 1
|
||||
1 5 3 6 6 6 6 3 5 5 5 5 5 3 5 5 5 5 3 3 1
|
||||
1 6 1 6 1 6 1 3 1 4 1 4 1 3 1 5 1 5 1 5 1
|
||||
1 6 6 6 6 6 3 3 3 3 3 3 3 3 3 5 5 5 5 5 1
|
||||
1 6 1 6 1 6 1 3 1 3 1 6 1 3 1 5 1 5 1 4 1
|
||||
1 6 6 6 6 6 6 6 6 6 6 6 4 4 5 5 6 5 0 4 1
|
||||
1 6 1 6 1 6 1 6 1 3 1 6 1 4 1 6 1 3 1 4 1
|
||||
1 6 6 6 4 6 3 6 6 6 6 6 6 4 3 3 3 3 3 3 1
|
||||
1 6 1 6 1 6 1 6 1 6 1 6 1 4 1 6 1 3 1 4 1
|
||||
1 6 6 5 6 6 6 6 6 6 6 6 4 4 4 4 3 3 3 3 1
|
||||
1 3 3 3 3 3 3 6 3 3 3 3 0 0 0 0 5 5 5 5 1
|
||||
1 3 1 3 1 3 1 6 1 0 1 3 1 5 1 0 1 5 1 5 1
|
||||
1 3 3 3 3 3 3 6 3 0 0 3 5 5 5 5 5 5 5 5 1
|
||||
1 3 1 3 1 3 1 6 1 6 1 3 1 5 1 5 1 0 1 0 1
|
||||
1 3 3 5 3 4 3 6 3 5 0 3 0 3 3 3 3 3 3 0 1
|
||||
1 3 1 5 1 4 1 6 1 5 1 3 1 4 1 4 1 4 1 0 1
|
||||
1 0 0 4 4 4 4 4 6 6 6 6 6 6 4 4 3 3 3 3 1
|
||||
1 0 1 5 1 4 1 6 1 5 1 0 1 4 1 4 1 4 1 3 1
|
||||
1 5 5 5 5 4 5 6 6 5 6 5 6 6 4 4 4 4 4 3 1
|
||||
1 5 1 6 1 5 1 6 1 6 1 5 1 0 1 4 1 4 1 3 1
|
||||
1 5 6 6 6 5 6 6 6 6 6 6 5 5 4 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
|
||||
8
|
||||
7 13 2 457.7330299999967
|
||||
7 10 2 459.4610799999966
|
||||
2 9 1 459.5
|
||||
8 9 2 460.68547999999663
|
||||
1 13 2 460.9700000000011
|
||||
5 11 2 461.2325499999966
|
||||
7 7 2 462.4569499999966
|
||||
3 7 1 462.5
|
||||
3
|
||||
5 1 3 189.5
|
||||
7 4 6 190.30000000000013
|
||||
6 3 2 192.5
|
||||
4
|
||||
8 7 0 5 2 2 1 0
|
||||
4 7 1 0 2 1 0 1
|
||||
2 11 2 2 2 2 0 0
|
||||
5 14 3 5 2 2 6 6
|
||||
7 1 0 0 2 3 1 1
|
||||
5 3 1 0 0 2 1 3
|
||||
6 3 2 6 1 2 2 2
|
||||
7 5 3 1 0 6 1 1
|
||||
0
|
||||
|
|
|
@ -1 +1 @@
|
|||
1 1
|
||||
0 0
|
Loading…
Reference in New Issue