diff --git a/again b/again index 91b5cbc..ea035a8 100755 Binary files a/again and b/again differ diff --git a/again.cmi b/again.cmi index d0fb4ca..925472d 100644 Binary files a/again.cmi and b/again.cmi differ diff --git a/again.cmx b/again.cmx index e80fd65..6b60a85 100644 Binary files a/again.cmx and b/again.cmx differ diff --git a/again.ml b/again.ml index fece1cd..38721e4 100644 --- a/again.ml +++ b/again.ml @@ -433,7 +433,7 @@ let generate_gain_map (gd : game_data) = 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 + if is_valid nx ny lines cols && gd.laby.(l).(c) <> 3+gd.player_id then begin res.(nx).(ny) <- res.(nx).(ny) + 1; if (gd.laby.(l).(c) >= 3) then res.(nx).(ny) <- res.(nx).(ny) + 1; @@ -683,59 +683,6 @@ let is_dead_all (dgs : danger_map) (x : int) (y : int) (t : float) (dt : float) (* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) (* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) - -(*let goto_tile (gd : game_data) (dgs : danger_map) (x0 : int) (y0 : int) (end_x : int) (end_y : int) (stime : float) = - let lines = Array.length gd.laby - and cols = Array.length gd.laby.(0) in - - let pid = gd.player_id 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 - - (*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 ; - - 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_all dgs x y ct interval false) && - ct < stime +. 70. *. interval && - not (Array.fold_left (fun acc (b : bomb) -> acc || (b.xy.x = x && b.xy.y = y)) false gd.bombs) - then begin (* is not lethal *) - if - (is_empty_lst dgs.explosionTimes.(x).(y)) && (* safe *) - (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) - end; - (*Queue.add (x, y, ct +. interval, direction) q ;*) - if 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) && 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 - end - done; - 4 ; - with - | ReturnInt k -> k ;;*) - -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) let contains_crate (gd : game_data) = Array.fold_left @@ -964,56 +911,148 @@ let move_crate (gd : game_data) (dgs : danger_map) = (* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) (* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) -(* let goto_tile (gd : game_data) (dgs : danger_map) (x0 : int) (y0 : int) (end_x : int) (end_y : int) (stime : float) = *) - -(*let draw_random (gd : game_data) (infx : int) (infy : int) (lines : int) (cols : int) (dmin : int) = - (* get a random, valid tile *) - let xres = ref (-1) - and yres = ref (-1) in - while not (is_valid !xres !yres lines cols && gd.laby.(!xres).(!yres) >= 3 && gd.laby.(!xres).(!yres) <> 3 + gd.player_id && not (Array.fold_left (fun acc (b : bomb) -> acc || (b.xy.x = !xres && b.xy.y = !yres)) false gd.bombs)) do - xres := infx + Random.int (lines - infx) ; - yres := infy + Random.int (cols - infy) ; - done; - (!xres, !yres) ;; - -let nloops = 70 ;; -let move_land_2 (gd : game_data) (dgs : danger_map) (gns : int array array) = +let bfs_for_land ?return_x:(retx=fodder) ?return_y:(rety=fodder) ?return_ok:(retfl=bodder) (skip_near : bool) (gd : game_data) (dgs : danger_map) (x0 : int) (y0 : int) (target_x : int) (target_y : int) ?leniency:(lenc=1) (stime : float) (minDist : int) (maxDist : int) = 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 + let pid = gd.player_id in + + let needs_gtfo = not (is_empty_lst dgs.explosionTimes.(x0).(y0)) in + (*let nearest_player = min_dist_with_dash gd gd.players.(pid).xy.x gd.players.(pid).xy.y in*) + let nearest_player = min_dist_from_player gd gd.players.(pid).xy.x gd.players.(pid).xy.y in + + let undead_end_tiles = generate_dead_end_map gd in + + if gd.player_id = 4 then begin + for l = 0 to Array.length undead_end_tiles -1 do + for c = 0 to Array.length undead_end_tiles.(l) -1 do + if undead_end_tiles.(l).(c) >= 727 then + Printf.fprintf stderr "- " + else + Printf.fprintf stderr "%d " undead_end_tiles.(l).(c); + done; + Printf.fprintf stderr "\n"; + done + end ; + + Queue.add (x0, y0, stime +. interval, 4, 1) 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, polar) = Queue.pop q in + (*Printf.fprintf stderr "at (%d %d)\n" x y;*) + 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 false) && + ct < stime +. (float_of_int maxDist) *. interval && + not (Array.fold_left (fun acc (b : bomb) -> acc || (b.xy.x = x && b.xy.y = y)) false gd.bombs) && + polar <= 4 + then begin (* is not lethal *) + if false && ct <= stime +. 3. *. interval then begin + Printf.fprintf stderr "(at %d %d) %b %b %b\n" x y + (ct >= stime +. (float_of_int minDist) *. interval) (* not too deep *) + (is_empty_lst dgs.explosionTimes.(x).(y)) (* safe *) + (needs_gtfo || undead_end_tiles.(x).(y) * 2 <= nearest_player) (* is not going to be an ez kill *) + end; + if + (ct >= stime +. (float_of_int minDist) *. interval) && (* not too deep *) + (is_empty_lst dgs.explosionTimes.(x).(y)) && (* safe *) + (needs_gtfo || undead_end_tiles.(x).(y) * 2 <= nearest_player) && (* is not going to be an ez kill *) + (skip_near || tile_distance gd x y target_x target_y <= lenc) (* close enough to target *) + then begin + retx := x ; + rety := y ; + raise (ReturnInt direction) + end; + if not (x0 = x && y0 = y) && (needs_gtfo || undead_end_tiles.(x).(y) * 2 <= nearest_player) then begin + for dir = 0 to 3 do + Queue.add (x + (fst order.(dir)), y + (snd order.(dir)), ct +. interval, direction, polar) q ; + done; + Queue.add (x, y, ct +. interval, direction, polar+1) q + end + end + end + end + done; + retfl := false ; + 4 ; + with + | ReturnInt k -> + retfl := true ; + k ;; + +let move_land (gd : game_data) (dgs : danger_map) (gn : int array array) = + let max_cols = Array.mapi + (fun i lne -> + Array.fold_left + (fun acc (idc, sco) -> + if sco > snd acc then + (idc, sco) + else + acc + ) + (0, 0) + (Array.mapi (fun j v -> (j, v)) lne) + ) + gn + in + let (xmax, ymax, _) = Array.fold_left + (fun (cxm, cym, cvm) (nx, ny, nv) -> + if nv > cvm then + (nx, ny, nv) + else + (cxm, cym, cvm) + ) + (0, 0, 0) + (Array.mapi (fun i (j, v) -> (i, j, v)) max_cols) + in let pid = gd.player_id in let cxi = gd.players.(pid).xy.x and cyi = gd.players.(pid).xy.y in - try - for azertyiop = 0 to nloops -1 do - let (x, y) = draw_random gd 0 0 lines cols 4 in - let result_0 = goto_tile gd dgs cxi cyi x y gd.dt in - if result_0 <> 4 then begin - if - gd.players.(pid).bomb_to_place > 0 && - not (Array.fold_left (fun acc (b : bomb) -> acc || (b.xy.x = cxi && b.xy.y = cyi)) false gd.bombs) && - (is_empty_lst dgs.explosionTimes.(cxi).(cyi)) - then begin - if logg then Printf.fprintf stderr "trying...\n" ; - let _ = simulate_bomb_deconstruct gd dgs cxi cyi gd.players.(pid).bomb_radius (gd.dt +. 5.5) in - let result = goto_tile gd dgs cxi cyi x y gd.dt in - if result <> 4 then begin - action := 1 ; - raise (ReturnInt result) - end - end; - raise (ReturnInt result_0) - end - done; - 4 - with - | ReturnInt k -> k ;;*) + if logg then Printf.fprintf stderr "going at (%d, %d) [score=%d]\n" xmax ymax gn.(xmax).(ymax); + + (* try to place a bomb *) + let is_safe = is_empty_lst dgs.explosionTimes.(cxi).(cyi) in + let saved_p = simulate_bomb_deconstruct gd dgs cxi cyi gd.players.(pid).bomb_radius (gd.dt +. 5.5) in + let is_good = ref false in + + let result_bomb = bfs_for_land ~return_ok:is_good true gd dgs cxi cyi xmax ymax gd.dt 1 80 in + if is_safe && !is_good then begin + if logg then Printf.fprintf stderr "kaboom\n" ; + action := 1 ; + result_bomb + end + else begin + reverse_simulate_bomb dgs saved_p ; + + let res = bfs_for_land ~return_ok:is_good false gd dgs cxi cyi xmax ymax gd.dt 1 80 in + if !is_good then begin + if logg then Printf.fprintf stderr "going to kaboom\n" ; + res + end + else begin + if logg then Printf.fprintf stderr "E\n" ; + let res = bfs_for_land ~leniency:20 false gd dgs cxi cyi xmax ymax gd.dt 1 80 in + res + end + end ;; + (* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) (* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) -let exists_crate (gd : game_data) = +let exists_crate (gd : game_data) (dgs : danger_map) = Array.exists (fun line -> Array.exists (fun tile -> tile = 2) line) gd.laby ;; @@ -1035,15 +1074,13 @@ print_dangers danger_data ;;*) print_dangers danger_data ;;*) let direction = ref 4 ;; -if exists_crate game_map then begin +if exists_crate game_map danger_data then begin if logg then Printf.fprintf stderr "Crates\n" ; direction := move_crate game_map danger_data end else begin if logg then Printf.fprintf stderr "No crates\n" ; - Printf.fprintf stderr "WIN\n" ; - (*direction := move_land game_map danger_data gain_map *) - (*direction := move_land_2 game_map danger_data gain_map *) + direction := move_land game_map danger_data gain_map end ;; Printf.printf "%d %d" !direction !action ; diff --git a/again.o b/again.o index e282706..124b249 100644 Binary files a/again.o and b/again.o differ diff --git a/entrees.txt b/entrees.txt index 87ff3b9..5cb7cde 100644 --- a/entrees.txt +++ b/entrees.txt @@ -1,22 +1,25 @@ -164.0 -2 +192.1625000000009 +1 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 0 0 0 0 0 3 3 3 3 3 3 5 5 5 1 -1 3 1 3 1 0 1 6 1 6 1 3 1 3 1 0 1 5 1 5 1 -1 3 3 3 3 3 0 6 0 6 5 3 5 3 3 4 5 5 5 5 1 -1 3 1 3 1 3 1 6 1 6 1 6 1 4 1 6 1 4 1 5 1 -1 3 3 6 6 6 6 6 6 6 6 6 6 6 6 6 3 4 0 5 1 -1 6 1 6 1 3 1 6 1 6 1 6 1 6 1 6 1 4 1 0 1 -1 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 0 1 -1 6 1 6 1 3 1 6 1 6 1 6 1 6 1 6 1 4 1 4 1 -1 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 1 -1 6 1 6 1 6 1 6 1 6 1 6 1 6 1 6 1 4 1 4 1 -1 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 4 4 4 1 +1 3 3 3 3 3 3 4 3 3 3 3 3 3 3 4 3 3 5 5 1 +1 3 1 3 1 3 1 4 1 0 1 3 1 3 1 4 1 5 1 5 1 +1 3 3 3 4 6 4 4 4 5 5 4 3 4 4 4 4 4 4 4 1 +1 3 1 3 1 6 1 4 1 5 1 4 1 4 1 4 1 4 1 4 1 +1 3 3 6 6 6 4 6 4 5 5 5 5 5 5 5 5 4 5 4 1 +1 3 1 3 1 6 1 6 1 5 1 4 1 4 1 4 1 4 1 4 1 +1 3 3 6 6 5 5 5 5 5 5 5 5 5 3 4 4 4 4 4 1 +1 6 1 3 1 3 1 6 1 5 1 4 1 4 1 4 1 4 1 4 1 +1 6 3 3 3 6 6 6 4 5 4 6 4 6 4 6 4 4 4 4 1 +1 6 1 3 1 3 1 6 1 5 1 6 1 6 1 6 1 4 1 4 1 +1 6 6 3 3 6 6 6 6 5 6 6 6 6 6 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 -0 -3 -3 10 0 4 3 2 3 1 -5 10 2 0 2 3 1 4 -7 10 3 3 4 6 2 1 +4 +7 16 3 192.41370000000083 +6 15 3 193.72590000000085 +5 14 3 195.03810000000087 +10 7 4 195.5400000000004 +2 +7 12 1 4 1 3 2 3 +11 5 2 2 0 4 1 3 0 diff --git a/iachallenge2024_bomberman_tkinter.py b/iachallenge2024_bomberman_tkinter.py index fd93e74..0786864 100644 --- a/iachallenge2024_bomberman_tkinter.py +++ b/iachallenge2024_bomberman_tkinter.py @@ -454,6 +454,7 @@ def execute_evenement(evenements, evenement, plateau, plateauCouleur, bombes, jo ip, jp = prochain(i,j,direction) ajoute_evenement(evenements, [evenement[0]+TEMPS_PROPAGATION, EVENEMENT_PROPAGATION, ip, jp, direction, longueurFlammes-1, indJoueur]) +NB_TROUS = 20 TAILLE_TUILE = 40 HAUTEUR_JOUEUR = TAILLE_TUILE @@ -528,7 +529,7 @@ def simulation(strategies): dimensions = 13,21 positionsInitiales=[(1, 1), (dimensions[0]-2, dimensions[1]-2), (1, dimensions[1]-2), (dimensions[0]-2, 1)] - plateau = cree_plateau_initial(dimensions[0]-2, dimensions[1]-2, 20) + plateau = cree_plateau_initial(dimensions[0]-2, dimensions[1]-2, NB_TROUS) plateauCouleur = [[-1 for j in range(dimensions[1])] for i in range(dimensions[0])] evenements = [] diff --git a/sortie.txt b/sortie.txt index 7cc0f37..45bfd49 100644 --- a/sortie.txt +++ b/sortie.txt @@ -1 +1 @@ -4 0 \ No newline at end of file +3 1 \ No newline at end of file