commit 06f01a63079e7df155cbbbe1522940b68c1f148a Author: Alexandre Date: Tue Nov 5 22:30:03 2024 +0100 Initial commit diff --git a/bin/main b/bin/main new file mode 100755 index 0000000..3a17023 Binary files /dev/null and b/bin/main differ diff --git a/compil.sh b/compil.sh new file mode 100644 index 0000000..e4b88a4 --- /dev/null +++ b/compil.sh @@ -0,0 +1 @@ +ocamlc main.ml -o bin/main \ No newline at end of file diff --git a/exec.sh b/exec.sh new file mode 100644 index 0000000..c04a152 --- /dev/null +++ b/exec.sh @@ -0,0 +1,2 @@ +ocamlc main.ml -o bin/main +./bin/main \ No newline at end of file diff --git a/iachallenge2024_bomberman.pdf b/iachallenge2024_bomberman.pdf new file mode 100644 index 0000000..57ce02c Binary files /dev/null and b/iachallenge2024_bomberman.pdf differ diff --git a/iachallenge2024_bomberman_base.py b/iachallenge2024_bomberman_base.py new file mode 100644 index 0000000..db36db0 --- /dev/null +++ b/iachallenge2024_bomberman_base.py @@ -0,0 +1,84 @@ +#!/usr/bin/python3 + +# Les constantes du jeu +TEMPS_BASE = 1 +TEMPS_PROPAGATION = 0.01 +TEMPS_EXPLOSION = 5.5 +TEMPS_PARTIE = 100 + +E_TEMPS = 0 +E_NATURE = 1 + +EVENEMENT_TOUR_JOUEUR = 1 +EVENEMENT_EXPLOSION_BOMBE = 2 +EVENEMENT_PROPAGATION = 3 + +PLATEAU_VIDE = 0 +PLATEAU_PIERRE = 1 +PLATEAU_BOIS = 2 + +DIRECTION_NORD = 0 +DIRECTION_EST = 1 +DIRECTION_SUD = 2 +DIRECTION_OUEST = 3 +DIRECTION_ATTENTE = 4 + +B_LIGNE = 0 +B_COLONNE = 1 +B_LONGUEURFLAMMES = 2 +B_JOUEUR = 3 +B_INSTANT = 4 + +J_LIGNE = 0 +J_COLONNE = 1 +J_DECISION = 2 +J_VITESSE = 3 +J_NOMBREBOMBES = 4 +J_LONGUEURFLAMMES = 5 +J_BOMBESRESTANTES = 6 +J_DASHSRESTANTS = 7 +J_PIEGESRESTANTS = 8 +J_TOURSDASH = 9 + +A_BOMBE = 1 +A_DASH = 2 +A_PIEGE = 3 + +POWERUP_VITESSE = 0 +POWERUP_NOMBREBOMBES = 1 +POWERUP_LONGUEURFLAMMES = 2 +POWERUP_DASH = 3 +POWERUP_PIEGE = 4 + +PU_LIGNE = 0 +PU_COLONNE = 1 +PU_NATURE = 2 + +# Lecture des entrées +instant = float(input()) +indiceMoi = int(input()) +hauteur, largeur = map(int, input().split()) +grille = [] +for i in range(hauteur): + grille.append(list(map(int,input().split()))) + +nbBombes = int(input()) +bombes = [] +for i in range(nbBombes): + ligne = input().split() + bombes.append([int(ligne[0]), int(ligne[1]), int(ligne[2]), float(ligne[2])]) + +nbJoueurs = int(input()) +joueurs = [None]*4 +for i in range(nbJoueurs): + joueur = list(map(int, input().split())) + joueurs[joueur.pop(2)] = joueur + +nbPowerups = int(input()) +powerups = [] +for i in range(nbPowerups): + powerups.append(list(map(int,input().split()))) + +# Ecriture de la décision +from random import randrange +print(randrange(5), 0) \ No newline at end of file diff --git a/iachallenge2024_bomberman_tkinter.py b/iachallenge2024_bomberman_tkinter.py new file mode 100644 index 0000000..40d031e --- /dev/null +++ b/iachallenge2024_bomberman_tkinter.py @@ -0,0 +1,382 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Sep 12 13:52:48 2018 + +@author: Laurent +""" +TEMPS_BASE = 1 +TEMPS_PROPAGATION = 0.01 +TEMPS_EXPLOSION = 5.5 +TEMPS_PARTIE = 100 + +E_INSTANT = 0 +E_NATURE = 1 + +EVENEMENT_TOUR_JOUEUR = 1 +EVENEMENT_EXPLOSION_BOMBE = 2 +EVENEMENT_PROPAGATION = 3 + +PLATEAU_VIDE = 0 +PLATEAU_PIERRE = 1 +PLATEAU_BOIS = 2 + +DIRECTION_NORD = 0 +DIRECTION_EST = 1 +DIRECTION_SUD = 2 +DIRECTION_OUEST = 3 +DIRECTION_ATTENTE = 4 + +B_LIGNE = 0 +B_COLONNE = 1 +B_LONGUEURFLAMMES = 2 +B_JOUEUR = 3 +B_INSTANT = 4 + +J_LIGNE = 0 +J_COLONNE = 1 +J_DECISION = 2 +J_VITESSE = 3 +J_NOMBREBOMBES = 4 +J_LONGUEURFLAMMES = 5 +J_BOMBESRESTANTES = 6 +J_DASHSRESTANTS = 7 +J_PIEGESRESTANTS = 8 +J_TOURSDASH = 9 + +A_BOMBE = 1 +A_DASH = 2 +A_PIEGE = 3 + +POWERUP_VITESSE = 0 +POWERUP_NOMBREBOMBES = 1 +POWERUP_LONGUEURFLAMMES = 2 +POWERUP_DASH = 3 +POWERUP_PIEGE = 4 + +PU_LIGNE = 0 +PU_COLONNE = 1 +PU_NATURE = 2 + +from random import randrange +from copy import deepcopy +from tkinter import * +from os import system + +def attente(vitesse): + return TEMPS_BASE * 0.9**vitesse + +def cree_plateau_initial(lignes, colonnes, nombreDeTrous): + plateau = [[PLATEAU_BOIS for i in range(colonnes+2)] for j in range(lignes+2)] + for i in range(2, lignes+1,2): + for j in range(2, colonnes+1, 2): + plateau[i][j]=PLATEAU_PIERRE + for i in range(0, lignes+2): + plateau[i][0] = PLATEAU_PIERRE + plateau[i][-1] = PLATEAU_PIERRE + + for j in range(0, colonnes+2): + plateau[0][j] = PLATEAU_PIERRE + plateau[-1][j] = PLATEAU_PIERRE + + plateau[1][1] = plateau[1][2] = plateau[2][1] = PLATEAU_VIDE + plateau[1][-2] = plateau[1][-3] = plateau[2][-2] = PLATEAU_VIDE + plateau[-2][1] = plateau[-2][2] = plateau[-3][1] = PLATEAU_VIDE + plateau[-2][-2] = plateau[-2][-3] = plateau[-3][-2] = PLATEAU_VIDE + + for i in range(nombreDeTrous): + i,j=0,0 + while plateau[i][j] != PLATEAU_BOIS: + i=randrange(lignes) + j=randrange(colonnes) + plateau[i][j] = PLATEAU_VIDE + return plateau + +def affiche_plateau(canvas, plateau, plateauCouleur, bombes, joueurs, powerups): + canvas.delete(ALL) + + for i in range(len(plateau)): + for j in range(len(plateau[0])): + 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") + else: + if plateauCouleur[i][j]!=-1: + couleurJoueur = COULEURS_JOUEURS[plateauCouleur[i][j]] + canvas.create_rectangle(j*TAILLE_TUILE, i*TAILLE_TUILE, j*TAILLE_TUILE+TAILLE_TUILE, i*TAILLE_TUILE+TAILLE_TUILE, fill=couleurJoueur, outline = couleurJoueur) + if trouve_objet(i,j, bombes)!=None: + canvas.create_oval(j*TAILLE_TUILE+5, i*TAILLE_TUILE+5, j*TAILLE_TUILE+TAILLE_TUILE-5, i*TAILLE_TUILE+TAILLE_TUILE-5, fill="cyan") + if trouve_objet(i,j, joueurs)!=None: + couleurJoueur = COULEURS_JOUEURS[trouve_objet(i,j, joueurs)] + 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) + +def trace_bomberman(canvas, x, y, couleur): + canvas.create_oval(x+15, y+15, x+TAILLE_TUILE-15, y+TAILLE_TUILE, fill=couleur) + canvas.create_oval(x+10, y, x+TAILLE_TUILE-10, y+TAILLE_TUILE-20, fill=couleur) + canvas.create_oval(x+13, y+5, x+TAILLE_TUILE-13, y+TAILLE_TUILE-26, fill="pink") + +def compte_couleur(grille, nbJoueurs): + compteurs = [0 for i in range(nbJoueurs)] + for ligne in grille: + for couleur in ligne: + if couleur >= 0: + compteurs[couleur]+=1 + return compteurs + +def affiche_infos(canvas, joueurs, plateauCouleur): + canvas.delete(ALL) + scores = list(reversed((sorted(zip(compte_couleur(plateauCouleur, len(joueurs)), range(len(joueurs))))))) + for k in range(len(scores)): + i = scores[k][1] + if joueurs[i]!=None: + 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_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_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_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_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_text((j+1)*TAILLE_TUILE+TAILLE_TUILE/2, (k+0.5)*TAILLE_TUILE, text=joueurs[i][J_PIEGESRESTANTS]) + + j = 12 + canvas.create_text((j+1)*TAILLE_TUILE+TAILLE_TUILE/2, (k+0.5)*TAILLE_TUILE, text=joueurs[i][J_DECISION]) + else: + couleur = "gray" + trace_bomberman(canvas, 0, HAUTEUR_JOUEUR*k,couleur) + + +def ajoute_evenement(evenements, evenement): + for i in range(0,len(evenements)): + if evenement[0]0 and action == A_BOMBE: + joueur[J_BOMBESRESTANTES]-=1 + bombes.append([i,j,joueur[J_LONGUEURFLAMMES],indiceJoueur,evenement[0]+TEMPS_EXPLOSION]) + ajoute_evenement(evenements, [evenement[0]+TEMPS_EXPLOSION, EVENEMENT_EXPLOSION_BOMBE, len(bombes)-1]) + elif joueurs[indiceJoueur][J_DASHSRESTANTS]>0 and action == A_DASH: + joueurs[J_DASHSRESTANTS]-=1 + joueurs[J_TOURSDASH]+=3 + elif joueurs[indiceJoueur][J_PIEGESRESTANTS]>0 and action == A_PIEGE: + joueurs[J_PIEGESRESTANTS]-=1 + pieges.append([i,j,indiceJoueur]) + ip,jp = prochain(i,j,direction) + if plateau[ip][jp]==PLATEAU_VIDE and trouve_objet(ip, jp, bombes)==None: + joueur[J_LIGNE]=ip + joueur[J_COLONNE]=jp + + i, j = joueur[J_LIGNE], joueur[J_COLONNE] + indicePiege = trouve_objet(i,j, pieges) + penalite = 0 + if indicePiege != None: + if piege[P_JOUEUR] != indiceJoueur: + penalite = 3 + piege.pop(indicePiege) + + indicePowerup = trouve_objet(i,j,powerups) + if indicePowerup != None: + powerup = powerups.pop(indicePowerup) + if powerup[PU_NATURE]==POWERUP_LONGUEURFLAMMES: + joueur[J_LONGUEURFLAMMES]+=1 + elif powerup[PU_NATURE]==POWERUP_NOMBREBOMBES: + joueur[J_NOMBREBOMBES]+=1 + joueur[J_BOMBESRESTANTES]+=1 + elif powerup[PU_NATURE]==POWERUP_VITESSE: + joueur[J_VITESSE]+=1 + elif powerup[PU_NATURE]==POWERUP_DASH: + joueur[J_DASHSRESTANTS]+=1 + elif powerup[PU_NATURE]==POWERUP_PIEGE: + joueur[J_PIEGESRESTANTS]+=1 + + ajoute_evenement(evenements, [temps+attente(joueur[J_VITESSE])*(joueur[J_TOURSDASH]==0)+penalite, EVENEMENT_TOUR_JOUEUR, indiceJoueur]) + if joueur[J_TOURSDASH]>0: + joueur[J_TOURSDASH]-=1 + elif evenement[E_NATURE]==EVENEMENT_EXPLOSION_BOMBE: + temps, nature, indiceBombe = evenement + if bombes[indiceBombe]==None: + return + + + i,j,longueurFlammes, indiceJoueur, instant = bombes[indiceBombe] + indJoueur = bombes[indiceBombe][B_JOUEUR] + bombes[indiceBombe] = None + + for direction in [DIRECTION_NORD, DIRECTION_SUD, DIRECTION_EST, DIRECTION_OUEST]: + ajoute_evenement(evenements, [evenement[0], EVENEMENT_PROPAGATION, i, j, direction, longueurFlammes, indJoueur]) + if joueurs[indiceJoueur]!=None: + joueurs[indiceJoueur][J_BOMBESRESTANTES]+=1 + elif evenement[E_NATURE]==EVENEMENT_PROPAGATION: + temps, nature, i, j, direction, longueurFlammes, indJoueur = evenement + if plateau[i][j]==PLATEAU_PIERRE: + # Pierre : indestuctible donc pas d'effet + return + elif plateau[i][j]==PLATEAU_BOIS: + # Bois : destructible, on détruit + casse(plateau, powerups, i,j) + return + else: + # On colore la case avec la couleur du joueur + plateauCouleur[i][j] = indJoueur + # On détruit le powerup s'il y en a un + indicePowerup = trouve_objet(i,j,powerups) + if indicePowerup != None: + powerups.pop(indicePowerup) + + # On tue tous les joueurs qui sont à cet endroit + indiceJoueur = trouve_objet(i,j,joueurs) + while indiceJoueur != None: + joueurs[indiceJoueur] = None + indiceJoueur = trouve_objet(i,j,joueurs) + + # On fait exploser la bombe s'il y en a une + indiceBombe = trouve_objet(i,j,bombes) + if indiceBombe != None: + ajoute_evenement(evenements, [evenement[0],EVENEMENT_EXPLOSION_BOMBE, indiceBombe]) + longueurFlammes = 0 + + # Si on est pas au bout de la flamme, on propage + if longueurFlammes>0: + ip, jp = prochain(i,j,direction) + ajoute_evenement(evenements, [evenement[0]+TEMPS_PROPAGATION, EVENEMENT_PROPAGATION, ip, jp, direction, longueurFlammes-1, indJoueur]) + + +TAILLE_TUILE = 40 +HAUTEUR_JOUEUR = TAILLE_TUILE +LARGEUR_INFOS = 800 +COULEURS_JOUEURS = ["red", "blue", "green", "yellow"] +COULEURS_POWERUPS = [ "cyan", "orangered", "yellow", "magenta", "purple"] + +def decision(programme, indiceJoueur, plateau, plateauCouleur, bombes, joueurs, powerups, instant): + with open("entrees.txt", "w") as entrees: + print(instant, file=entrees) + print(indiceJoueur, file=entrees) + print(len(plateau), len(plateau[0]), file=entrees) + plateauTotal = [[plateau[i][j] if plateau[i][j]!=0 or plateauCouleur[i][j]==-1 else 3+plateauCouleur[i][j] for j in range(len(plateau[0]))] for i in range(len(plateau))] + + for ligne in plateauTotal: + for val in ligne: + print(val, end=" ", file=entrees) + print(file=entrees) + print(len(bombes)-bombes.count(None), file=entrees) + for bombe in bombes: + if bombe!=None: + print(bombe[B_LIGNE], bombe[B_COLONNE], bombe[B_LONGUEURFLAMMES], bombe[B_INSTANT], file=entrees) + print(len(joueurs)-joueurs.count(None), file=entrees) + for j, joueur in enumerate(joueurs): + if joueur!=None: + print(joueur[J_LIGNE], joueur[J_COLONNE], j, joueur[J_VITESSE], joueur[J_NOMBREBOMBES], joueur[J_LONGUEURFLAMMES], joueur[J_DASHSRESTANTS], joueur[J_PIEGESRESTANTS], file=entrees) + print(len(powerups), file=entrees) + for pu in powerups: + print(pu[PU_LIGNE], pu[PU_COLONNE], pu[PU_NATURE], file=entrees) + + system("cat entrees.txt | "+programme+" > sortie.txt") + + with open("sortie.txt", "r") as sortie: + direction, b = sortie.readline().split() + action = int(b) + return int(direction), action + +def simulation(strategies): + def pas_de_jeu(): + if len(joueurs) - joueurs.count(None) > 1: + evenement = evenements.pop(0) + if evenement[0]>TEMPS_PARTIE: + return + execute_evenement(evenements, evenement, plateau, plateauCouleur, bombes, joueurs, powerups, pieges) + affiche_plateau(canvas, plateau, plateauCouleur, bombes, joueurs, powerups) + affiche_infos(canvasInfosJoueurs, joueurs, plateauCouleur) + temps = int((evenements[0][0]-evenement[0])/3*1000) + if temps != 0: + fenetre.after(temps, pas_de_jeu) + else: + pas_de_jeu() + + dimensions = 13,21 + positionsInitiales=[(1, 1), (dimensions[0]-2, dimensions[1]-2), (1, dimensions[1]-2), (dimensions[0]-2, 1)] + + + plateau = cree_plateau_initial(dimensions[0]-2, dimensions[1]-2, 20) + plateauCouleur = [[-1 for j in range(dimensions[1])] for i in range(dimensions[0])] + + evenements = [] + + bombes = [] + joueurs = [] + powerups = [] + pieges = [] + + fenetre = Tk() + canvas = Canvas(width=dimensions[1]*TAILLE_TUILE, height=dimensions[0]*TAILLE_TUILE) + canvas.pack() + + joueurs = [] + + for i in range(len(strategies)): + joueur = [positionsInitiales[i][0], positionsInitiales[i][1], strategies[i], 0, 1, 1, 1, 0, 0, 0] + joueurs.append(joueur) + ajoute_evenement(evenements, [0., EVENEMENT_TOUR_JOUEUR, i]) + + canvasInfosJoueurs = Canvas(width = LARGEUR_INFOS, height=len(joueurs)*HAUTEUR_JOUEUR) + canvasInfosJoueurs.pack() + + pas_de_jeu() + + fenetre.mainloop() + return + +from importlib import import_module +simulation(["./patient.py", "./aleatoire.py","./patient.py", "./aleatoire.py"]) diff --git a/input_test.txt b/input_test.txt new file mode 100644 index 0000000..9f6219b --- /dev/null +++ b/input_test.txt @@ -0,0 +1,44 @@ +3.7 +3 +7 11 +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 +3 +3 2 4 4.1 +4 4 2 4.3 +0 0 3 5.5 +5 +0 0 0 3 2 4 5 3 +2 0 1 4 3 2 2 2 +10 5 2 0 2 3 2 3 +5 5 3 5 1 10 2 3 +7 5 4 9 8 7 5 4 +2 +0 1 1 +0 0 2 + + +(* + - instant actuel de jeu (sous la forme d’un nombre à virgule flottante) + — votre numéro de joueur (sur une ligne) + — les dimensions du labyrinthe (ligne colonne inscrit sur une ligne) + — la grille du labyrinthe constituée de ligne lignes, et colonnes nombre par ligne. Les nombres possibles sont + 0 pour les cases vides non revendiquées, 1 pour les murs en pierre (indestructibles) et 2 pour les caisses en + bois (destructibles), puis 3 + j pour les cases vides revendiquées par le joueur de numéro j + — le nombre de bombes actuellement en jeu (sur une ligne) + — pour chaque bombe actuellement en jeu, une ligne indiquant ses coordonnées, la taille des déflagrations et son + instant d’explosion (ligne colonne taille instant) inscrit sur une ligne) + — le nombre de joueurs actuellement en jeu (sur une ligne) + — pour chaque joueur actuellement en jeu, une ligne indiquant ses coordonnées, son numéro et le nombre + de powerups qu’il a actuellement (ligne colonne joueur vitesse nbbombes deflagration nbdashs + nbpieges) + — le nombre de powerups actuellement en jeu (sur une ligne) + — pour chaque powerup actuellement en jeu, une ligne indiquant ses coordonnées et son type (ligne colonne + type). Avec type qui vaut 0 pour Vitesse augmentée, 1 pour Nombre de bombes augmenté, et 2 pour Taille + des déflagration augmentée. +*) \ No newline at end of file diff --git a/main.cmi b/main.cmi new file mode 100644 index 0000000..4d5bcb5 Binary files /dev/null and b/main.cmi differ diff --git a/main.cmo b/main.cmo new file mode 100644 index 0000000..c2de0a6 Binary files /dev/null and b/main.cmo differ diff --git a/main.ml b/main.ml new file mode 100644 index 0000000..731ecc7 --- /dev/null +++ b/main.ml @@ -0,0 +1,211 @@ +let debug = false ;; + +type bomb = { + x : int ; + y : int ; + size : int ; + det_time : float ; +} + +type player = { + id : int ; + x : int ; + y : int ; + nspeed : int ; + nbomb_atonce : int ; + bomb_radius : int ; + ndash : int ; + ntraps : int ; +} + +type boost = { + x : int ; + y : int ; + spec : int ; +} + +let default_bomb = { + x = 0 ; + y = 0 ; + size = 0 ; + det_time = 0. ; +} + +and default_player = { + id = 0 ; + x = 0 ; + y = 0 ; + nspeed = 0 ; + nbomb_atonce = 0 ; + bomb_radius = 0 ; + ndash = 0 ; + ntraps = 0 ; +} + +and default_boost = { + x = 0 ; + y = 0 ; + 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 ; +} + +(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) +(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) + +let print_game_data (gd : game_data) = + Printf.printf "-----------------------| Board data |-----------------------\n" ; + Printf.printf "Time : %f\n" gd.dt ; + Printf.printf "ID : %d\n" gd.player_id ; + Printf.printf "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.printf " " ; + for c = 0 to Array.length gd.laby.(l) -1 do + Printf.printf "%d " gd.laby.(l).(c) ; + done; + Printf.printf "\n" + done ; + Printf.printf "Bombs (%d) : \n" gd.nbombs ; + for b = 0 to gd.nbombs -1 do + Printf.printf " [Bomb] (at %d %d) (of size %d) (blowing up at %f)\n" gd.bombs.(b).x gd.bombs.(b).y gd.bombs.(b).size gd.bombs.(b).det_time ; + done; + Printf.printf "Players (%d) : \n" gd.nplayers ; + for b = 0 to gd.nplayers -1 do + Printf.printf " [Player %d] (at %d %d) (holding %d %d %d %d %d)\n" gd.players.(b).id gd.players.(b).x gd.players.(b).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.printf "Boosts (%d) : \n" gd.nboosts ; + for b = 0 to gd.nboosts -1 do + Printf.printf " [Boost] (at %d %d) (of type %d)\n" gd.boosts.(b).x gd.boosts.(b).y gd.boosts.(b).spec ; + done;; + +(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) +(* ---------------------------------------------------------------------------------------------------------------------------------------------------- *) + +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 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 then Printf.printf "Time\n" ; + res.dt <- Float.of_string (input_line ptr) ; + + (* player_id *) + if debug then Printf.printf "PID\n" ; + res.player_id <- int_of_string (input_line ptr) ; + + (* maze *) + if debug then Printf.printf "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 then Printf.printf "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) <- { + x = dat.(0) ; + y = dat.(1) ; + size = dat.(2) ; + det_time = dtime ; + } + done; + + (* players *) + if debug then Printf.printf "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) ; + 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 then Printf.printf "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) <- { + x = dat.(0) ; + y = dat.(1) ; + spec = dat.(2) + } + done; + + if debug then Printf.printf "Done!\n" ; + close_in ptr ; + res + with + | End_of_file -> + close_in ptr ; + failwith "cannot happen unless something is wrong" ;; + +print_game_data (parse_input "input_test.txt") ;; \ No newline at end of file