diff --git a/again b/again index 6a935d4..e12571c 100755 Binary files a/again and b/again differ diff --git a/again.cmi b/again.cmi index 3e7a71b..3730a6d 100644 Binary files a/again.cmi and b/again.cmi differ diff --git a/again.cmx b/again.cmx index 9301440..8c59f2e 100644 Binary files a/again.cmx and b/again.cmx differ diff --git a/again.ml b/again.ml index 39506c7..6ddcc94 100644 --- a/again.ml +++ b/again.ml @@ -31,7 +31,7 @@ type player = { id : int ; xy : pt ; nspeed : int ; - nbomb_atonce : int ; + bomb_to_place : int ; bomb_radius : int ; ndash : int ; ntraps : int ; @@ -57,7 +57,7 @@ and default_player = { id = -1 ; xy = default_point ; nspeed = 0 ; - nbomb_atonce = 0 ; + bomb_to_place = 0 ; bomb_radius = 0 ; ndash = 0 ; ntraps = 0 ; @@ -168,7 +168,7 @@ let print_game_data (gd : game_data) = done; Printf.fprintf stderr "Players (%d) : \n" gd.nplayers ; for b = 0 to gd.nplayers -1 do - Printf.fprintf stderr " [Player %d] (at %d %d) (holding %d %d %d %d %d)\n" gd.players.(b).id gd.players.(b).xy.x gd.players.(b).xy.y gd.players.(b).nspeed gd.players.(b).nbomb_atonce gd.players.(b).bomb_radius gd.players.(b).ndash gd.players.(b).ntraps ; + Printf.fprintf stderr " [Player %d] (at %d %d) (holding %d %d %d %d %d)\n" gd.players.(b).id gd.players.(b).xy.x gd.players.(b).xy.y gd.players.(b).nspeed gd.players.(b).bomb_to_place gd.players.(b).bomb_radius gd.players.(b).ndash gd.players.(b).ntraps ; done; Printf.fprintf stderr "Boosts (%d) : \n" gd.nboosts ; for b = 0 to gd.nboosts -1 do @@ -200,6 +200,10 @@ let rec ln_b b = function | k when k < b -> 0 | k -> 1 + ln_b b (k/b) ;; +let int_of_bool = function + | false -> 0 + | true -> 1 ;; + let get_meta_info (pid : int) = let ptr = open_in ("main_"^(string_of_int pid)^".sav") in let fct0 () = match (int_of_string (input_line ptr)) with @@ -303,7 +307,7 @@ let parse_input (str : string) = res.players <- Array.make 4 default_player ; for p = 0 to res.nplayers -1 do let dat = int_n_of_string (input_line ptr) 8 useless in - res.players.(dat.(2)) <- {id = dat.(2) ; xy = {x = dat.(0) ; y = dat.(1) ;} ; nspeed = dat.(3) ; nbomb_atonce = dat.(4) ; bomb_radius = dat.(5) ; ndash = dat.(6) ; ntraps = dat.(7) ;} + res.players.(dat.(2)) <- {id = dat.(2) ; xy = {x = dat.(0) ; y = dat.(1) ;} ; nspeed = dat.(3) ; bomb_to_place = dat.(4) ; bomb_radius = dat.(5) ; ndash = dat.(6) ; ntraps = dat.(7) ;} done; (* boosts *) @@ -505,7 +509,7 @@ let tile_distance (gd : game_data) (x0 : int) (y0 : int) (end_x : int) (end_y : if (x = end_x && y = end_y) then begin raise (ReturnInt depth) end; - if not (x0 == x && y0 == y) then begin + if true then begin for dir = 0 to 3 do Queue.add (x + (fst order.(dir)), y + (snd order.(dir)), depth+1) q ; done; @@ -547,82 +551,50 @@ let amt_free_adj_spaces (gd : game_data) (x : int) (y : int) = 0 order ;; -let max_depth = 12345 ;; -let is_player_nearby (gd : game_data) (x0 : int) (y0 : int) (detect_dist : int) = - let mind = min_dist_from_player gd x0 y0 in - (mind <= detect_dist) ;; +let generate_dead_end_map (gd : game_data) = + (* links every cell that has at least 3 neighbors *) -let is_dead_end (gd : game_data) (xstart : int) (ystart : int) (xban : int) (yban : int) = - if not (is_player_nearby gd gd.players.(gd.player_id).xy.x gd.players.(gd.player_id).xy.y 3) 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 - | _ -> raise (ReturnBool false) - end - end - in - try - aux xstart ystart; - true ; - with - | ReturnBool b -> b - end ;; - -let has_multiple_escapes (gd : game_data) (xstart : int) (ystart : int) (xban : int) (yban : int) = let lines = Array.length gd.laby and cols = Array.length gd.laby.(0) 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 + let res = Array.make_matrix lines cols false in + (* false = dead end (or wall), true = not a dead end *) - Queue.add (xstart, ystart, 0, false) q; + let pid = gd.player_id in + let visited = Hashtbl.create (lines * cols) in + + let rec dfs x y prev last_dir = + if + (is_valid x y lines cols) && + (Hashtbl.find_opt visited (x, y) = None) && + (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)) && + (not (Array.fold_left (fun acc (p : player) -> acc || (p.xy.x = x && p.xy.y = y && p.id <> pid)) false gd.players)) + then begin + Hashtbl.add visited (x, y) 1 ; + if (amt_free_adj_spaces gd x y) >= 3 then begin + if prev <> [] then + Hashtbl.remove visited (x, y) ; + List.iter (fun (cx, cy) -> res.(cx).(cy) <- true) ((x, y)::prev) ; + for dir = 0 to 3 do + if (dir + 2) mod 4 <> last_dir then (* dont backtrack *) + dfs (x + fst (order.(dir))) (y + snd (order.(dir))) [] dir + done + end + else begin + for dir = 0 to 3 do + if (dir + 2) mod 4 <> last_dir then + dfs (x + fst (order.(dir))) (y + snd (order.(dir))) ((x, y)::prev) dir + done + end + end + in + dfs gd.players.(pid).xy.x gd.players.(pid).xy.y [] 4 ; + res ;; - try - 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 k -> k - end ;; - -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 is_player_nearby (gd : game_data) (x0 : int) (y0 : int) (detect_dist : int) = + let mind = min_dist_from_player gd x0 y0 in + if x0 = gd.players.(gd.player_id).xy.x && y0 = gd.players.(gd.player_id).xy.y then Printf.fprintf stderr "[player %d] %d\n" gd.player_id mind ; + (mind <= detect_dist) ;; let reverse_simulate_bomb (dgs : danger_map) (save : (int * int, float) Hashtbl.t) = Hashtbl.iter @@ -662,7 +634,7 @@ 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 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 @@ -710,7 +682,7 @@ let goto_tile (gd : game_data) (dgs : danger_map) (x0 : int) (y0 : int) (end_x : done; 4 ; with - | ReturnInt k -> k ;; + | ReturnInt k -> k ;;*) (* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) (* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) @@ -784,6 +756,19 @@ let bfs_for_crate (gd : game_data) (dgs : danger_map) (x0 : int) (y0 : int) (sti 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 undead_end_tiles = generate_dead_end_map gd in + + (*if gd.player_id = 0 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 + Printf.fprintf stderr "%d " (int_of_bool 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 ; @@ -805,15 +790,13 @@ 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 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 (is_player_nearby gd x y 4 && not undead_end_tiles.(x).(y))) && (* is not going to be an ez kill *) (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; - (*Queue.add (x, y, ct +. interval, direction, polar+1) q ;*) - if not (x0 == x && y0 == 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)) then begin + if not (x0 == x && y0 == y) && (needs_gtfo || not (is_player_nearby gd x y 5 && not undead_end_tiles.(x).(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; @@ -831,15 +814,38 @@ 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_for_crate gd dgs cxi cyi gd.dt false true false 0 false 7 in - if bonusres <> 4 then begin - if logg then Printf.fprintf stderr "bonus spotted\n" ; - raise (ReturnInt bonusres) ; + (* send away a player standing right on top *) + if Array.exists (fun (p : player) -> p.id <> pid && p.xy.x = cxi && p.xy.y = cyi) gd.players then begin + if gd.players.(pid).bomb_to_place > 0 then begin + if logg then Printf.fprintf stderr "oh no you dont\n" ; + let saved_p = simulate_bomb_deconstruct dgs cxi cyi gd.players.(pid).bomb_radius (gd.dt +. 5.5) in + + let bonusres_2p = bfs_for_crate gd dgs cxi cyi gd.dt false true false 0 false 7 in + if bonusres_2p <> 4 then begin + if logg then Printf.fprintf stderr "mine\n" ; + raise (ReturnInt bonusres_2p) ; + end; + + let resultp = bfs_for_crate gd dgs cxi cyi gd.dt false false true 1 false 80 in + if resultp <> 4 then begin + if logg then Printf.fprintf stderr "go away\n" ; + action := 1 ; + raise (ReturnInt resultp) ; + end; + reverse_simulate_bomb dgs saved_p ; + end end; 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 gd.players.(pid).bomb_to_place > 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 bonusres_2 = bfs_for_crate gd dgs cxi cyi gd.dt false true false 0 false 7 in + if bonusres_2 <> 4 then begin + if logg then Printf.fprintf stderr "Bonus Spotted\n" ; + raise (ReturnInt bonusres_2) ; + end; + let result = bfs_for_crate gd dgs cxi cyi gd.dt false false true 1 false 80 in if result <> 4 then begin action := 1 ; @@ -851,6 +857,11 @@ let move_crate (gd : game_data) (dgs : danger_map) = raise (ReturnInt 4) end; end; + let bonusres = bfs_for_crate gd dgs cxi cyi gd.dt false true false 0 false 7 in + if bonusres <> 4 then begin + if logg then Printf.fprintf stderr "bonus spotted\n" ; + raise (ReturnInt bonusres) ; + end; if logg then Printf.fprintf stderr "searching...\n" ; let rescr = bfs_for_crate gd dgs cxi cyi gd.dt true false false 0 false 80 in if rescr <> 4 then @@ -868,61 +879,7 @@ 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 move_land (gd : game_data) (dgs : danger_map) (gns : int array array) = - let pid = gd.player_id in - let cxi = gd.players.(pid).xy.x - and cyi = gd.players.(pid).xy.y in - let max_map = Array.mapi - (fun i line -> Array.mapi - (fun j elt -> - if (gd.laby.(i).(j) <> 1 && gd.laby.(i).(j) <> 2 && not (Array.fold_left (fun acc (b : bomb) -> acc || (b.xy.x = i && b.xy.y = j)) false gd.bombs)) then - (elt, i, j) - else - (-1, i, j) - ) - line - ) - gns - in - let (_, xmax, ymax) = Array.fold_left - (fun (vm, xm, ym) line -> - let (otm, xtm, ytm) = Array.fold_left - (fun (vm2, xm2, ym2) (i, j, v) -> - if vm2 > v then - (vm2, xm2, ym2) - else - (i, j, v) - ) (-1, -1, -1) line - in - if vm > otm then - (vm, xm, ym) - else - (otm, xtm, ytm) - ) (-1, -1, -1) max_map - in - Printf.fprintf stderr "(%d %d) -> (%d %d)\n" cxi cyi xmax ymax ; - try - if cxi = xmax && cyi = ymax && (is_empty_lst dgs.explosionTimes.(cxi).(cyi)) then begin (* standing on right tile *) - 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 = goto_tile gd dgs cxi cyi xmax ymax gd.dt in - if result <> 4 then begin - action := 1 ; - raise (ReturnInt result) ; - end; - reverse_simulate_bomb dgs saved ; - raise (ReturnInt 4) - end - else - raise (ReturnInt 4) - end - else - raise (ReturnInt (goto_tile gd dgs cxi cyi xmax ymax gd.dt)) - with - | ReturnInt k -> k ;; - -let draw_random (gd : game_data) (infx : int) (infy : int) (lines : int) (cols : int) (dmin : int) = +(*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 @@ -947,7 +904,7 @@ let move_land_2 (gd : game_data) (dgs : danger_map) (gns : int array array) = let result_0 = goto_tile gd dgs cxi cyi x y gd.dt in if result_0 <> 4 then begin if - gd.players.(pid).nbomb_atonce > 0 && + 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 @@ -964,7 +921,7 @@ let move_land_2 (gd : game_data) (dgs : danger_map) (gns : int array array) = done; 4 with - | ReturnInt k -> k ;; + | ReturnInt k -> k ;;*) (* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) (* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) @@ -992,16 +949,15 @@ print_dangers danger_data ;;*) let direction = ref 4 ;; if exists_crate game_map then begin - Printf.fprintf stderr "Crates\n" ; + if logg then Printf.fprintf stderr "Crates\n" ; direction := move_crate game_map danger_data end else begin - Printf.fprintf stderr "No crates\n" ; + if logg then Printf.fprintf stderr "No crates\n" ; (*direction := move_land game_map danger_data gain_map *) - direction := move_land_2 game_map danger_data gain_map + (*direction := move_land_2 game_map danger_data gain_map *) end ;; - Printf.printf "%d %d" !direction !action ; if true || logg then Printf.fprintf stderr "[player %d] %d %d (at time %f)\n" game_map.player_id !direction !action game_map.dt; diff --git a/again.o b/again.o index 60d8fd2..3f3905d 100644 Binary files a/again.o and b/again.o differ diff --git a/entrees.txt b/entrees.txt index a673742..496b05c 100644 --- a/entrees.txt +++ b/entrees.txt @@ -1,26 +1,25 @@ -183.6000000000002 +227.200000000001 0 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 0 0 0 4 4 4 4 5 5 5 5 5 1 -1 3 1 3 1 3 1 3 1 0 1 0 1 4 1 4 1 5 1 5 1 -1 3 6 3 6 3 3 3 3 3 3 3 4 4 4 4 4 5 5 5 1 -1 3 1 0 1 3 1 3 1 3 1 0 1 4 1 4 1 4 1 5 1 -1 6 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 5 4 5 1 -1 3 1 3 1 6 1 3 1 5 1 5 1 5 1 5 1 4 1 4 1 -1 3 3 6 6 5 5 3 5 5 5 5 5 5 5 5 5 4 4 4 1 -1 3 1 3 1 6 1 5 1 5 1 5 1 5 1 5 1 4 1 4 1 -1 3 6 3 6 6 6 5 6 6 5 5 5 5 5 5 4 4 4 4 1 -1 6 1 6 1 3 1 4 1 5 1 5 1 5 1 4 1 4 1 4 1 -1 6 6 6 4 4 4 4 4 4 4 6 5 5 5 5 4 4 4 4 1 +1 3 3 3 3 3 0 0 0 3 3 3 3 3 3 4 4 4 4 5 1 +1 3 1 3 1 3 1 3 1 0 1 3 1 5 1 5 1 4 1 5 1 +1 3 3 3 3 3 2 3 0 3 5 3 5 5 5 4 5 4 5 5 1 +1 3 1 3 1 3 1 3 1 3 1 3 1 5 1 4 1 4 1 5 1 +1 3 3 3 3 3 3 3 3 3 3 3 3 5 5 5 5 4 5 4 1 +1 3 1 3 1 3 1 3 1 3 1 5 1 5 1 4 1 4 1 4 1 +1 3 3 3 3 3 3 3 3 3 4 4 4 5 4 4 4 4 4 4 1 +1 3 1 3 1 6 1 3 1 3 1 3 1 5 1 4 1 4 1 4 1 +1 6 3 3 6 6 6 6 6 6 6 6 4 4 4 4 4 4 4 4 1 +1 6 1 6 1 6 1 6 1 6 1 6 1 4 1 4 1 4 1 4 1 +1 6 6 6 6 6 6 6 6 6 6 6 0 4 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 -3 -8 9 3 186.5850000000011 -2 7 2 187.30000000000018 -9 10 3 188.04300000000111 -4 -1 8 0 1 1 2 1 4 -9 8 1 3 1 3 1 1 -9 8 2 1 4 2 2 0 -9 11 3 1 4 2 0 2 0 +4 +1 9 0 1 7 3 4 2 +3 15 1 1 2 4 2 6 +1 13 2 1 1 3 2 5 +3 9 3 2 3 2 3 0 +2 +1 7 3 +1 8 4 diff --git a/iachallenge2024_bomberman_tkinter.py b/iachallenge2024_bomberman_tkinter.py index c048f8a..12f600c 100644 --- a/iachallenge2024_bomberman_tkinter.py +++ b/iachallenge2024_bomberman_tkinter.py @@ -427,6 +427,7 @@ def execute_evenement(evenements, evenement, plateau, plateauCouleur, bombes, jo indiceJoueur = trouve_objet(i,j,joueurs) while indiceJoueur != None: joueurs[indiceJoueur] = None + print("DEATH :", indiceJoueur) indiceJoueur = trouve_objet(i,j,joueurs) # On fait exploser la bombe s'il y en a une @@ -541,5 +542,6 @@ def simulation(strategies): fenetre.mainloop() return +#simulation(["./again"]) #simulation(["./again", "./again"]) simulation(["./again", "./again", "./again", "./again"]) diff --git a/sortie.txt b/sortie.txt index 92880af..e69de29 100644 --- a/sortie.txt +++ b/sortie.txt @@ -1 +0,0 @@ -1 1 \ No newline at end of file