# Implémentation du jeu de bataille navale # Documentation # sur l'interface graphique ktinker : # 1) http://tkinter.fdex.eu/ # 1.1) http://tkinter.fdex.eu/doc/uwm.html?highlight=after#after # 2) http://apprendre-python.com/page-tkinter-interface-graphique-python-tutoriel # 3) https://www.tutorialspoint.com/python/python_gui_programming.htm # 4) http://effbot.org/tkinterbook/ # 5) https://www.science-emergence.com/Articles/Comment-passer-des-arguments-en-ligne-de-commande-avec-python/ from tkinter import * from random import * from time import * import sys # Variables globales *************************************************** # Taille du coté de la grille en nombre de cellules ----------------------- # Valeur par défaut : 10 NbCellulesCoteGrille = int(10) # Nombre de porte-avions ----------------------------------------------- # Valeur par défaut : 2 NbPorteAvions = 2 # Nombre de croiseurs -------------------------------------------------- # Valeur par défaut : 3 NbCroiseurs = 3 # Nombre de destroyers ------------------------------------------------- # Valeur par défaut : 3 NbDestroyers = 5 # Taille de chaque case en nombre de pixels ---------------------------- NbPixelsCase = int(70) # Taille du coté de la grille en nombre de pixels ---------------------- # Valeur par défaut : 700 NbPixelsCoteGrille = int(NbPixelsCase * NbCellulesCoteGrille) # Grille ordinateur ---------------------------------------------------- # Tableau 7 x 7 # Ce tableau est constitué d'entiers codés de la manière suivante : # 0 = case de la grille associée en BLANC # 1 = case de la grille associée en NOIR # 2 = case de la grille associée en VERT # 3 = case de la grille associée en JAUNE # 4 = case de la grille associée en ROUGE GrilleOrdinateur = {} # Grille Joueur -------------------------------------------------------- # Tableau 7 x 7 # Ce tableau est constitué d'entiers codés de la manière suivante : # 0 = case de la grille associée en BLANC # 1 = case de la grille associée en NOIR # 2 = case de la grille associée en VERT # 3 = case de la grille associée en JAUNE # 4 = case de la grille associée en ROUGE GrilleJoueur = {} # Fonctions à utiliser ************************************************* #----------------------------------------------------------------------- # Dessine une grille à l'écran def DessinerGrille(grille, canevas, display) : print("DessinerGrille()") for i in range(NbCellulesCoteGrille) : for j in range(NbCellulesCoteGrille) : DessinerCaseGrille(i, j, grille=grille, canevas=canevas, display=display) #----------------------------------------------------------------------- #----------------------------------------------------------------------- # Dessine une case d'une grille à l'écran def DessinerCaseGrille(l, c, grille, canevas, display) : # print("DessinerCaseGrille()") x = int(l*NbPixelsCase) y = int(c*NbPixelsCase) if (display == False) : fill = "white" else : # case 'cachée' if (grille[l,c] == 0) : fill = "white" # case 'montrée' pleine elif grille[l,c] == 1 : fill = "black" # case 'montrée : coup dans l'eau' elif grille[l,c] == 2 : fill = "green" # case 'sécurisée' elif grille[l,c] == 3 : fill = "yellow" # case 'montrée : touché' elif grille[l,c] == 4 : fill = "red" canevas.create_rectangle(x, y, x+NbPixelsCase, y+NbPixelsCase, fill=fill) #----------------------------------------------------------------------- #----------------------------------------------------------------------- # Dépose un batiment sur la grille et l'entoure d'une zone de sécurité # d'une case afin d'empêcher le positionnement d'un autre batiment # juste adjacent # grille : grille concernée # l,c : coordonnées de la 1ère case du batiment # modele : 'destroyer', 'croiseur' ou 'porteavions' # orientation : 'horizontale' (1ère case à gauche) ou # 'verticale' (1ère case en haut) # RETOUR : True si ok, False sinon def PoserEtSecuriserBatiment(grille, l, c, modele, orientation) : print("SecuriserBatiment()") lp1 = l+1 lp2 = l+2 lp3 = l+3 lm1 = l-1 lm2 = l-2 lm3 = l-3 cp1 = c+1 cp2 = c+2 cp3 = c+3 cm1 = c-1 cm2 = c-2 cm3 = c-3 if modele == 'destroyer' : grille[l,c] = 1 if (l == 0) : lm1 = lp1 if (l == NbCellulesCoteGrille - 1) : lp1 = lm1 if (c == 0) : cm1 = cp1 if (c == NbCellulesCoteGrille - 1) : cp1 = cm1 grille[lm1, cm1] = 3 grille[lm1, c] = 3 grille[lm1, cp1] = 3 grille[l, cm1] = 3 grille[l, cp1] = 3 grille[lp1, cm1] = 3 grille[lp1, c] = 3 grille[lp1, cp1] = 3 elif modele == 'croiseur' : if orientation == 'vertical' : print("Dépot croiseur vertical") grille[l,c] = 1 grille[lp1,c] = 1 if (l == 0) : lm1 = lp2 if (l == NbCellulesCoteGrille - 2) : lp2 = lm1 if (c == 0) : cm1 = cp1 if (c == NbCellulesCoteGrille - 1) : cp1 = cm1 grille[lm1, cm1] = 3 grille[lm1, c] = 3 grille[lm1, cp1] = 3 grille[l, cm1] = 3 grille[l, cp1] = 3 grille[lp1, cm1] = 3 grille[lp1, cp1] = 3 grille[lp2, cm1] = 3 grille[lp2, c] = 3 grille[lp2, cp1] = 3 elif orientation == "horizontal" : print("Dépot croiseur horizontal") grille[l,c] = 1 grille[l,cp1] = 1 if (l == 0) : lm1 = lp1 if (l == NbCellulesCoteGrille - 2) : lp1 = lm1 if (c == 0) : cm1 = cp2 if (c == NbCellulesCoteGrille - 1) : cp2 = cm1 grille[lm1, cm1] = 3 grille[lm1, c] = 3 grille[lm1, cp1] = 3 grille[lm1, cp2] = 3 grille[l, cp2] = 3 grille[l, cm1] = 3 grille[lp1, cm1] = 3 grille[lp1, c] = 3 grille[lp1, cp1] = 3 grille[lp1, cp2] = 3 else : return False elif modele == 'porteavions' : if orientation == 'vertical' : print("Dépot porteavion vertical") grille[l,c] = 1 grille[lp1,c] = 1 grille[lp2,c] = 1 if (l == 0) : lm1 = lp3 if (l == NbCellulesCoteGrille - 2) : lp3 = lm1 if (c == 0) : cm1 = cp1 if (c == NbCellulesCoteGrille - 1) : cp1 = cm1 grille[lm1, cm1] = 3 grille[lm1, c] = 3 grille[lm1, cp1] = 3 grille[l, cm1] = 3 grille[l, cp1] = 3 grille[lp1, cm1] = 3 grille[lp1, cp1] = 3 grille[lp2, cm1] = 3 grille[lp2, cp1] = 3 grille[lp3, cm1] = 3 grille[lp3, c] = 3 grille[lp3, cp1] = 3 elif orientation == "horizontal" : print("Dépot porteavion horizontal") grille[l,c] = 1 grille[l,c+1] = 1 grille[l,c+2] = 1 if (l == 0) : lm1 = lp1 if (l == NbCellulesCoteGrille - 1) : lp1 = lm1 if (c == 0) : cm1 = cp3 if (c == NbCellulesCoteGrille - 1) : cp3 = cm1 grille[lm1, cm1] = 3 grille[lm1, c] = 3 grille[lm1, cp1] = 3 grille[lm1, cp2] = 3 grille[lm1, cp3] = 3 grille[l, cp3] = 3 grille[l, cm1] = 3 grille[lp1, cm1] = 3 grille[lp1, c] = 3 grille[lp1, cp1] = 3 grille[lp1, cp2] = 3 grille[lp1, cp3] = 3 else : return False else : return False return True #----------------------------------------------------------------------- #----------------------------------------------------------------------- # Initialise une grille de manière aléatoire def InitialiserGrilleAleatoire(grille) : print("InitialiserGrilleAleatoire()") # déposer votre code ci-dessous for i in range(NbCellulesCoteGrille) : for j in range(NbCellulesCoteGrille) : grille[i, j] = 0 # on commence par placer les destroyers for n in range (NbDestroyers) : ok = False while not ok : l = randint(0, NbCellulesCoteGrille - 1) c = randint(0, NbCellulesCoteGrille - 1) if DeposerBatimentPossible(grille, l, c, "destroyer", "notused") : PoserEtSecuriserBatiment(grille, l, c, "destroyer", "notused") ok = True # puis les croiseurs for n in range (NbCroiseurs) : ok = False while not ok : l = randint(0, NbCellulesCoteGrille - 1) c = randint(0, NbCellulesCoteGrille - 1) if (randint(0,1) == 1) : orientation = "vertical" else : orientation = "horizontal" print(orientation) if DeposerBatimentPossible(grille, l, c, "croiseur", orientation) : PoserEtSecuriserBatiment(grille, l, c, "croiseur", orientation) ok = True # et enfin les porteavions for n in range (NbPorteAvions) : ok = False while not ok : l = randint(0, NbCellulesCoteGrille - 1) c = randint(0, NbCellulesCoteGrille - 1) if (randint(0,1) == 1) : orientation = "vertical" else : orientation = "horizontal" print(orientation) if DeposerBatimentPossible(grille, l, c, "porteavions", orientation) : PoserEtSecuriserBatiment(grille, l, c, "porteavions", orientation) ok = True #----------------------------------------------------------------------- #----------------------------------------------------------------------- def callback(event): c = int(event.x / NbPixelsCase) l = int(event.y / NbPixelsCase) print ("Case grille ORDINATEUR", l, c) AlgoJoueur(l, c) #----------------------------------------------------------------------- # Fonctions à compléter ************************************************ #----------------------------------------------------------------------- # Vérifie si un batiment peut être déposé aux coordonnées indiquées # grille : grille concernée # l,c : coordonnées de la 1ère case du batiment # modele : 'destroyer', 'croiseur' ou 'porteavions' # orientation : 'horizontale' (1ère case à gauche) ou # 'verticale' (1ère case en haut) # RETOUR : True si c'est possible, False sinon def DeposerBatimentPossible(grille, l, c, modele, orientation) : print("DeposerBatimentPossible() : à compléter") # Placer votre code ci-dessous #----------------------------------------------------------------------- #----------------------------------------------------------------------- # Exécute l'algorithme de tir de l'ordinateur # Rappel : un coup dans l'eau colore la case en vert # Rappel : un coup au but colore la case en rouge def AlgoOrdinateur() : print("AlgoOrdinateur() : à compléter") # Placer votre code ci-dessous # A CONSERVER (pour éviter une réplique trop rapide de l'ordinateur sleep(2) # A CONSERVER pour redessiner la grille JOUEUR DessinerGrille(GrilleJoueur, CanevasJoueur) #----------------------------------------------------------------------- #----------------------------------------------------------------------- # Exécute l'algorithme de gestion des clicks du joueur sur la grille # de l'ordinateur # l , c = coordonnées de la case cliquée # Rappel : un coup dans l'eau colore la case en vert # Rappel : un coup au but colore la case en rouge # La fonction 'AlgoOrdinateur()' est dans cette fonction # pour que l'ordinateur riposte def AlgoJoueur(l, c) : print("AlgoJoueur() : à compléter") # Placer votre code ci-dessous #----------------------------------------------------------------------- # Fonctions à utiliser ************************************************* # Programme principal ************************************************** # Le code ci-dessous est A CONSERVER # Initialisation du contexte graphique fenêtre ORDINATEUR fenetreOrdinateur = Tk() fenetreOrdinateur.title("Grille ORDINATEUR"); CanevasOrdinateur = Canvas(fenetreOrdinateur, width=NbPixelsCoteGrille, height=NbPixelsCoteGrille, bg ='white') CanevasOrdinateur.bind("", callback) CanevasOrdinateur.pack(side =TOP, padx =5, pady =5) # Initialisation du contexte graphique fenêtre JOUEUR fenetreJoueur = Tk() fenetreJoueur.title("Grille JOUEUR"); CanevasJoueur = Canvas(fenetreJoueur, width=NbPixelsCoteGrille, height=NbPixelsCoteGrille, bg ='white') CanevasJoueur.pack(side =TOP, padx =5, pady =5) # Initialise la grille de l'ordinateur de manière aléatoire InitialiserGrilleAleatoire(GrilleOrdinateur) # Initialise la grille de l'ordinateur de manière aléatoire InitialiserGrilleAleatoire(GrilleJoueur) # Dessin initial de la grille de l'ordinateur DessinerGrille(GrilleOrdinateur, CanevasOrdinateur, False) # Dessin initial de la grille du joueur DessinerGrille(GrilleJoueur, CanevasJoueur, True) # Boucle de gestion des événements de la fenêtre du joueur fenetreOrdinateur.mainloop()