added claim function + tweaked some numbers
This commit is contained in:
parent
77f6ec5c5e
commit
1f47adad37
44
entrees.txt
44
entrees.txt
|
@ -1,24 +1,26 @@
|
|||
182.62000000000037
|
||||
2
|
||||
205.50000000000065
|
||||
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 3 3 3 3 3 3 3 3 3 2 0 0 5 5 5 5 5 5 5 1
|
||||
1 3 1 3 1 3 1 0 1 0 1 2 1 0 1 5 1 5 1 5 1
|
||||
1 3 3 3 3 3 3 3 2 3 2 2 2 2 5 5 5 5 5 5 1
|
||||
1 3 1 3 1 3 1 3 1 3 1 2 1 2 1 5 1 5 1 5 1
|
||||
1 3 0 3 3 3 3 3 3 3 3 3 0 2 0 5 5 5 5 5 1
|
||||
1 0 1 0 1 3 1 3 1 3 1 4 1 0 1 5 1 5 1 2 1
|
||||
1 0 0 6 6 3 3 3 3 3 0 4 0 5 5 5 5 5 4 4 1
|
||||
1 0 1 6 1 6 1 3 1 3 1 4 1 4 1 5 1 4 1 4 1
|
||||
1 6 6 6 6 6 6 4 4 3 4 4 4 4 4 4 4 4 5 4 1
|
||||
1 6 1 6 1 6 1 6 1 3 1 4 1 4 1 5 1 4 1 4 1
|
||||
1 6 6 6 6 6 6 6 0 3 4 4 4 4 4 4 4 4 4 4 1
|
||||
1 6 3 3 3 4 4 4 4 6 6 6 6 6 6 4 6 5 6 6 1
|
||||
1 6 1 3 1 6 1 6 1 4 1 6 1 6 1 4 1 5 1 5 1
|
||||
1 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 4 6 5 1
|
||||
1 6 1 3 1 6 1 6 1 4 1 6 1 6 1 4 1 4 1 5 1
|
||||
1 6 6 6 6 6 6 6 6 4 6 6 4 6 4 4 4 4 4 4 1
|
||||
1 6 1 6 1 6 1 6 1 3 1 6 1 6 1 4 1 4 1 4 1
|
||||
1 6 6 6 6 6 6 4 4 4 4 6 4 4 4 4 4 4 4 4 1
|
||||
1 6 1 6 1 6 1 6 1 3 1 6 1 6 1 4 1 4 1 4 1
|
||||
1 6 6 6 6 3 3 3 4 3 3 6 3 3 3 4 4 4 4 4 1
|
||||
1 6 1 6 1 6 1 6 1 3 1 6 1 3 1 3 1 4 1 4 1
|
||||
1 6 6 6 3 6 3 3 3 3 3 3 3 3 3 3 3 4 3 4 1
|
||||
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|
||||
2
|
||||
6 11 2 185.56136399999963
|
||||
9 13 4 186.85000000000056
|
||||
2
|
||||
8 13 1 2 3 4 1 3
|
||||
7 15 2 2 3 2 1 1
|
||||
1
|
||||
2 9 1
|
||||
4
|
||||
5 9 5 206.50000000000063
|
||||
5 18 2 207.00000000000085
|
||||
7 10 5 209.20000000000064
|
||||
11 15 4 209.69300000000123
|
||||
3
|
||||
11 17 1 3 2 4 1 3
|
||||
3 19 2 1 2 2 1 3
|
||||
8 9 3 1 4 5 4 3
|
||||
0
|
||||
|
|
227
main.ml
227
main.ml
|
@ -329,6 +329,21 @@ let evaluate_dangers (gd : game_data) =
|
|||
done
|
||||
done ;
|
||||
|
||||
(* add players *)
|
||||
for p = 0 to gd.nplayers -1 do
|
||||
if p <> gd.player_id then begin
|
||||
let player_dgr = (Danger (gd.dt +. 5.5)) in
|
||||
for d = 0 to 3 do
|
||||
for o = 0 to gd.players.(p).bomb_radius do
|
||||
let nx = gd.players.(p).xy.x + o*(fst order.(d))
|
||||
and ny = gd.players.(p).xy.y + o*(snd order.(d)) in
|
||||
if is_valid nx ny lines cols then
|
||||
res.(nx).(ny) <- danger_priority res.(nx).(ny) player_dgr ;
|
||||
done
|
||||
done
|
||||
end
|
||||
done;
|
||||
|
||||
(* add bonuses *)
|
||||
for b = 0 to gd.nboosts -1 do
|
||||
res.(gd.boosts.(b).xy.x).(gd.boosts.(b).xy.y) <- danger_priority (res.(gd.boosts.(b).xy.x).(gd.boosts.(b).xy.y)) Bonus
|
||||
|
@ -401,8 +416,10 @@ let cell_values (gd : game_data) =
|
|||
let cx = ln + w*(fst order.(dir))
|
||||
and cy = cl + w*(snd order.(dir)) in
|
||||
if not !halt && is_valid (cx) (cy) lines cols then begin
|
||||
if gd.laby.(cx).(cy) <> 1 && gd.laby.(cx).(cy) <> 2 then (* non-wall *)
|
||||
if gd.laby.(cx).(cy) = 0 then (* unclaimed tile *)
|
||||
res.(cx).(cy) <- res.(cx).(cy) + 1
|
||||
else if gd.laby.(cx).(cy) >= 3 then (* opponent tile *)
|
||||
res.(cx).(cy) <- res.(cx).(cy) + 2
|
||||
else
|
||||
halt := true ;
|
||||
end
|
||||
|
@ -486,7 +503,6 @@ let has_a_safe_path_origin_2 (cx0 : int) (cy0 : int) (lines : int) (cols : int)
|
|||
|
||||
Hashtbl.add visited (cx0, cy0) 1 ;
|
||||
|
||||
|
||||
Queue.add (cx0+1, cy0, simt +. interval, 2) q ;
|
||||
Queue.add (cx0-1, cy0, simt +. interval, 0) q ;
|
||||
Queue.add (cx0, cy0+1, simt +. interval, 1) q ;
|
||||
|
@ -498,6 +514,7 @@ let has_a_safe_path_origin_2 (cx0 : int) (cy0 : int) (lines : int) (cols : int)
|
|||
let (cx, cy, cur_t, direct) = Queue.pop q in
|
||||
|
||||
if (Hashtbl.find_opt visited (cx, cy) = None && is_valid cx cy lines cols && level_of_danger dgs.(cx).(cy) >= cur_t) then begin
|
||||
(* cell is unvisited, wont kill the player and is within range *)
|
||||
Hashtbl.add visited (cx, cy) 1 ;
|
||||
if cur_t > simt +. (float_of_int maxdepth) *. interval then (* too deep *)
|
||||
raise (ReturnInt 4)
|
||||
|
@ -526,48 +543,9 @@ let has_a_safe_path_origin_2 (cx0 : int) (cy0 : int) (lines : int) (cols : int)
|
|||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
|
||||
let is_safe = function
|
||||
| Safe | Danger _ | Bonus -> true
|
||||
| Fatal _ | Blocked -> false ;;
|
||||
|
||||
let move_safe (gd : game_data) (dgs : danger array array) =
|
||||
(* use this whenever you are standing on a non-safe tile *)
|
||||
(* Strat : find the shortest, safest path *)
|
||||
let pid = gd.player_id in
|
||||
let interval = Float.pow 0.9 (float_of_int gd.players.(pid).nspeed) in
|
||||
|
||||
if debug_all then Printf.fprintf stderr "I = %f\n" interval ;
|
||||
|
||||
let lines = Array.length gd.laby
|
||||
and cols = Array.length gd.laby.(0) in
|
||||
|
||||
(* BFS to find the nearest safe spot (if it exists) *)
|
||||
try
|
||||
(* 0. if you're standing on a safe tile, stay there *)
|
||||
let (cx, cy) = (gd.players.(pid).xy.x, gd.players.(pid).xy.y) in
|
||||
if dgs.(cx).(cy) = Safe then begin
|
||||
current_status := BlowUpCrates ;
|
||||
raise (ReturnInt 4) ;
|
||||
end;
|
||||
|
||||
(*let result = has_a_safe_path (cx) (cy) gd.dt in*)
|
||||
let result = has_a_safe_path_origin_2 cx cy lines cols gd.dt interval gd dgs [|Bonus|] [||] [|Blocked|] [||] 20 in
|
||||
|
||||
if result <> 4 then result else begin
|
||||
let result2 = has_a_safe_path_origin_2 cx cy lines cols gd.dt interval gd dgs [|Safe|] [||] [|Blocked|] [||] 80 in
|
||||
if result2 <> 4 then result2
|
||||
else begin
|
||||
(* you're probably dead if the code reaches here... *)
|
||||
if debug_all then Printf.fprintf stderr "[escape] Attempt F...\n";
|
||||
Printf.fprintf stderr "well shit\n" ;
|
||||
4
|
||||
end
|
||||
end
|
||||
with
|
||||
| ReturnInt k -> k ;;
|
||||
|
||||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
let contains_crate (gd : game_data) =
|
||||
Array.fold_left
|
||||
(fun b1 lst -> b1 || (Array.fold_left (fun b2 tile -> b2 || (tile = 2)) false lst)) false gd.laby ;;
|
||||
|
||||
let is_a_crate_nearby (gd : game_data) (dgs : danger array array) =
|
||||
let pid = gd.player_id
|
||||
|
@ -622,7 +600,7 @@ let move_explore (gd: game_data) (dgs : danger array array) =
|
|||
res2
|
||||
end
|
||||
else begin
|
||||
if false && exit then (* TODO *)
|
||||
if exit then (* TODONE *)
|
||||
current_status := ClaimLand ;
|
||||
Printf.fprintf stderr "Exited.\n" ;
|
||||
4
|
||||
|
@ -672,9 +650,157 @@ let move_explore (gd: game_data) (dgs : danger array array) =
|
|||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
|
||||
let cell_profit (d_from_p : int) (gain : int) =
|
||||
(100000 * gain * (1 + ln_b 7 gain)) / d_from_p ;;
|
||||
|
||||
let move_claim (gd : game_data) (dgs : danger array array) (gns : int array array) =
|
||||
let lines = Array.length gd.laby
|
||||
and cols = Array.length gd.laby.(0) in
|
||||
let pid = gd.player_id in
|
||||
let cxi = gd.players.(pid).xy.x
|
||||
and cyi = gd.players.(pid).xy.y in
|
||||
let interval = Float.pow 0.9 (float_of_int gd.players.(pid).nspeed) in
|
||||
|
||||
let distances = Array.make_matrix lines cols (-1) in
|
||||
|
||||
(* 1st BFS to calculate the distances *)
|
||||
let visited = Hashtbl.create 100 in
|
||||
let q = Queue.create () in
|
||||
|
||||
Hashtbl.add visited (cxi, cyi) 1 ;
|
||||
distances.(cxi).(cyi) <- 1 ;
|
||||
|
||||
Queue.add (cxi+1, cyi, gd.dt +. interval, 2) q ;
|
||||
Queue.add (cxi-1, cyi, gd.dt +. interval, 2) q ;
|
||||
Queue.add (cxi, cyi+1, gd.dt +. interval, 2) q ;
|
||||
Queue.add (cxi, cyi-1, gd.dt +. interval, 2) q ;
|
||||
|
||||
while not (Queue.is_empty q) do
|
||||
let (cx, cy, cur_t, dist) = Queue.pop q in
|
||||
|
||||
if (Hashtbl.find_opt visited (cx, cy) = None && is_valid cx cy lines cols && dgs.(cx).(cy) <> Blocked && level_of_danger dgs.(cx).(cy) >= cur_t) then begin
|
||||
(* cell is unvisited, is not a wall, wont kill the player and is within range *)
|
||||
Hashtbl.add visited (cx, cy) 1 ;
|
||||
distances.(cx).(cy) <- dist ;
|
||||
for dir = 0 to 3 do
|
||||
let newx = cx + fst order.(dir)
|
||||
and newy = cy + snd order.(dir) in
|
||||
Queue.add (newx, newy, cur_t +. interval, dist+1) q
|
||||
done
|
||||
end
|
||||
done;
|
||||
|
||||
(* compute the best value *)
|
||||
let maxi_gain = ref 0 in
|
||||
let maxi_i = ref (-1)
|
||||
and maxi_j = ref (-1) in
|
||||
Array.iteri
|
||||
(fun i lst -> Array.iteri
|
||||
(
|
||||
fun j elt ->
|
||||
if (distances.(i).(j) <> -1) then begin maxi_gain := max (!maxi_gain) (cell_profit distances.(i).(j) gns.(i).(j)); maxi_i := i ; maxi_j := j end
|
||||
)
|
||||
lst
|
||||
)
|
||||
gd.laby ;
|
||||
|
||||
(* 2nd BFS to find the direction, if you're not standing on the tile *)
|
||||
try
|
||||
if cell_profit distances.(cxi).(cyi) gns.(cxi).(cyi) = !maxi_gain then begin
|
||||
if gd.players.(pid).nbomb_atonce > 0 then begin
|
||||
(* simulate the placement of a bomb to ensure a safe escape route*)
|
||||
let bsize = gd.players.(pid).bomb_radius in
|
||||
|
||||
let bomb_hash = Hashtbl.create (4 * (bsize +1)) in
|
||||
let saved_dgs = Hashtbl.create (4 * (bsize +1)) in
|
||||
for dir = 0 to 3 do
|
||||
for w = 0 to bsize do
|
||||
Hashtbl.add bomb_hash (cxi + w*(fst order.(dir)), cyi + w*(snd order.(dir))) (Danger (gd.dt +. 5.5)) ;
|
||||
done
|
||||
done;
|
||||
Hashtbl.iter
|
||||
(fun (kx, ky) v ->
|
||||
if is_valid kx ky lines cols then begin
|
||||
Hashtbl.add saved_dgs (kx, ky) dgs.(kx).(ky) ;
|
||||
dgs.(kx).(ky) <- danger_priority dgs.(kx).(ky) v
|
||||
end
|
||||
)
|
||||
bomb_hash ;
|
||||
let result0 = has_a_safe_path_origin_2 cxi cyi lines cols gd.dt interval gd dgs [|Safe; Bonus|] [||] [|Blocked|] [||] 80 in
|
||||
Hashtbl.iter (fun (k1, k2) v -> dgs.(k1).(k2) <- v) saved_dgs ;
|
||||
|
||||
if result0 <> 4 then begin
|
||||
action := 1 ;
|
||||
current_status := EscapeDeath ;
|
||||
raise (ReturnInt result0)
|
||||
end
|
||||
end;
|
||||
raise (ReturnInt 4)
|
||||
end
|
||||
else if !maxi_i = (-1) then begin
|
||||
current_status := EscapeDeath ;
|
||||
raise (ReturnInt (has_a_safe_path_origin_2 cxi cyi lines cols gd.dt interval gd dgs [|Bonus; Safe|] [||] [|Blocked|] [||] 80))
|
||||
end
|
||||
else begin
|
||||
let memo = gd.laby.(!maxi_i).(!maxi_j) in
|
||||
gd.laby.(!maxi_i).(!maxi_j) <- (-2) ;
|
||||
let result = has_a_safe_path_origin_2 cxi cyi lines cols gd.dt interval gd dgs [||] [|-2|] [|Blocked|] [||] 80 in
|
||||
gd.laby.(!maxi_i).(!maxi_j) <- memo ;
|
||||
result
|
||||
end
|
||||
with
|
||||
| ReturnInt k -> k ;;
|
||||
|
||||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
|
||||
let move_safe (gd : game_data) (dgs : danger array array) (gns : int array array)=
|
||||
(* use this whenever you are standing on a non-safe tile *)
|
||||
(* Strat : find the shortest, safest path *)
|
||||
let pid = gd.player_id in
|
||||
let interval = Float.pow 0.9 (float_of_int gd.players.(pid).nspeed) in
|
||||
|
||||
if debug_all then Printf.fprintf stderr "I = %f\n" interval ;
|
||||
|
||||
let lines = Array.length gd.laby
|
||||
and cols = Array.length gd.laby.(0) in
|
||||
|
||||
(* BFS to find the nearest safe spot (if it exists) *)
|
||||
try
|
||||
(* 0. if you're standing on a safe tile, switch mode *)
|
||||
let (cx, cy) = (gd.players.(pid).xy.x, gd.players.(pid).xy.y) in
|
||||
if dgs.(cx).(cy) = Safe then begin
|
||||
if contains_crate gd then begin
|
||||
current_status := BlowUpCrates ;
|
||||
raise (ReturnInt (move_explore gd dgs)) ;
|
||||
end else begin
|
||||
current_status := ClaimLand ;
|
||||
raise (ReturnInt (move_claim gd dgs gns)) ;
|
||||
end
|
||||
end;
|
||||
|
||||
(*let result = has_a_safe_path (cx) (cy) gd.dt in*)
|
||||
let result = has_a_safe_path_origin_2 cx cy lines cols gd.dt interval gd dgs [|Bonus|] [||] [|Blocked|] [||] 20 in
|
||||
|
||||
if result <> 4 then result else begin
|
||||
let result2 = has_a_safe_path_origin_2 cx cy lines cols gd.dt interval gd dgs [|Safe|] [||] [|Blocked|] [||] 80 in
|
||||
if result2 <> 4 then result2
|
||||
else begin
|
||||
(* you're probably dead if the code reaches here... *)
|
||||
Printf.fprintf stderr "well shit\n" ;
|
||||
4
|
||||
end
|
||||
end
|
||||
with
|
||||
| ReturnInt k -> k ;;
|
||||
|
||||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
|
||||
let update_strat (gd : game_data) (dgs : danger array array) = match dgs.(gd.players.(gd.player_id).xy.x).(gd.players.(gd.player_id).xy.y) with
|
||||
| Safe -> ()
|
||||
| Danger k -> current_status := EscapeDeath
|
||||
| Danger k when k < 3.0 -> current_status := EscapeDeath
|
||||
| Danger k -> ()
|
||||
| Bonus -> ()
|
||||
| Fatal k -> (* should not happen *) current_status := EscapeDeath
|
||||
| Blocked -> failwith "did you just suffocate the player ?" ;;
|
||||
|
@ -691,6 +817,8 @@ let debug_game_data (gd : game_data) =
|
|||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
|
||||
|
||||
Printf.fprintf stderr "XXXXXXXX\n" ;;
|
||||
|
||||
let game_d = parse_input "entrees.txt" ;;
|
||||
let dangers = evaluate_dangers game_d ;;
|
||||
let gains = cell_values game_d ;;
|
||||
|
@ -711,7 +839,7 @@ let chosen = ref 0 ;;
|
|||
|
||||
let main_actions () = match !current_status with
|
||||
| EscapeDeath ->
|
||||
chosen := move_safe game_d dangers ;
|
||||
chosen := move_safe game_d dangers gains ;
|
||||
Printf.printf "%d " !chosen
|
||||
| BlowUpCrates ->
|
||||
if dangers.(game_d.players.(game_d.player_id).xy.x).(game_d.players.(game_d.player_id).xy.y) = Safe then begin
|
||||
|
@ -720,11 +848,12 @@ let main_actions () = match !current_status with
|
|||
end
|
||||
else begin
|
||||
current_status := EscapeDeath ;
|
||||
chosen := move_safe game_d dangers ;
|
||||
chosen := move_safe game_d dangers gains ;
|
||||
Printf.printf "%d " !chosen
|
||||
end
|
||||
| ClaimLand ->
|
||||
()
|
||||
chosen := move_claim game_d dangers gains ;
|
||||
Printf.printf "%d " !chosen
|
||||
| KillPlayers ->
|
||||
() ;;
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
1
|
||||
2
|
Loading…
Reference in New Issue