This commit is contained in:
Alexandre 2024-11-14 22:26:57 +01:00
parent 0a7a37b79b
commit 523a9c78f7
6 changed files with 108 additions and 135 deletions

BIN
again

Binary file not shown.

BIN
again.cmi

Binary file not shown.

BIN
again.cmo

Binary file not shown.

178
again.ml
View File

@ -8,6 +8,7 @@ TODO :
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
let debug_all = false ;;
let logg = true ;;
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
@ -80,8 +81,8 @@ type game_data = {
type danger_map = {
explosionTimes : (float list) array array ;
playersTimes : (float list) array array ;
bonusMap : bool array array ;
playersMap : (int * int * int) array ;
explodedCrates : bool array array ;
}
@ -165,7 +166,7 @@ let print_game_data (gd : game_data) =
let print_dangers (dgs : danger_map) =
for w = 0 to Array.length dgs.explosionTimes -1 do
for h = 0 to Array.length dgs.explosionTimes.(0) -1 do
Printf.fprintf stderr "%d " (List.length dgs.explosionTimes.(w).(h)) ;
Printf.fprintf stderr "%d " ((List.length dgs.explosionTimes.(w).(h)) + (List.length dgs.playersTimes.(w).(h))) ;
done ;
Printf.fprintf stderr "\n" ;
done ;;
@ -316,12 +317,13 @@ let build_danger_map (gd : game_data) =
and cols = Array.length gd.laby.(0) in
let (res : danger_map) = {
explosionTimes = Array.make lines [||] ;
playersTimes = Array.make lines [||] ;
bonusMap = Array.make lines [||] ;
playersMap = Array.make (gd.nplayers) (0, 0, 0) ;
explodedCrates = Array.make lines [||] ;
} in
for l = 0 to lines -1 do
res.explosionTimes.(l) <- Array.make cols [] ;
res.playersTimes.(l) <- Array.make cols [] ;
res.explodedCrates.(l) <- Array.make cols false ;
res.bonusMap.(l) <- Array.make cols false ;
done;
@ -332,6 +334,9 @@ let build_danger_map (gd : game_data) =
)
gd.bombs ;
(*if gd.nbombs > 0 then
Printf.fprintf stderr "%f %f\n" (gd.bombs.(0).det_time) (gd.bombs.(Array.length gd.bombs -1).det_time) ;*)
(* add bombs *)
let halt = ref false in
for b = 0 to gd.nbombs -1 do
@ -366,8 +371,7 @@ let build_danger_map (gd : game_data) =
let bx = gd.players.(p).xy.x
and by = gd.players.(p).xy.y in
let bsize = gd.players.(p).bomb_radius
(*and dtime = min (gd.dt +. 5.5) (List.fold_left min (gd.dt +. 1000.) res.explosionTimes.(bx).(by)) in*)
and dtime = (gd.dt +. 5.5) in
and dtime = min (gd.dt +. 5.5) (min (List.fold_left min (gd.dt +. 1000.) res.explosionTimes.(bx).(by)) (List.fold_left min (gd.dt +. 1000.) res.playersTimes.(bx).(by))) in
for dir = 0 to 3 do
for w = 0 to bsize do
if (not !halt) && (w > 0 || dir = 0) then begin
@ -375,7 +379,7 @@ let build_danger_map (gd : game_data) =
and ny = by + w * (snd order.(dir)) in
if is_valid nx ny lines cols then begin
if (gd.laby.(nx).(ny) = 0 || gd.laby.(nx).(ny) >= 3) || (gd.laby.(nx).(ny) = 2 && res.explodedCrates.(nx).(ny)) then
res.explosionTimes.(nx).(ny) <- (dtime)::(res.explosionTimes.(nx).(ny))
res.playersTimes.(nx).(ny) <- (dtime)::(res.playersTimes.(nx).(ny))
else if gd.laby.(nx).(ny) = 1 then
halt := true
else if gd.laby.(nx).(ny) = 2 then begin
@ -387,7 +391,6 @@ let build_danger_map (gd : game_data) =
done;
halt := false ;
done
(*res.playersMap.(p) <- (gd.players.(p).xy.x, gd.players.(p).xy.y, gd.players.(p).bomb_radius) ;*)
end
done;
@ -449,12 +452,32 @@ let reverse_simulate_bomb (dgs : danger_map) (save : (int * int, float) Hashtbl.
save ;;
let is_dead (dgs : danger_map) (x : int) (y : int) (t : float) (dt : float) =
List.fold_left
(List.fold_left
(fun acc curtime ->
acc || (t >= curtime && t <= curtime +. dt)
)
false
dgs.explosionTimes.(x).(y)
) || (List.fold_left
(fun acc curtime ->
acc || (t >= curtime && t <= curtime +. dt)
)
false
dgs.playersTimes.(x).(y)
) ;;
let is_dead_2 (dgs : danger_map) (x : int) (y : int) (t : float) (dt : float) =
(List.fold_left
(fun acc curtime ->
acc || (t > curtime && t < curtime +. dt)
)
false
dgs.explosionTimes.(x).(y) ;;
dgs.explosionTimes.(x).(y)
) ;;
let is_dead_all (dgs : danger_map) (x : int) (y : int) (t : float) (dt : float) = function
| true -> is_dead_2 dgs x y t dt
| false -> is_dead dgs x y t dt ;;
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *)
@ -519,7 +542,7 @@ let sees_a_crate (gd : game_data) (dgs : danger_map) (x : int) (y : int) =
with
| ReturnBool b -> b ;;
let bfs_for_crate (gd : game_data) (dgs : danger_map) (x0 : int) (y0 : int) (stime : float) =
let bfs_for_crate (gd : game_data) (dgs : danger_map) (x0 : int) (y0 : int) (stime : float) (searchCrate : bool) (searchBonus : bool) (minDist : int) (ignorePlayers : bool) (maxDist : int) =
let lines = Array.length gd.laby
and cols = Array.length gd.laby.(0) in
@ -527,101 +550,36 @@ let bfs_for_crate (gd : game_data) (dgs : danger_map) (x0 : int) (y0 : int) (sti
let q = Queue.create () in
let interval = Float.pow (0.9) (float_of_int gd.players.(gd.player_id).nspeed) in
Hashtbl.add visited (x0, y0) 1 ;
Queue.add (x0, y0, stime +. interval, 4, 1) q ;
Queue.add (x0+1, y0, stime +. interval, 2) q ;
Queue.add (x0-1, y0, stime +. interval, 0) q ;
Queue.add (x0, y0+1, stime +. interval, 1) q ;
Queue.add (x0, y0-1, stime +. interval, 3) q ;
Queue.add (x0+1, y0, stime +. interval, 2, 1) q ;
Queue.add (x0-1, y0, stime +. interval, 0, 1) q ;
Queue.add (x0, y0+1, stime +. interval, 1, 1) q ;
Queue.add (x0, y0-1, stime +. interval, 3, 1) q ;
try
while not (Queue.is_empty q) do
let (x, y, ct, direction) = Queue.pop q in
let (x, y, ct, direction, polar) = Queue.pop q in
if is_valid x y lines cols && gd.laby.(x).(y) <> 1 && gd.laby.(x).(y) <> 2 then begin (* within the map *)
if Hashtbl.find_opt visited (x, y) = None then begin (* has not been visited yet *)
Hashtbl.add visited (x, y) 1 ;
if not (is_dead dgs x y ct interval) then begin (* is not lethal *)
if (is_empty_lst dgs.explosionTimes.(x).(y)) && (sees_a_crate gd dgs x y && not dgs.explodedCrates.(x).(y)) then begin (* is a safe and valid tile *)
if Hashtbl.find_opt visited (x, y, polar) = None then begin (* has not been visited yet *)
Hashtbl.add visited (x, y, polar) 1 ;
if not (is_dead_all dgs x y ct interval ignorePlayers) && ct < stime +. (float_of_int maxDist) *. interval then begin (* is not lethal *)
if
(ct >= stime +. (float_of_int minDist) *. interval) &&
(is_empty_lst dgs.explosionTimes.(x).(y)) && (* safe *)
(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
raise (ReturnInt direction)
end;
(*Printf.fprintf stderr "+4 (%b %b)\n" (is_empty_lst dgs.explosionTimes.(x).(y)) (sees_a_crate gd dgs x y) ;*)
(*Queue.add (x, y, ct +. interval, direction, polar+1) q ;*)
if not (x0 == x && y0 == y) then begin
for dir = 0 to 3 do
Queue.add (x + (fst order.(dir)), y + (snd order.(dir)), ct +. interval, direction) q ;
done
end
end
end
Queue.add (x + (fst order.(dir)), y + (snd order.(dir)), ct +. interval, direction, polar) q ;
done;
4 ;
with
| ReturnInt k -> k ;;
let bfs_gtfo (gd : game_data) (dgs : danger_map) (x0 : int) (y0 : int) (stime : float) =
let lines = Array.length gd.laby
and cols = Array.length gd.laby.(0) in
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
Hashtbl.add visited (x0, y0) 1 ;
Queue.add (x0+1, y0, stime +. interval, 2) q ;
Queue.add (x0-1, y0, stime +. interval, 0) q ;
Queue.add (x0, y0+1, stime +. interval, 1) q ;
Queue.add (x0, y0-1, stime +. interval, 3) q ;
try
while not (Queue.is_empty q) do
let (x, y, ct, direction) = Queue.pop q in
if is_valid x y lines cols && gd.laby.(x).(y) <> 1 && gd.laby.(x).(y) <> 2 then begin (* within the map *)
if Hashtbl.find_opt visited (x, y) = None then begin (* has not been visited yet *)
Hashtbl.add visited (x, y) 1 ;
if not (is_dead dgs x y ct interval) then begin (* is not lethal *)
if (is_empty_lst dgs.explosionTimes.(x).(y)) then begin (* is a safe and valid tile *)
raise (ReturnInt direction)
end;
for dir = 0 to 3 do
Queue.add (x + (fst order.(dir)), y + (snd order.(dir)), ct +. interval, direction) q ;
done
end
end
end
done;
4 ;
with
| ReturnInt k -> k ;;
let bfs_bonus (gd : game_data) (dgs : danger_map) (x0 : int) (y0 : int) (stime : float) =
let lines = Array.length gd.laby
and cols = Array.length gd.laby.(0) in
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
Hashtbl.add visited (x0, y0) 1 ;
Queue.add (x0+1, y0, stime +. interval, 2) q ;
Queue.add (x0-1, y0, stime +. interval, 0) q ;
Queue.add (x0, y0+1, stime +. interval, 1) q ;
Queue.add (x0, y0-1, stime +. interval, 3) q ;
try
while not (Queue.is_empty q) do
let (x, y, ct, direction) = Queue.pop q in
if is_valid x y lines cols && gd.laby.(x).(y) <> 1 && gd.laby.(x).(y) <> 2 then begin (* within the map *)
if Hashtbl.find_opt visited (x, y) = None then begin (* has not been visited yet *)
Hashtbl.add visited (x, y) 1 ;
if not (is_dead dgs x y ct interval) && ct < stime +. 7. *. interval then begin (* is not lethal *)
if dgs.bonusMap.(x).(y) then begin (* is a safe and valid tile *)
raise (ReturnInt direction)
end;
for dir = 0 to 3 do
Queue.add (x + (fst order.(dir)), y + (snd order.(dir)), ct +. interval, direction) q ;
done
end
end
end
done;
4 ;
@ -633,20 +591,35 @@ let move_crate (gd : game_data) (dgs : danger_map) =
let cxi = gd.players.(pid).xy.x
and cyi = gd.players.(pid).xy.y in
try
let bonusres = bfs_bonus gd dgs cxi cyi gd.dt in
if bonusres <> 4 then raise (ReturnInt bonusres) ;
let bonusres = bfs_for_crate gd dgs cxi cyi gd.dt false true 0 false 7 in
if bonusres <> 4 then begin
if logg then Printf.fprintf stderr "bonus spotted\n" ;
raise (ReturnInt bonusres) ;
end;
if (is_a_crate_nearby gd dgs) && (is_empty_lst dgs.explosionTimes.(cxi).(cyi)) then begin
Printf.fprintf stderr "trying...\n" ;
if gd.players.(pid).nbomb_atonce > 0 then begin
if logg then Printf.fprintf stderr "trying...\n" ;
let saved = simulate_bomb_deconstruct dgs cxi cyi gd.players.(pid).bomb_radius (gd.dt +. 5.5) in
let result = bfs_gtfo gd dgs cxi cyi gd.dt in
if result <> 4 && gd.players.(pid).nbomb_atonce > 0 then begin
let result = bfs_for_crate gd dgs cxi cyi gd.dt false false 1 false 80 in
if result <> 4 then begin
action := 1 ;
raise (ReturnInt result) ;
end;
reverse_simulate_bomb dgs saved ;
end
else
else begin
raise (ReturnInt 4)
end;
bfs_for_crate gd dgs cxi cyi gd.dt
end;
if logg then Printf.fprintf stderr "searching...\n" ;
let rescr = bfs_for_crate gd dgs cxi cyi gd.dt true false 0 false 80 in
if rescr <> 4 then
rescr
else begin
if logg then Printf.fprintf stderr "searching 2...\n" ;
let rescr2 = bfs_for_crate gd dgs cxi cyi gd.dt false false 0 false 80 in
rescr2
end
with
| ReturnInt k -> k ;;
@ -657,6 +630,9 @@ let game_map = parse_input "entrees.txt" ;;
if debug_all then print_game_data game_map ;;
let danger_data = build_danger_map game_map ;;
(*Printf.fprintf stderr "\n" ;;
print_dangers danger_data ;;*)
get_meta_info game_map.player_id ;;
(*Printf.fprintf stderr "\n" ;;
print_dangers danger_data ;;*)
@ -664,7 +640,7 @@ print_dangers danger_data ;;*)
let direction = move_crate game_map danger_data ;;
Printf.printf "%d %d" direction !action ;
Printf.fprintf stderr "[player %d] %d %d (at time %f)\n" game_map.player_id direction !action game_map.dt;
if true || logg then Printf.fprintf stderr "[player %d] %d %d (at time %f)\n" game_map.player_id direction !action game_map.dt;
set_meta_info game_map.player_id ;;

View File

@ -1,27 +1,24 @@
135.09900000000007
85.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 3 3 3 3 0 2 2 2 2 2 2 2 0 5 5 5 5 5 5 1
1 3 1 3 1 0 1 2 1 0 1 2 1 2 1 5 1 5 1 5 1
1 3 3 3 3 3 3 0 2 0 2 2 0 0 5 5 5 5 5 5 1
1 3 1 3 1 0 1 2 1 2 1 2 1 0 1 5 1 5 1 5 1
1 0 0 3 0 0 2 2 2 2 2 2 0 4 4 5 5 5 5 5 1
1 0 1 3 1 3 1 6 1 0 1 2 1 4 1 4 1 5 1 0 1
1 3 6 3 3 3 3 6 2 6 2 0 0 4 4 4 4 5 4 4 1
1 6 1 3 1 3 1 6 1 6 1 2 1 5 1 4 1 4 1 4 1
1 6 6 6 6 6 3 6 3 3 0 2 0 5 5 5 4 4 4 4 1
1 6 1 6 1 0 1 6 1 6 1 2 1 5 1 5 1 4 1 4 1
1 6 6 6 6 6 6 6 6 6 6 0 2 5 5 5 5 5 4 4 1
1 3 3 3 6 6 6 0 2 2 2 2 0 5 5 5 5 5 5 5 1
1 3 1 3 1 6 1 2 1 0 1 2 1 2 1 5 1 5 1 5 1
1 3 3 3 6 6 0 2 2 2 2 2 0 2 0 5 5 5 5 4 1
1 3 1 3 1 0 1 2 1 2 1 2 1 2 1 0 1 5 1 4 1
1 3 3 3 3 0 2 2 2 2 0 0 2 2 2 0 5 5 5 4 1
1 3 1 3 1 2 1 2 1 2 1 2 1 2 1 2 1 5 1 4 1
1 6 3 3 0 2 2 0 0 2 2 2 2 2 2 0 5 5 5 5 1
1 6 1 0 1 2 1 2 1 2 1 0 1 0 1 2 1 5 1 4 1
1 6 6 0 0 2 0 2 2 2 2 0 2 2 2 0 4 5 4 4 1
1 6 1 0 1 2 1 2 1 2 1 2 1 0 1 2 1 4 1 4 1
1 6 6 6 0 2 2 2 2 2 2 2 2 2 0 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
9 5 5 137.68300000000002
5 12 2 138.5
3 12 1 139.70000000000022
4 13 2 140.5
3
3 13 1 1 2 1 2 2
3 13 2 0 4 2 0 2
7 3 3 3 3 5 0 2
1
11 11 0
5 16 2 87.5
3
7 4 0 0 5 1 2 1
9 17 1 0 3 2 1 0
4 5 3 0 3 1 2 2
1
3 6 4

View File

@ -318,7 +318,7 @@ def decision(programme, indiceJoueur, plateau, plateauCouleur, bombes, joueurs,
print(len(joueurs)-joueurs.count(None), file=entrees)
for j, joueur in enumerate(joueurs):
if joueur!=None:
print(joueur[J_LIGNE], joueur[J_COLONNE], j, joueur[J_VITESSE], joueur[J_NOMBREBOMBES], joueur[J_LONGUEURFLAMMES], joueur[J_DASHSRESTANTS], joueur[J_PIEGESRESTANTS], file=entrees)
print(joueur[J_LIGNE], joueur[J_COLONNE], j, joueur[J_VITESSE], joueur[J_BOMBESRESTANTES], joueur[J_LONGUEURFLAMMES], joueur[J_DASHSRESTANTS], joueur[J_PIEGESRESTANTS], file=entrees)
print(len(powerups), file=entrees)
for pu in powerups:
print(pu[PU_LIGNE], pu[PU_COLONNE], pu[PU_NATURE], file=entrees)
@ -340,7 +340,7 @@ def simulation(strategies):
execute_evenement(evenements, evenement, plateau, plateauCouleur, bombes, joueurs, powerups, pieges)
affiche_plateau(canvas, plateau, plateauCouleur, bombes, joueurs, powerups)
affiche_infos(canvasInfosJoueurs, joueurs, plateauCouleur)
temps = int((evenements[0][0]-evenement[0])/3*100)
temps = int((evenements[0][0]-evenement[0])/3*200)
if temps != 0:
fenetre.after(temps, pas_de_jeu)
else: