diff --git a/again b/again index f067460..d3d4952 100755 Binary files a/again and b/again differ diff --git a/again.cmi b/again.cmi index 5ae80a4..7ace879 100644 Binary files a/again.cmi and b/again.cmi differ diff --git a/again.cmo b/again.cmo index c649df1..b3c5c66 100644 Binary files a/again.cmo and b/again.cmo differ diff --git a/again.ml b/again.ml index f9fc8c2..8a8a415 100644 --- a/again.ml +++ b/again.ml @@ -446,6 +446,9 @@ let simulate_bomb_deconstruct (dgs : danger_map) (bx : int) (by : int) (bsize : done; saved_data ;; +(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) +(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) + let reverse_simulate_bomb (dgs : danger_map) (save : (int * int, float) Hashtbl.t) = Hashtbl.iter (fun (x, y) dt -> diff --git a/compil.sh b/compil.sh deleted file mode 100644 index a5fbb7d..0000000 --- a/compil.sh +++ /dev/null @@ -1 +0,0 @@ -ocamlc main.ml -o main \ No newline at end of file diff --git a/entrees.txt b/entrees.txt index 6f0a0e3..7179547 100644 --- a/entrees.txt +++ b/entrees.txt @@ -1,23 +1,27 @@ -157.4200000000005 -2 +6.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 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 5 4 4 1 -1 3 1 6 1 4 1 6 1 3 1 6 1 5 1 4 1 5 1 5 1 -1 3 3 6 3 4 6 6 6 3 6 6 6 5 4 4 4 4 4 4 1 -1 3 1 6 1 4 1 6 1 3 1 6 1 5 1 4 1 5 1 5 1 -1 4 4 6 4 4 4 4 4 4 6 6 6 6 6 6 6 6 4 4 1 -1 3 1 6 1 4 1 6 1 3 1 6 1 4 1 4 1 5 1 0 1 -1 3 3 3 3 4 3 4 4 4 4 5 4 4 4 4 5 5 5 4 1 -1 3 1 0 1 4 1 3 1 4 1 5 1 5 1 4 1 4 1 4 1 -1 6 6 6 3 4 4 4 4 4 4 5 4 4 3 4 5 5 5 4 1 -1 6 1 0 1 3 1 3 1 4 1 5 1 5 1 5 1 4 1 4 1 -1 6 0 6 6 6 6 6 6 4 6 6 6 6 6 6 6 6 4 4 1 +1 0 0 2 2 2 2 0 2 2 2 2 2 0 2 2 2 2 0 0 1 +1 0 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 0 1 +1 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 +1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 0 1 2 1 2 1 +1 2 0 2 0 0 2 2 2 0 2 2 0 2 2 2 2 2 2 2 1 +1 0 1 2 1 2 1 2 1 0 1 2 1 2 1 2 1 2 1 2 1 +1 2 2 0 2 2 2 2 2 2 2 2 2 0 2 0 2 2 2 2 1 +1 2 1 2 1 2 1 2 1 2 1 0 1 2 1 2 1 2 1 2 1 +1 2 2 2 2 2 0 0 0 2 2 2 2 2 2 2 2 2 2 2 1 +1 0 1 2 1 0 1 2 1 0 1 2 1 2 1 2 1 2 1 0 1 +1 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -0 4 -3 6 0 1 3 4 0 1 -10 5 1 3 3 4 1 2 -7 6 2 2 3 4 0 1 -3 5 3 7 3 5 0 5 +2 1 1 6.5 +10 19 1 6.5 +2 19 1 6.5 +10 1 1 6.5 +4 +1 2 0 0 0 1 0 0 +11 18 1 0 0 1 0 0 +1 18 2 0 0 1 0 0 +11 2 3 0 0 1 0 0 0 diff --git a/exec.sh b/exec.sh deleted file mode 100644 index 0ff119f..0000000 --- a/exec.sh +++ /dev/null @@ -1,2 +0,0 @@ -ocamlc main.ml -o main -./main \ No newline at end of file diff --git a/iachallenge2024_bomberman_tkinter.py b/iachallenge2024_bomberman_tkinter.py index 6f36173..2e06957 100644 --- a/iachallenge2024_bomberman_tkinter.py +++ b/iachallenge2024_bomberman_tkinter.py @@ -91,6 +91,77 @@ def cree_plateau_initial(lignes, colonnes, nombreDeTrous): plateau[i][j] = PLATEAU_VIDE return plateau +def affiche_powerup(canvas, couleurPowerup, j, k): + # COULEURS_POWERUPS = ["cyan", "orangered", "red", "magenta", "purple"] + if couleurPowerup == "orangered": + canvas.create_oval(j*TAILLE_TUILE+TAILLE_TUILE*1/5, k*TAILLE_TUILE+TAILLE_TUILE*2/5, j*TAILLE_TUILE+TAILLE_TUILE-TAILLE_TUILE*1/5, k*TAILLE_TUILE+TAILLE_TUILE, fill=couleurPowerup) + canvas.create_polygon( + j*TAILLE_TUILE+TAILLE_TUILE/2-TAILLE_TUILE/15, k*TAILLE_TUILE+TAILLE_TUILE*7/10, + j*TAILLE_TUILE+TAILLE_TUILE/2+TAILLE_TUILE/15, k*TAILLE_TUILE+TAILLE_TUILE*7/10, + j*TAILLE_TUILE+TAILLE_TUILE/2+TAILLE_TUILE/15, k*TAILLE_TUILE+TAILLE_TUILE/15, + j*TAILLE_TUILE+TAILLE_TUILE/2-TAILLE_TUILE/15, k*TAILLE_TUILE+TAILLE_TUILE/15, + fill=couleurPowerup) + #canvas.create_text((j+1)*TAILLE_TUILE+TAILLE_TUILE/2, (k+0.5)*TAILLE_TUILE, text=joueurs[i][J_NOMBREBOMBES]) + elif couleurPowerup == "red": + canvas.create_polygon( + j*TAILLE_TUILE+TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE, + j*TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE, + j*TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE*(randrange(7))/10, + j*TAILLE_TUILE+1*TAILLE_TUILE/6, k*TAILLE_TUILE+TAILLE_TUILE*(randrange(7))/10, + j*TAILLE_TUILE+2*TAILLE_TUILE/6, k*TAILLE_TUILE+TAILLE_TUILE*(randrange(7))/10, + j*TAILLE_TUILE+3*TAILLE_TUILE/6, k*TAILLE_TUILE+TAILLE_TUILE*(randrange(7))/10, + j*TAILLE_TUILE+4*TAILLE_TUILE/6, k*TAILLE_TUILE+TAILLE_TUILE*(randrange(7))/10, + j*TAILLE_TUILE+5*TAILLE_TUILE/6, k*TAILLE_TUILE+TAILLE_TUILE*(randrange(7))/10, + j*TAILLE_TUILE+6*TAILLE_TUILE/6, k*TAILLE_TUILE+TAILLE_TUILE*(randrange(7))/10, + outline="black", fill=couleurPowerup) + #canvas.create_text((j+1)*TAILLE_TUILE+TAILLE_TUILE/2, (k+0.5)*TAILLE_TUILE, text=joueurs[i][J_LONGUEURFLAMMES]) + elif couleurPowerup == "cyan": + canvas.create_polygon( + j*TAILLE_TUILE+TAILLE_TUILE/10, k*TAILLE_TUILE+TAILLE_TUILE/10, + j*TAILLE_TUILE+TAILLE_TUILE*2/5, k*TAILLE_TUILE+TAILLE_TUILE/10, + j*TAILLE_TUILE+TAILLE_TUILE*2/5, k*TAILLE_TUILE+TAILLE_TUILE/2, + j*TAILLE_TUILE+TAILLE_TUILE*9/10, k*TAILLE_TUILE+TAILLE_TUILE*7/10, + j*TAILLE_TUILE+TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE*9/10, + j*TAILLE_TUILE+TAILLE_TUILE/10, k*TAILLE_TUILE+TAILLE_TUILE*9/10, + outline="black", fill=couleurPowerup) + #canvas.create_text((j+1)*TAILLE_TUILE+TAILLE_TUILE/2, (k+0.5)*TAILLE_TUILE, text=joueurs[i][J_VITESSE]) + elif couleurPowerup == "magenta": + canvas.create_polygon( + j*TAILLE_TUILE, k*TAILLE_TUILE, + j*TAILLE_TUILE+TAILLE_TUILE*6/10, k*TAILLE_TUILE+TAILLE_TUILE/2, + j*TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE, + fill=couleurPowerup) + canvas.create_polygon( + j*TAILLE_TUILE+TAILLE_TUILE*4/10, k*TAILLE_TUILE, + j*TAILLE_TUILE+TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE/2, + j*TAILLE_TUILE+TAILLE_TUILE*4/10, k*TAILLE_TUILE+TAILLE_TUILE, + fill=couleurPowerup) + #canvas.create_text((j+1)*TAILLE_TUILE+TAILLE_TUILE/2, (k+0.5)*TAILLE_TUILE, text=joueurs[i][J_DASHSRESTANTS]) + elif couleurPowerup == "purple": + canvas.create_polygon( + j*TAILLE_TUILE+TAILLE_TUILE*1/10, k*TAILLE_TUILE+TAILLE_TUILE*7/10, + j*TAILLE_TUILE+TAILLE_TUILE*3/20, k*TAILLE_TUILE+TAILLE_TUILE*6/10, + j*TAILLE_TUILE+TAILLE_TUILE/2, k*TAILLE_TUILE+TAILLE_TUILE*8/10, + j*TAILLE_TUILE+TAILLE_TUILE*17/20, k*TAILLE_TUILE+TAILLE_TUILE*6/10, + j*TAILLE_TUILE+TAILLE_TUILE*9/10, k*TAILLE_TUILE+TAILLE_TUILE*7/10, + j*TAILLE_TUILE+TAILLE_TUILE/2, k*TAILLE_TUILE+TAILLE_TUILE*9/10, + fill=couleurPowerup) + + canvas.create_polygon(j*TAILLE_TUILE, k*TAILLE_TUILE, j*TAILLE_TUILE+TAILLE_TUILE/(TAILLE_OVERLAY), k*TAILLE_TUILE, j*TAILLE_TUILE+TAILLE_TUILE/(TAILLE_OVERLAY), k*TAILLE_TUILE+TAILLE_TUILE, j*TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE, fill="black") + canvas.create_polygon(j*TAILLE_TUILE, k*TAILLE_TUILE, j*TAILLE_TUILE+TAILLE_TUILE, k*TAILLE_TUILE, j*TAILLE_TUILE+TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE/(TAILLE_OVERLAY), j*TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE/(TAILLE_OVERLAY), fill="black") + canvas.create_polygon(j*TAILLE_TUILE+TAILLE_TUILE*(TAILLE_OVERLAY-1)/(TAILLE_OVERLAY), k*TAILLE_TUILE, j*TAILLE_TUILE+TAILLE_TUILE, k*TAILLE_TUILE, j*TAILLE_TUILE+TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE, j*TAILLE_TUILE+TAILLE_TUILE*(TAILLE_OVERLAY-1)/(TAILLE_OVERLAY), k*TAILLE_TUILE+TAILLE_TUILE, fill="black") + canvas.create_polygon(j*TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE*(TAILLE_OVERLAY-1)/(TAILLE_OVERLAY), j*TAILLE_TUILE+TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE*(TAILLE_OVERLAY-1)/(TAILLE_OVERLAY), j*TAILLE_TUILE+TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE, j*TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE, fill="black") + + for s in range(NOMBRE_SPARKS): + xr = randrange(1, SIZE_SPARKS-1) + yr = randrange(1, SIZE_SPARKS-1) + canvas.create_polygon( + j*TAILLE_TUILE+TAILLE_TUILE*xr/SIZE_SPARKS, k*TAILLE_TUILE+TAILLE_TUILE*yr/SIZE_SPARKS, + j*TAILLE_TUILE+TAILLE_TUILE*(xr+1)/SIZE_SPARKS, k*TAILLE_TUILE+TAILLE_TUILE*yr/SIZE_SPARKS, + j*TAILLE_TUILE+TAILLE_TUILE*(xr+1)/SIZE_SPARKS, k*TAILLE_TUILE+TAILLE_TUILE*(yr+1)/SIZE_SPARKS, + j*TAILLE_TUILE+TAILLE_TUILE*xr/SIZE_SPARKS, k*TAILLE_TUILE+TAILLE_TUILE*(yr+1)/SIZE_SPARKS, + fill="yellow") + def affiche_plateau(canvas, plateau, plateauCouleur, bombes, joueurs, powerups): canvas.delete(ALL) @@ -99,7 +170,25 @@ def affiche_plateau(canvas, plateau, plateauCouleur, bombes, joueurs, powerups): if plateau[i][j]==PLATEAU_PIERRE: canvas.create_rectangle(j*TAILLE_TUILE, i*TAILLE_TUILE, j*TAILLE_TUILE+TAILLE_TUILE, i*TAILLE_TUILE+TAILLE_TUILE, fill="black") elif plateau[i][j]==PLATEAU_BOIS: - canvas.create_rectangle(j*TAILLE_TUILE, i*TAILLE_TUILE, j*TAILLE_TUILE+TAILLE_TUILE, i*TAILLE_TUILE+TAILLE_TUILE, fill="brown") + canvas.create_rectangle(j*TAILLE_TUILE, i*TAILLE_TUILE, j*TAILLE_TUILE+TAILLE_TUILE, i*TAILLE_TUILE+TAILLE_TUILE, outline="black", fill="brown") + canvas.create_polygon( + j*TAILLE_TUILE+OFFSET_CRATE, i*TAILLE_TUILE, + j*TAILLE_TUILE, i*TAILLE_TUILE, + j*TAILLE_TUILE, i*TAILLE_TUILE+OFFSET_CRATE, + + j*TAILLE_TUILE+TAILLE_TUILE-OFFSET_CRATE, i*TAILLE_TUILE+TAILLE_TUILE, + j*TAILLE_TUILE+TAILLE_TUILE, i*TAILLE_TUILE+TAILLE_TUILE, + j*TAILLE_TUILE+TAILLE_TUILE, i*TAILLE_TUILE+TAILLE_TUILE-OFFSET_CRATE, + outline="black", fill="#94643E") + canvas.create_polygon( + j*TAILLE_TUILE+TAILLE_TUILE-OFFSET_CRATE, i*TAILLE_TUILE, + j*TAILLE_TUILE+TAILLE_TUILE, i*TAILLE_TUILE, + j*TAILLE_TUILE+TAILLE_TUILE, i*TAILLE_TUILE+OFFSET_CRATE, + + j*TAILLE_TUILE+OFFSET_CRATE, i*TAILLE_TUILE+TAILLE_TUILE, + j*TAILLE_TUILE, i*TAILLE_TUILE+TAILLE_TUILE, + j*TAILLE_TUILE, i*TAILLE_TUILE+TAILLE_TUILE-OFFSET_CRATE, + outline="black", fill="#94643E") else: if plateauCouleur[i][j]!=-1: couleurJoueur = COULEURS_JOUEURS[plateauCouleur[i][j]] @@ -111,7 +200,8 @@ def affiche_plateau(canvas, plateau, plateauCouleur, bombes, joueurs, powerups): trace_bomberman(canvas, j*TAILLE_TUILE, i*TAILLE_TUILE, couleurJoueur) if trouve_objet(i,j, powerups)!=None: couleurPowerup = COULEURS_POWERUPS[powerups[trouve_objet(i,j, powerups)][PU_NATURE]] - canvas.create_polygon(j*TAILLE_TUILE+TAILLE_TUILE/2, i*TAILLE_TUILE, j*TAILLE_TUILE, i*TAILLE_TUILE+TAILLE_TUILE/2, j*TAILLE_TUILE+TAILLE_TUILE/2, (i+1)*TAILLE_TUILE, (j+1)*TAILLE_TUILE, i*TAILLE_TUILE + TAILLE_TUILE/2, fill=couleurPowerup) + affiche_powerup(canvas, couleurPowerup, j, i) + #canvas.create_polygon(j*TAILLE_TUILE+TAILLE_TUILE/2, i*TAILLE_TUILE, j*TAILLE_TUILE, i*TAILLE_TUILE+TAILLE_TUILE/2, j*TAILLE_TUILE+TAILLE_TUILE/2, (i+1)*TAILLE_TUILE, (j+1)*TAILLE_TUILE, i*TAILLE_TUILE + TAILLE_TUILE/2, fill=couleurPowerup) def trace_bomberman(canvas, x, y, couleur): canvas.create_oval(x+15, y+15, x+TAILLE_TUILE-15, y+TAILLE_TUILE, fill=couleur) @@ -135,27 +225,66 @@ def affiche_infos(canvas, joueurs, plateauCouleur): couleur = COULEURS_JOUEURS[i] j=2 couleurPowerup = COULEURS_POWERUPS[POWERUP_NOMBREBOMBES] - canvas.create_polygon(j*TAILLE_TUILE+TAILLE_TUILE/2, k*TAILLE_TUILE, j*TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE/2, j*TAILLE_TUILE+TAILLE_TUILE/2, (k+1)*TAILLE_TUILE, (j+1)*TAILLE_TUILE, k*TAILLE_TUILE + TAILLE_TUILE/2, fill=couleurPowerup) + canvas.create_oval(j*TAILLE_TUILE+TAILLE_TUILE*1/5, k*TAILLE_TUILE+TAILLE_TUILE*2/5, j*TAILLE_TUILE+TAILLE_TUILE-TAILLE_TUILE*1/5, k*TAILLE_TUILE+TAILLE_TUILE, fill=couleurPowerup) + canvas.create_polygon( + j*TAILLE_TUILE+TAILLE_TUILE/2-TAILLE_TUILE/15, k*TAILLE_TUILE+TAILLE_TUILE*7/10, + j*TAILLE_TUILE+TAILLE_TUILE/2+TAILLE_TUILE/15, k*TAILLE_TUILE+TAILLE_TUILE*7/10, + j*TAILLE_TUILE+TAILLE_TUILE/2+TAILLE_TUILE/15, k*TAILLE_TUILE+TAILLE_TUILE/15, + j*TAILLE_TUILE+TAILLE_TUILE/2-TAILLE_TUILE/15, k*TAILLE_TUILE+TAILLE_TUILE/15, + fill=couleurPowerup) canvas.create_text((j+1)*TAILLE_TUILE+TAILLE_TUILE/2, (k+0.5)*TAILLE_TUILE, text=joueurs[i][J_NOMBREBOMBES]) j=4 couleurPowerup = COULEURS_POWERUPS[POWERUP_LONGUEURFLAMMES] - canvas.create_polygon(j*TAILLE_TUILE+TAILLE_TUILE/2, k*TAILLE_TUILE, j*TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE/2, j*TAILLE_TUILE+TAILLE_TUILE/2, (k+1)*TAILLE_TUILE, (j+1)*TAILLE_TUILE, k*TAILLE_TUILE + TAILLE_TUILE/2, fill=couleurPowerup) + canvas.create_polygon( + j*TAILLE_TUILE+TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE, + j*TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE, + j*TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE*(randrange(7))/10, + j*TAILLE_TUILE+1*TAILLE_TUILE/6, k*TAILLE_TUILE+TAILLE_TUILE*(randrange(7))/10, + j*TAILLE_TUILE+2*TAILLE_TUILE/6, k*TAILLE_TUILE+TAILLE_TUILE*(randrange(7))/10, + j*TAILLE_TUILE+3*TAILLE_TUILE/6, k*TAILLE_TUILE+TAILLE_TUILE*(randrange(7))/10, + j*TAILLE_TUILE+4*TAILLE_TUILE/6, k*TAILLE_TUILE+TAILLE_TUILE*(randrange(7))/10, + j*TAILLE_TUILE+5*TAILLE_TUILE/6, k*TAILLE_TUILE+TAILLE_TUILE*(randrange(7))/10, + j*TAILLE_TUILE+6*TAILLE_TUILE/6, k*TAILLE_TUILE+TAILLE_TUILE*(randrange(7))/10, + outline="black", fill=couleurPowerup) canvas.create_text((j+1)*TAILLE_TUILE+TAILLE_TUILE/2, (k+0.5)*TAILLE_TUILE, text=joueurs[i][J_LONGUEURFLAMMES]) j=6 couleurPowerup = COULEURS_POWERUPS[POWERUP_VITESSE] - canvas.create_polygon(j*TAILLE_TUILE+TAILLE_TUILE/2, k*TAILLE_TUILE, j*TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE/2, j*TAILLE_TUILE+TAILLE_TUILE/2, (k+1)*TAILLE_TUILE, (j+1)*TAILLE_TUILE, k*TAILLE_TUILE + TAILLE_TUILE/2, fill=couleurPowerup) + canvas.create_polygon( + j*TAILLE_TUILE+TAILLE_TUILE/10, k*TAILLE_TUILE+TAILLE_TUILE/10, + j*TAILLE_TUILE+TAILLE_TUILE*2/5, k*TAILLE_TUILE+TAILLE_TUILE/10, + j*TAILLE_TUILE+TAILLE_TUILE*2/5, k*TAILLE_TUILE+TAILLE_TUILE/2, + j*TAILLE_TUILE+TAILLE_TUILE*9/10, k*TAILLE_TUILE+TAILLE_TUILE*7/10, + j*TAILLE_TUILE+TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE*9/10, + j*TAILLE_TUILE+TAILLE_TUILE/10, k*TAILLE_TUILE+TAILLE_TUILE*9/10, + outline="black", fill=couleurPowerup) canvas.create_text((j+1)*TAILLE_TUILE+TAILLE_TUILE/2, (k+0.5)*TAILLE_TUILE, text=joueurs[i][J_VITESSE]) j=8 couleurPowerup = COULEURS_POWERUPS[POWERUP_DASH] - canvas.create_polygon(j*TAILLE_TUILE+TAILLE_TUILE/2, k*TAILLE_TUILE, j*TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE/2, j*TAILLE_TUILE+TAILLE_TUILE/2, (k+1)*TAILLE_TUILE, (j+1)*TAILLE_TUILE, k*TAILLE_TUILE + TAILLE_TUILE/2, fill=couleurPowerup) + canvas.create_polygon( + j*TAILLE_TUILE, k*TAILLE_TUILE, + j*TAILLE_TUILE+TAILLE_TUILE*6/10, k*TAILLE_TUILE+TAILLE_TUILE/2, + j*TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE, + fill=couleurPowerup) + canvas.create_polygon( + j*TAILLE_TUILE+TAILLE_TUILE*4/10, k*TAILLE_TUILE, + j*TAILLE_TUILE+TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE/2, + j*TAILLE_TUILE+TAILLE_TUILE*4/10, k*TAILLE_TUILE+TAILLE_TUILE, + fill=couleurPowerup) canvas.create_text((j+1)*TAILLE_TUILE+TAILLE_TUILE/2, (k+0.5)*TAILLE_TUILE, text=joueurs[i][J_DASHSRESTANTS]) j=10 couleurPowerup = COULEURS_POWERUPS[POWERUP_PIEGE] - canvas.create_polygon(j*TAILLE_TUILE+TAILLE_TUILE/2, k*TAILLE_TUILE, j*TAILLE_TUILE, k*TAILLE_TUILE+TAILLE_TUILE/2, j*TAILLE_TUILE+TAILLE_TUILE/2, (k+1)*TAILLE_TUILE, (j+1)*TAILLE_TUILE, k*TAILLE_TUILE + TAILLE_TUILE/2, fill=couleurPowerup) + canvas.create_polygon( + j*TAILLE_TUILE+TAILLE_TUILE*1/10, k*TAILLE_TUILE+TAILLE_TUILE*7/10, + j*TAILLE_TUILE+TAILLE_TUILE*3/20, k*TAILLE_TUILE+TAILLE_TUILE*6/10, + j*TAILLE_TUILE+TAILLE_TUILE/2, k*TAILLE_TUILE+TAILLE_TUILE*8/10, + j*TAILLE_TUILE+TAILLE_TUILE*17/20, k*TAILLE_TUILE+TAILLE_TUILE*6/10, + j*TAILLE_TUILE+TAILLE_TUILE*9/10, k*TAILLE_TUILE+TAILLE_TUILE*7/10, + j*TAILLE_TUILE+TAILLE_TUILE/2, k*TAILLE_TUILE+TAILLE_TUILE*9/10, + fill=couleurPowerup) canvas.create_text((j+1)*TAILLE_TUILE+TAILLE_TUILE/2, (k+0.5)*TAILLE_TUILE, text=joueurs[i][J_PIEGESRESTANTS]) j = 12 @@ -298,7 +427,11 @@ TAILLE_TUILE = 40 HAUTEUR_JOUEUR = TAILLE_TUILE LARGEUR_INFOS = 800 COULEURS_JOUEURS = ["red", "blue", "green", "yellow"] -COULEURS_POWERUPS = [ "cyan", "orangered", "yellow", "magenta", "purple"] +COULEURS_POWERUPS = ["cyan", "orangered", "red", "magenta", "purple"] +OFFSET_CRATE = TAILLE_TUILE/25 +TAILLE_OVERLAY = 15 +NOMBRE_SPARKS = 10 +SIZE_SPARKS = 12 def decision(programme, indiceJoueur, plateau, plateauCouleur, bombes, joueurs, powerups, instant): with open("entrees.txt", "w") as entrees: diff --git a/main b/main deleted file mode 100755 index 80304ee..0000000 Binary files a/main and /dev/null differ diff --git a/main.ml b/main.ml deleted file mode 100755 index 08d7eb4..0000000 --- a/main.ml +++ /dev/null @@ -1,928 +0,0 @@ -(*#! /home/alexandre/.opam/myswitch/bin/ocaml *) -(* -TODO : -- deal with double bombing (DONE) -- well shit ==> dash (DONE (needs dash to be fixed tho)) -- deeper analysis on pathfinfing -*) -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) - -let debug_all = false ;; -let debug_data = false ;; -let fatal_time = 1.0 ;; -let explosion_time = 1.0 ;; -let logg = true ;; - -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) - -type pt = { - x : int ; - y : int ; -} - -type bomb = { - xy : pt ; - size : int ; - det_time : float ; -} - -type player = { - id : int ; - xy : pt ; - nspeed : int ; - nbomb_atonce : int ; - bomb_radius : int ; - ndash : int ; - ntraps : int ; -} - -type boost = { - xy : pt ; - spec : int ; -} - -let default_point = { - x = 0 ; - y = 0 ; -} - -let default_bomb = { - xy = default_point ; - size = 0 ; - det_time = 0. ; -} - -and default_player = { - id = 0 ; - xy = default_point ; - nspeed = 0 ; - nbomb_atonce = 0 ; - bomb_radius = 0 ; - ndash = 0 ; - ntraps = 0 ; -} - -and default_boost = { - xy = default_point ; - spec = 0 ; -} - -and useless = ref 0 ;; - -type game_data = { - mutable dt : float ; - mutable player_id : int ; - mutable laby : int array array ; - mutable nbombs : int ; - mutable bombs : bomb array ; - mutable nplayers : int ; - mutable players : player array ; - mutable nboosts : int ; - mutable boosts : boost array ; -} - -type danger = Safe | Danger of float | Fatal of float | Blocked | Bonus ;; - -let int_of_danger = function - | Safe -> 0 - | Bonus -> 1 - | Danger _ -> 2 - | Fatal _ -> 3 - | Blocked -> 4 ;; - -let danger_of_int t = function - | 0 -> Safe - | 1 -> Bonus - | 2 -> Danger t - | 3 -> Fatal t - | _ -> Blocked ;; - -type moveType = EscapeDeath | BlowUpCrates | KillPlayers | ClaimLand ;; - -exception ReturnInt of int ;; -exception ReturnBool of bool ;; - -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) - -let current_status = ref BlowUpCrates ;; -let action = ref 0 ;; - -let dash_left = ref 0 ;; - -let equal_pt (p1 : pt) (p2 : pt) = - p1.x = p2.x && p1.y = p2.y ;; - -let swap arr i j = - let temp = arr.(i) in - arr.(i) <- arr.(j) ; - arr.(j) <- temp ;; - -let is_valid i j len hei = - i >= 0 && j >= 0 && i < len && j < hei ;; - -let print_direction = function - | 0 -> Printf.fprintf stderr "NORTH " - | 1 -> Printf.fprintf stderr "EAST " - | 2 -> Printf.fprintf stderr "SOUTH " - | 3 -> Printf.fprintf stderr "WEST " - | 4 -> Printf.fprintf stderr "STILL " - | _-> failwith "ERROR : invalid direction" ;; - -let level_of_danger = function - | Danger k | Fatal k -> k - | _ -> 32768. ;; - -let delta i j = - if i = j then 1 else 0 ;; - -let overwrite_file (filename : string) = - let ptr = open_out filename in - close_out ptr ;; - -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) - -let print_game_data (gd : game_data) = - Printf.fprintf stderr "--------------------------------| Board data |--------------------------------\n" ; - Printf.fprintf stderr "Time : %f\n" gd.dt ; - Printf.fprintf stderr "ID : %d\n" gd.player_id ; - Printf.fprintf stderr "Laby [of size %d %d]:\n" (Array.length gd.laby) (Array.length gd.laby.(0)); - for l = 0 to Array.length gd.laby -1 do - Printf.fprintf stderr " " ; - for c = 0 to Array.length gd.laby.(l) -1 do - Printf.fprintf stderr "%d " gd.laby.(l).(c) ; - done; - Printf.fprintf stderr "\n" - done ; - Printf.fprintf stderr "Bombs (%d) : \n" gd.nbombs ; - for b = 0 to gd.nbombs -1 do - Printf.fprintf stderr " [Bomb] (at %d %d) (of size %d) (blowing up at %f)\n" gd.bombs.(b).xy.x gd.bombs.(b).xy.y gd.bombs.(b).size gd.bombs.(b).det_time ; - 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 ; - done; - Printf.fprintf stderr "Boosts (%d) : \n" gd.nboosts ; - for b = 0 to gd.nboosts -1 do - Printf.fprintf stderr " [Boost] (at %d %d) (of type %d)\n" gd.boosts.(b).xy.x gd.boosts.(b).xy.y gd.boosts.(b).spec ; - done;; - -let print_danger_levels (map : danger array array) = - Printf.fprintf stderr "--------------------------------| Danger levels |--------------------------------\n" ; - for l = 0 to (Array.length map -1) do - for c = 0 to (Array.length map.(l) -1) do - match map.(l).(c) with - | Blocked -> Printf.fprintf stderr "@ " - | Safe -> Printf.fprintf stderr ". " - | Bonus -> Printf.fprintf stderr "+ " - | Danger x -> Printf.fprintf stderr "! " - | Fatal x -> Printf.fprintf stderr "X " - done; - Printf.fprintf stderr "\n" - done ;; - -let print_gain_map (map : int array array) = - Printf.fprintf stderr "--------------------------------| Gain levels |--------------------------------\n" ; - for l = 0 to (Array.length map -1) do - for c = 0 to (Array.length map.(l) -1) do - Printf.fprintf stderr "%d " map.(l).(c) ; - done; - Printf.fprintf stderr "\n" - done ;; - -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) - -let rec ln_b b = function - | k when k < 0 -> failwith "are you sure about that ?" - | k when k < b -> 0 - | k -> 1 + ln_b b (k/b) ;; - -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 - | 0 -> current_status := EscapeDeath - | 1 -> current_status := BlowUpCrates - | 2 -> current_status := ClaimLand - | 3 -> current_status := KillPlayers - | _ -> current_status := EscapeDeath - in - fct0 () ; - try - let resu = int_of_string (input_line ptr) in - dash_left := resu -1; - close_in ptr - with - | End_of_file -> close_in ptr ;; - -let set_meta_info (pid : int) = - let ptr = open_out ("main_"^(string_of_int pid)^".sav") in - let fct0 () = match !current_status with - | EscapeDeath -> Printf.fprintf ptr "0" - | BlowUpCrates -> Printf.fprintf ptr "1" - | ClaimLand -> Printf.fprintf ptr "2" - | KillPlayers -> Printf.fprintf ptr "3" - in - fct0 () ; - if !dash_left > 0 then - Printf.fprintf ptr "\n%d" !dash_left ; - close_out ptr ;; - -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) - -let int_of_string (str : string) = - String.fold_right (fun ch acc -> let cd = Char.code ch in if cd >= 48 || cd <= 57 then 10*acc + cd - 48 else failwith "not an integer\n") str 0 ;; - -let string_of_int (k0 : int) = - String.make (1) (Char.chr (k0 + 48)) ;; - -let int_n_of_string (str : string) (n : int) (nlast : int ref) = - let res = Array.make n 0 in - let rec aux idres idstr = match idstr with - | k when k = String.length str || idres >= n -> - nlast := k - | k -> - if str.[k] = ' ' then - aux (idres+1) (k+1) - else begin - let cd = Char.code str.[k] in - if cd >= 48 && cd <= 57 then begin - res.(idres) <- 10 * res.(idres) + cd - 48 ; - aux (idres) (k+1) - end - else - failwith "not an integer (n/n)\n" - end - in - aux 0 0 ; - res ;; - -let parse_input (str : string) = - let ptr = open_in str in - let (res : game_data) = {dt = 0. ; player_id = 0 ; laby = [||] ; nbombs = 0 ; bombs = [||] ; nplayers = 0 ; players = [||] ; nboosts = 0 ; boosts = [||] ;} in - try - (* time *) - if debug_all then Printf.fprintf stderr "Time\n" ; - res.dt <- Float.of_string (input_line ptr) ; - - (* player_id *) - if debug_all then Printf.fprintf stderr "PID\n" ; - res.player_id <- int_of_string (input_line ptr) ; - - (* maze *) - if debug_all then Printf.fprintf stderr "Maze\n" ; - let msize = int_n_of_string (input_line ptr) 2 useless in - - res.laby <- Array.make msize.(0) [||] ; - for lane = 0 to msize.(0) -1 do - let psd = input_line ptr in - res.laby.(lane) <- int_n_of_string psd msize.(1) useless ; - done; - - (* bombs *) - if debug_all then Printf.fprintf stderr "Boom\n" ; - res.nbombs <- int_of_string (input_line ptr) ; - - res.bombs <- Array.make res.nbombs default_bomb ; - for b = 0 to res.nbombs -1 do - let psd = input_line ptr - and last = ref 0 in - let dat = int_n_of_string psd 3 last in - let dtime = Float.of_string (String.init (String.length psd - !last) (fun i -> psd.[i + !last])) in - res.bombs.(b) <- {xy = {x = dat.(0) ; y = dat.(1) ;} ; size = dat.(2) ; det_time = dtime ; - } - done; - - (* players *) - if debug_all then Printf.fprintf stderr "Players\n" ; - res.nplayers <- int_of_string (input_line ptr) ; - - res.players <- Array.make res.nplayers default_player ; - for p = 0 to res.nplayers -1 do - let dat = int_n_of_string (input_line ptr) 8 useless in - res.players.(p) <- {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) ;} - done; - - (* boosts *) - if debug_all then Printf.fprintf stderr "Boosts\n" ; - res.nboosts <- int_of_string (input_line ptr) ; - - res.boosts <- Array.make res.nboosts default_boost ; - for p = 0 to res.nboosts -1 do - let dat = int_n_of_string (input_line ptr) 3 useless in - res.boosts.(p) <- {xy = {x = dat.(0) ; y = dat.(1) ;} ; spec = dat.(2)} - done; - - if debug_all then Printf.fprintf stderr "Done!\n" ; - close_in ptr ; - res - with - | End_of_file -> - close_in ptr ; - failwith "cannot happen unless something is wrong" ;; - -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) - -let exploded = Hashtbl.create 21 ;; - -let warn_level (b : bomb) (ct : float) = match (b.det_time -. ct) with - | k when k < fatal_time -> Fatal b.det_time ; - | _ -> Danger b.det_time ;; - -let danger_priority (p1 : danger) (p2 : danger) = - danger_of_int (min (level_of_danger p1) (level_of_danger p2)) (max (int_of_danger p1) (int_of_danger p2)) ;; - -let order = [|(1, 0); (-1, 0); (0, 1); (0, -1)|] ;; -let evaluate_dangers (gd : game_data) = - let lines = Array.length gd.laby - and cols = Array.length gd.laby.(0) in - let res = Array.make_matrix lines cols Safe in - - (* add solid blocks *) - for l = 0 to lines -1 do - for c = 0 to cols -1 do - if gd.laby.(l).(c) = 1 || gd.laby.(l).(c) = 2 then - res.(l).(c) <- Blocked ; - done - 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 - done; - - (* sort bombs based on detonation time *) - for b = 0 to gd.nbombs -1 do - let m = ref gd.bombs.(b).det_time - and im = ref b in - for j = b+1 to gd.nbombs -1 do - if gd.bombs.(j).det_time < !m then begin - m := gd.bombs.(j).det_time ; - im := j ; - end - done; - swap gd.bombs b (!im) ; - done; - - (* add bomb tiles *) - for b = 0 to gd.nbombs -1 do - let bx = gd.bombs.(b).xy.x - and by = gd.bombs.(b).xy.y in - - let dgr = danger_priority (warn_level gd.bombs.(b) gd.dt) (res.(bx).(by)) in (* be careful of chained bombs *) - let halt = ref false in - - for dir = 0 to 3 do - for w = 0 to gd.bombs.(b).size do - let cx = bx + w*(fst order.(dir)) - and cy = by + w*(snd order.(dir)) in - if not !halt && is_valid (cx) (cy) lines cols then begin - if gd.laby.(cx).(cy) = 1 then (* bedrock *) - halt := true ; - if gd.laby.(cx).(cy) = 2 && Hashtbl.find_opt exploded (cx, cy) = None then begin (* unexploded crate *) - halt := true ; - res.(cx).(cy) <- danger_priority res.(cx).(cy) dgr ; - Hashtbl.add exploded (cx, cy) 1 - end - else begin - res.(cx).(cy) <- danger_priority res.(cx).(cy) dgr ; - end - end - done; - halt := false ; - done - done; - - (* add players *) - for p = 0 to gd.nplayers -1 do - if p <> gd.player_id then begin - let player_dgr = danger_priority (Danger (gd.dt +. 5.5)) (res.(gd.players.(p).xy.x).(gd.players.(p).xy.y)) 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; - - res ;; - -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) - -let cell_values (gd : game_data) = - (* computes the net gain upon blowing up each cell *) - let lines = Array.length gd.laby - and cols = Array.length gd.laby.(0) in - let res = Array.make_matrix lines cols 0 in - - let psize = gd.players.(gd.player_id).bomb_radius in - - for ln = 0 to lines -1 do - for cl = 0 to cols -1 do - if (gd.laby.(ln).(cl) >= 3 && gd.laby.(ln).(cl) <> 3 + gd.player_id) || gd.laby.(ln).(cl) = 0 then begin - (* use a similar method than danger for bombs *) - let halt = ref false in - - for dir = 0 to 3 do - for w = 1 - delta dir 0 to psize do - 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) = 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 - done; - halt := false ; - done - end - done - done ; - res ;; - -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) - -let has_a_safe_path_origin (cx0 : int) (cy0 : int) (lines : int) (cols : int) (simt : float) (interval : float) (gd : game_data) (dgs : danger array array) (white_dgs : danger array) (white_gd : int array) (black_dgs : danger array) (black_gd : int array) (maxdepth : int) = - (* - core function - performs a BFS starting at (cx0, cy0), avoiding anything in blacklists and halting upon stepping on a whitelisted element - *) - let visited = Hashtbl.create 100 in - let q = Queue.create () in - - Hashtbl.add visited (cx0, cy0) 1 ; - - if is_valid (cx0+1) (cy0) lines cols && not ((simt +. interval) > (level_of_danger dgs.(cx0+1).(cy0)) && (simt +. interval) < (level_of_danger dgs.(cx0+1).(cy0)) +. explosion_time) then begin (* South *) - if debug_all then Printf.fprintf stderr "[escape] +South\n" ; - Queue.add (cx0+1, cy0, simt +. interval, 2) q ; - end; - if is_valid (cx0-1) (cy0) lines cols && not ((simt +. interval) > (level_of_danger dgs.(cx0-1).(cy0)) && (simt +. interval) < (level_of_danger dgs.(cx0-1).(cy0)) +. explosion_time) then begin (* North *) - if debug_all then Printf.fprintf stderr "[escape] +North\n" ; - Queue.add (cx0-1, cy0, simt +. interval, 0) q ; - end; - if is_valid (cx0) (cy0+1) lines cols && not ((simt +. interval) > (level_of_danger dgs.(cx0).(cy0+1)) && (simt +. interval) < (level_of_danger dgs.(cx0).(cy0+1)) +. explosion_time) then begin (* East *) - if debug_all then Printf.fprintf stderr "[escape] +East\n" ; - Queue.add (cx0, cy0+1, simt +. interval, 1) q ; - end; - if is_valid (cx0) (cy0-1) lines cols && not ((simt +. interval) > (level_of_danger dgs.(cx0).(cy0-1)) && (simt +. interval) < (level_of_danger dgs.(cx0).(cy0-1)) +. explosion_time) then begin (* West *) - if debug_all then Printf.fprintf stderr "[escape] +West\n" ; - Queue.add (cx0, cy0-1, simt +. interval, 3) q ; - end; - - if debug_all then Printf.fprintf stderr "[escape] Attempt 1/1...\n" ; - try - while not (Queue.is_empty q) do - let (cx, cy, cur_t, direct) = Queue.pop q in - if Hashtbl.find_opt visited (cx, cy) <> None then () else begin - Hashtbl.add visited (cx, cy) 1 ; - if cur_t > simt +. (float_of_int maxdepth) *. interval then (* too deep *) - raise (ReturnInt 4) - else if Array.mem dgs.(cx).(cy) white_dgs then - raise (ReturnInt direct) - else if Array.mem gd.laby.(cx).(cy) white_gd then - raise (ReturnInt direct) - else if Array.mem dgs.(cx).(cy) black_dgs then - () - else if Array.mem gd.laby.(cx).(cy) black_gd then - () - else begin (* either danger or fatal *) - let dang_time = level_of_danger dgs.(cx).(cy) in - for dir = 0 to 3 do - let newx = cx + fst order.(dir) - and newy = cy + snd order.(dir) - and newt = cur_t +. interval in - if (is_valid newx newy lines cols) && not (newt > dang_time && newt < dang_time +. explosion_time) then - Queue.add (newx, newy, newt, direct) q - done - end - end - done; - 4 - with - | ReturnInt b -> b ;; - -let has_a_safe_path_origin_2 (cx0 : int) (cy0 : int) (lines : int) (cols : int) (simt : float) (interval : float) (gd : game_data) (dgs : danger array array) (white_dgs : danger array) (white_gd : int array) (black_dgs : danger array) (black_gd : int array) (maxdepth : int) = - (* - core function - performs a BFS starting at (cx0, cy0), avoiding anything in blacklists and halting upon stepping on a whitelisted element - *) - let visited = Hashtbl.create 100 in - let q = Queue.create () in - - 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 ; - Queue.add (cx0, cy0-1, simt +. interval, 3) q ; - - if debug_all then Printf.fprintf stderr "[escape] Attempt 1/1...\n" ; - try - while not (Queue.is_empty q) do - 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) - else if Array.mem dgs.(cx).(cy) white_dgs then - raise (ReturnInt direct) - else if Array.mem gd.laby.(cx).(cy) white_gd then - raise (ReturnInt direct) - else if Array.mem dgs.(cx).(cy) black_dgs then - () - else if Array.mem gd.laby.(cx).(cy) black_gd then - () - else begin - for dir = 0 to 3 do - let newx = cx + fst order.(dir) - and newy = cy + snd order.(dir) - and newt = cur_t +. interval in - Queue.add (newx, newy, newt, direct) q - done - end - end - done; - 4 - with - | ReturnInt b -> b ;; - -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) - -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 - and lines = Array.length gd.laby - and cols = Array.length gd.laby.(0) in - try - let halt = ref false in - let res = ref false in - for dir = 0 to 3 do - for o = 1 to gd.players.(pid).bomb_radius do - if not !halt then begin - let nx = gd.players.(pid).xy.x + o * (fst order.(dir)) - and ny = gd.players.(pid).xy.y + o * (snd order.(dir)) in - if is_valid nx ny lines cols then begin - if gd.laby.(nx).(ny) = 2 then - res := true - else if gd.laby.(nx).(ny) = 1 then - halt := true - else if dgs.(nx).(ny) = Bonus then - raise (ReturnBool false) - end - end - done; - halt := false ; - done; - !res - with - | ReturnBool b -> b ;; - -let move_explore (gd: game_data) (dgs : danger array array) = - (* destroy crates *) - let pid = gd.player_id in - let interval = Float.pow 0.9 (float_of_int gd.players.(pid).nspeed) in - - let lines = Array.length gd.laby - and cols = Array.length gd.laby.(0) in - - (* find nearest crate and blow it up *) - try - let (cxi, cyi) = (gd.players.(pid).xy.x, gd.players.(pid).xy.y) in - - let move_with_caution () = - let res = has_a_safe_path_origin_2 cxi cyi lines cols gd.dt interval gd dgs [|Bonus|] [||] [|Blocked|] [||] 7 in - if res <> 4 then begin - if debug_all then Printf.fprintf stderr "[crates] success 1/2!\n" ; - res - end - else begin - for w = 0 to lines -1 do - for h = 0 to cols -1 do - if gd.laby.(w).(h) = 2 then begin - for dir = 0 to 3 do - let nx = w + fst order.(dir) - and ny = h + snd order.(dir) in - if is_valid nx ny lines cols && dgs.(nx).(ny) <> Blocked then - gd.laby.(nx).(ny) <- (-5) ; - done - end - done - done; - (* you dont want to stop INSIDE a crate, but rather right next to it *) - let res2 = has_a_safe_path_origin_2 cxi cyi lines cols gd.dt interval gd dgs [||] [|-5|] [|Blocked|] [||] 80 in - if res2 <> 4 then begin - if debug_all then Printf.fprintf stderr "[crates] success 2/2!\n" ; - res2 - end - else begin - if not (contains_crate gd) then (* TODONE *) - current_status := ClaimLand ; - Printf.fprintf stderr "Exited.\n" ; - 4 - end - end - in - - let safe_path_with_bomb (bx : int) (by : int) (bsize : int) = - (* simulate the placement of a bomb, and test if that stills allows safe escape *) - let bomb_hash = Hashtbl.create (4 * (bsize +1)) in - let saved_dgs = Hashtbl.create (4 * (bsize +1)) in - let bomb_dgr = (danger_priority (Danger (gd.dt +. 5.5)) dgs.(bx).(by)) in - for dir = 0 to 3 do - for w = 0 to bsize do - Hashtbl.add bomb_hash (bx + w*(fst order.(dir)), by + w*(snd order.(dir))) bomb_dgr ; - 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 result = has_a_safe_path_origin_2 cxi cyi lines cols gd.dt interval gd dgs [|Bonus; Safe|] [||] [|Blocked|] [||] 10 in - Hashtbl.iter (fun (k1, k2) v -> dgs.(k1).(k2) <- v) saved_dgs ; - result - in - - (* check if there's a crate next to the player, and if upon placing a bomb it won't softlock the player, and if you can place a bomb *) - let spwb = safe_path_with_bomb cxi cyi gd.players.(pid).bomb_radius in - if is_a_crate_nearby gd dgs && (spwb <> 4) then begin (* Crate at South *) - if dgs.(cxi).(cyi) = Safe && gd.players.(pid).nbomb_atonce > 0 then begin - (*current_status := EscapeDeath ;*) - action := 1; - if debug_all then Printf.fprintf stderr "Fire in the hole!\n" ; - raise (ReturnInt spwb) ; - end; - end; - - if debug_all then Printf.fprintf stderr "[crates] Cannot bomb now, searching for a crate...\n"; - - (* go to one without stepping into a dangerous tile *) - raise (ReturnInt (move_with_caution ())) ; - with - | ReturnInt k -> k ;; - -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) - -let cell_profit (d_from_p : int) (gain : int) = - (100 * 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 - let cpft = cell_profit distances.(i).(j) gns.(i).(j) in - if !maxi_gain < cpft then begin - maxi_gain := cpft ; - maxi_i := i ; - maxi_j := j ; - end - 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 - let bomb_dgr = danger_priority (Danger (gd.dt +. 5.5)) (dgs.(gd.players.(pid).xy.x).(gd.players.(pid).xy.y)) 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))) bomb_dgr ; - 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 (!dash_left = 0) && 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 (!dash_left = 0) && 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 (!dash_left = 0) && result2 <> 4 then - result2 - else begin - (* you're probably dead if the code reaches here, unless... *) - if false && ((!dash_left > 0) || gd.players.(pid).ndash > 0) then begin - Printf.fprintf stderr "*teleports*\n" ; - if (!dash_left = 0) then - action := 2 ; - dash_left := 3 ; - has_a_safe_path_origin_2 cx cy lines cols (gd.dt -. interval *. float_of_int (!dash_left)) interval gd dgs [|Safe|] [||] [|Blocked|] [||] 80 - end - else begin - Printf.fprintf stderr "well shit\n" ; - 4 - end - 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 - | _ when !current_status = BlowUpCrates -> () - | _ when !current_status = ClaimLand -> () - | Safe -> () - | 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 ?" ;; - -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) - -let debug_game_data1 (gd : game_data) = - Printf.fprintf stderr "[player %d started turn]\n" gd.player_id ;; - -let debug_game_data (gd : game_data) = - Printf.fprintf stderr "[player %d ended turn]\n" gd.player_id ;; - -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) -(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) - -if logg then Printf.fprintf stderr "XXXXXXXX\n" ;; - -let game_d = parse_input "entrees.txt" ;; -let dangers = evaluate_dangers game_d ;; -let gains = cell_values game_d ;; - -get_meta_info game_d.player_id ;; - -if logg then Printf.fprintf stderr "[player %d started its turn]\n" game_d.player_id ;; - -if debug_data then begin - print_game_data game_d ; - print_danger_levels dangers ; - print_gain_map gains ; -end ;; - -update_strat game_d dangers ;; - -let chosen = ref 0 ;; - -let main_actions () = match !current_status with - | EscapeDeath -> - 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 - chosen := move_explore game_d dangers ; - Printf.printf "%d " !chosen - end - else begin - current_status := EscapeDeath ; - 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 -> - () ;; - -main_actions () ; -Printf.printf "%d" !action ; - -(*debug_game_data game_d ;;*) -if logg then begin - Printf.fprintf stderr "[player %d went at direction " game_d.player_id ; - print_direction !chosen ; - Printf.fprintf stderr "with action %d] time at end : %f\n" !action game_d.dt ; -end ;; - -set_meta_info game_d.player_id ;; \ No newline at end of file diff --git a/tp.txt b/tp.txt deleted file mode 100644 index b73a0da..0000000 --- a/tp.txt +++ /dev/null @@ -1,23 +0,0 @@ -0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 -3 3 3 0 0 0 0 0 4 4 0 -0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 3 3 0 0 - -0 0 0 0 0 0 0 0 0 0 0 -0 1 0 1 2 1 2 1 2 1 0 -0 0 0 2 2 2 2 2 0 0 0 -0 1 2 1 2 1 2 1 2 1 2 -3 3 3 0 0 0 2 2 4 4 0 -0 1 0 1 0 1 0 1 0 1 0 -0 0 0 2 2 2 2 3 3 2 0 - -0 0 2 2 2 2 2 2 2 0 0 -0 1 2 1 2 1 2 1 2 1 0 -2 2 2 2 2 2 2 0 2 2 2 -2 1 0 1 2 1 2 1 2 1 0 -2 2 2 2 2 2 2 2 2 2 2 -0 1 2 1 2 1 2 1 0 1 0 -0 0 2 2 2 2 2 2 2 0 0 \ No newline at end of file