visual changes to tkinter interface

This commit is contained in:
Alexandre 2024-11-16 16:47:49 +01:00
parent c6dcd8cfd2
commit be1af52e4f
11 changed files with 166 additions and 980 deletions

BIN
again

Binary file not shown.

BIN
again.cmi

Binary file not shown.

BIN
again.cmo

Binary file not shown.

View File

@ -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 ->

View File

@ -1 +0,0 @@
ocamlc main.ml -o main

View File

@ -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

View File

@ -1,2 +0,0 @@
ocamlc main.ml -o main
./main

View File

@ -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:

BIN
main

Binary file not shown.

928
main.ml
View File

@ -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 ;;

23
tp.txt
View File

@ -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