diff --git a/again b/again index 4aedcf8..4805f31 100755 Binary files a/again and b/again differ diff --git a/again.cmi b/again.cmi index 5855c1d..edfad43 100644 Binary files a/again.cmi and b/again.cmi differ diff --git a/again.cmo b/again.cmo index e9551c0..6b8dba2 100644 Binary files a/again.cmo and b/again.cmo differ diff --git a/again.ml b/again.ml index 7a17582..1cc1835 100644 --- a/again.ml +++ b/again.ml @@ -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,99 +550,34 @@ 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 - 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 *) + 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, 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) ;*) - 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_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 + (*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, polar) q ; + done; + end end end end @@ -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) ; - if (is_a_crate_nearby gd dgs) && (is_empty_lst dgs.explosionTimes.(cxi).(cyi)) then begin - 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 - action := 1 ; - raise (ReturnInt result) ; - end - else - raise (ReturnInt 4) + 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; - bfs_for_crate gd dgs cxi cyi gd.dt + if (is_a_crate_nearby gd dgs) && (is_empty_lst dgs.explosionTimes.(cxi).(cyi)) then begin + 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_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 begin + raise (ReturnInt 4) + end; + 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 ;; diff --git a/entrees.txt b/entrees.txt index 65ba8d9..c46c416 100644 --- a/entrees.txt +++ b/entrees.txt @@ -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 diff --git a/iachallenge2024_bomberman_tkinter.py b/iachallenge2024_bomberman_tkinter.py index 851deb8..6f36173 100644 --- a/iachallenge2024_bomberman_tkinter.py +++ b/iachallenge2024_bomberman_tkinter.py @@ -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: