From e5db2853256d1e27c3f6bacef9f2682c2234d8a6 Mon Sep 17 00:00:00 2001
From: Gantchou Koffi <koffi.gantchou.etu@116p12.fil.univ-lille.fr>
Date: Tue, 18 Mar 2025 13:26:50 +0100
Subject: [PATCH] TP5

---
 tp5_AP/__pycache__/cell.cpython-310.pyc       | Bin 0 -> 2846 bytes
 .../graphicalboard.cpython-310.pyc            | Bin 0 -> 4902 bytes
 .../__pycache__/minesweeper.cpython-310.pyc   | Bin 0 -> 7570 bytes
 tp5_AP/apl1test.py                            |  89 ++++++
 tp5_AP/cell.py                                | 140 +++++++++
 tp5_AP/graphical_main.py                      |  18 ++
 tp5_AP/graphicalboard.py                      | 174 +++++++++++
 tp5_AP/icons/0.gif                            | Bin 0 -> 99 bytes
 tp5_AP/icons/1.gif                            | Bin 0 -> 404 bytes
 tp5_AP/icons/10.gif                           | Bin 0 -> 393 bytes
 tp5_AP/icons/11.gif                           | Bin 0 -> 879 bytes
 tp5_AP/icons/12.gif                           | Bin 0 -> 658 bytes
 tp5_AP/icons/13.gif                           | Bin 0 -> 648 bytes
 tp5_AP/icons/2.gif                            | Bin 0 -> 668 bytes
 tp5_AP/icons/3.gif                            | Bin 0 -> 639 bytes
 tp5_AP/icons/4.gif                            | Bin 0 -> 649 bytes
 tp5_AP/icons/5.gif                            | Bin 0 -> 418 bytes
 tp5_AP/icons/6.gif                            | Bin 0 -> 660 bytes
 tp5_AP/icons/7.gif                            | Bin 0 -> 420 bytes
 tp5_AP/icons/8.gif                            | Bin 0 -> 427 bytes
 tp5_AP/icons/9.gif                            | Bin 0 -> 337 bytes
 tp5_AP/minesweeper.py                         | 278 ++++++++++++++++++
 tp5_AP/p1.py                                  |   0
 23 files changed, 699 insertions(+)
 create mode 100644 tp5_AP/__pycache__/cell.cpython-310.pyc
 create mode 100644 tp5_AP/__pycache__/graphicalboard.cpython-310.pyc
 create mode 100644 tp5_AP/__pycache__/minesweeper.cpython-310.pyc
 create mode 100644 tp5_AP/apl1test.py
 create mode 100755 tp5_AP/cell.py
 create mode 100644 tp5_AP/graphical_main.py
 create mode 100644 tp5_AP/graphicalboard.py
 create mode 100644 tp5_AP/icons/0.gif
 create mode 100644 tp5_AP/icons/1.gif
 create mode 100644 tp5_AP/icons/10.gif
 create mode 100644 tp5_AP/icons/11.gif
 create mode 100644 tp5_AP/icons/12.gif
 create mode 100644 tp5_AP/icons/13.gif
 create mode 100644 tp5_AP/icons/2.gif
 create mode 100644 tp5_AP/icons/3.gif
 create mode 100644 tp5_AP/icons/4.gif
 create mode 100644 tp5_AP/icons/5.gif
 create mode 100644 tp5_AP/icons/6.gif
 create mode 100644 tp5_AP/icons/7.gif
 create mode 100644 tp5_AP/icons/8.gif
 create mode 100644 tp5_AP/icons/9.gif
 create mode 100644 tp5_AP/minesweeper.py
 create mode 100644 tp5_AP/p1.py

diff --git a/tp5_AP/__pycache__/cell.cpython-310.pyc b/tp5_AP/__pycache__/cell.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..081254be76b64ce50e79f216b06113190308e0cb
GIT binary patch
literal 2846
zcmd1j<>g{vU|{$$WqtZbP6md@APzESW?*1&U|?V<Heq03NMVR#aA!ziOkrwaNMUMb
ziegM<N@31sDw0THNny=lj$%$_Uci#VwvdsLA%!&<j5XP-oVcuV^HZ!6l2dbX5)^Xt
zQ%ZAExwxznOG`5Hi>wr~^V8BY719&)N|H13OS!nLQW8s2trQH6^$m>ljSP%TxwyEJ
zk=+Dh!`)@Yz`&5o5XG3n5XA&>Srl^$a|%lfLljF2YYJNnLlkQYdkRMjLlj#IXDWLd
zQwmoKcMD4tM+#3cgC_4S7U$HQoMc9jp->EBGchnQID`Bx2J$y!4MRLb3W#J(VX9$>
zXG&oXX3%6wEMsI~;8K8s%)HE!%*33`s#JwUg}l^qg^bLUl+-*0khc}`(-aaFax?Q%
zi_23}3sQ^Jixtv~GE?;6x>GAMi%U}Tl2ai{lk#(ubQJPRbCXhwKq4T1u|j5^LSAZS
zdPY)yQAU1#3S4tWVp*y}Nxni-szPx|Vo7R>LQY~yY7xS8xXOZ})a3lUl+2RM{5&g#
zy!^aWxRh%}Vs1fBYOxg;Tu4Pl1>}4MTLn-cX=tKL=w%kigIop|cT3DEMwkfI4pLQ=
zT9%ralZtRMc9nS`(~9FW^Ww4k(*R-7OHgF_X)@nphq~bwcV=-s%$i$b*iBl=c#EYt
zH79K)LlFl91H&&9{fzwFRQ()7eQ+w&gQY^f)RIztm;B_?+|<01V*Qc=(|E@KeNas5
z6;$5hh>r(Fc6_`5D21>wFfgzQvN3WoR`G&@Ne?EQ3`$5KXM!+@4NA1&L?y()z)-`$
z!jQ#~!f4LG1WH^?!3>(riQdQw%Bm=}q_il{O2H2~nyiX5Q&JUD)6!CtORN+!^OB2F
zL5@@?$w(!XUO)*6<a>B1QaLqX4|BL}h}eTCjJ)Kcct|3T&rbs<C5*_&lIjT9V+gnL
zB`DPWG#QIn85kIfKoJFwb_l`Az`$@z1r&gUoS+JdW>ASB#9yTej$&eTVMIU31W@#U
z1{JyB(u5%e9PL#P;4aS1PsvQHRDh&oNM@#WtRZC^xHGWlPKc|pL<lw`LW)WeB|!)%
z5?F9W0vp6&OIR>-@m6tzgBc=@Ga!q285kHenX4|t-Ca;xqL8QnDnvkKB`B>cAWAbT
zr*>$$1GgJ{m=&j%fYUYhPy@LXZUAP8feH+)$(93VtQS1Y_@Jc^Oy(9Fr1-!Ydc|_!
zQYed|m^Fnln4yLti?N6clpsr(Y8bMZn;F3+(k84WQldg}Nl|8Ax<XNEK~ZXPYF<eq
zs78S$RY<~xd(5h+q_QB@3Zw@vMpR@#YgPrgE@;7ly+SH3Dbh$z&Cyh_wN+48P={+m
z30J5IdXS`r7Aq(w7!WXlm@)vL`Gy3{heaelGn{ak@rzO67Ne6UOA$EFfs)ZJ=Hikf
z+~pv9e0*_9QG9$9C_RD7CpHllMm8oEMlPl*9&lcSD)7_f1l50eiMgrq@wd3*<8#67
zx%l{7Jn`{`rHMHZnIe!GMLeJ!&j%v-L4+`f5CIXO$`?`!gIS=WxCm5MgVYv-ba60n
zFmZ@-h;RrB34molmgXjA=EcVsfyz<8Dt2gXtjT(dJw84qKRG@gtguKFRIYO*7UUR~
pq!yRlVh54A`6)=&!R@@oVFPi#9msO9#VpKxTpW2EjC_nN{{SK_s(Jtb

literal 0
HcmV?d00001

diff --git a/tp5_AP/__pycache__/graphicalboard.cpython-310.pyc b/tp5_AP/__pycache__/graphicalboard.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..74143f7ab1ec5291a7d9b062c86c5c4a543a7f0b
GIT binary patch
literal 4902
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
B`H=ts

literal 0
HcmV?d00001

diff --git a/tp5_AP/__pycache__/minesweeper.cpython-310.pyc b/tp5_AP/__pycache__/minesweeper.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e0f4179752d9545e5b5f786320a1a22dac906f47
GIT binary patch
literal 7570
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
Ba9RKW

literal 0
HcmV?d00001

diff --git a/tp5_AP/apl1test.py b/tp5_AP/apl1test.py
new file mode 100644
index 0000000..8533cca
--- /dev/null
+++ b/tp5_AP/apl1test.py
@@ -0,0 +1,89 @@
+import thonnycontrib
+from thonnycontrib.backend.evaluator import Evaluator
+import thonnycontrib.backend.l1test_backend
+from thonny.plugins.cpython_backend.cp_back import MainCPythonBackend
+import thonnycontrib.backend.doctest_parser 
+from thonnycontrib.backend.doctest_parser import ExampleWithExpected, ExampleWithoutExpected
+import thonnycontrib.backend.ast_parser
+from thonnycontrib.backend.ast_parser import L1DocTest
+import thonnycontrib.backend.verdicts
+from thonnycontrib.backend.verdicts.ExceptionVerdict import ExceptionVerdict 
+
+import inspect
+import tempfile
+import os
+import sys
+        
+class MockBackend(MainCPythonBackend):
+    """
+    Fake backend.
+    """
+    def __init__(self):
+        ...
+
+    def send_message(self, msg) -> None:
+        ...
+
+# register backend
+thonnycontrib.backend.l1test_backend.BACKEND = MockBackend()
+
+def l1test_to_org(filename: str, source: str=""):
+    """
+    Return an org abstract of the tests presents in `filename` file.
+    """
+    abstract = {'total': 0,
+                'success': 0,
+                'failures': 0,
+                'errors': 0,
+                'empty': 0}
+
+    if source == "":
+        with open(filename, 'rt') as fin:
+            source = fin.read()
+    evaluator = Evaluator(filename=filename,
+                          source=source)
+    tests = evaluator.evaluate()
+    n = len(tests)
+    abstract['total'] = n
+    res = ""
+    for test in tests:
+        examples = test.get_examples()
+        res_examples = ""
+        nb_test, nb_test_ok = 0, 0
+        empty = True
+        for example in examples:
+            verdict = test.get_verdict_from_example(example)
+            if isinstance(example, ExampleWithExpected):
+                nb_test += 1
+                if verdict.isSuccess():
+                    nb_test_ok += 1
+                    abstract['success'] += 1
+                else:
+                    abstract['failures'] += 1
+                empty = False
+            if isinstance(verdict, ExceptionVerdict):
+                abstract['errors'] += 1
+                empty = False
+            res_examples += f"** {verdict}\n\n"
+            if not verdict.isSuccess():
+                res_examples += f"   {verdict.get_details()}\n\n"
+        if not empty: 
+            res += f"* {test.get_name()} ~ {nb_test_ok}/{nb_test} réussis\n\n"
+        else:
+            abstract['empty'] += 1
+            res += f"* {test.get_name()}\n\n Aucun test trouvé !\n\n"
+        res += res_examples
+    res = f"Tests exécutés : {abstract['total']}\nSuccès: {abstract['success']}, \
+Echecs: {abstract['failures']}, Erreurs: {abstract['errors']}, \
+Vide: {abstract['empty']}\n\n" + res
+    return res
+
+
+def testmod(modulename: str):
+    """
+    mimic the doctest.testmod function
+    for `modulename` module
+    """
+    print(l1test_to_org(modulename))
+
+
diff --git a/tp5_AP/cell.py b/tp5_AP/cell.py
new file mode 100755
index 0000000..586daa5
--- /dev/null
+++ b/tp5_AP/cell.py
@@ -0,0 +1,140 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+"""
+:mod:`cell` module
+
+:author: koffi gantchou
+
+:date: 13/02/2025
+
+
+"""
+    
+class Cell:
+    
+    def __init__(self):
+        """
+        initialize a new hidden cell of a minesweeper's grid.
+        existence of a bomb, number of bombs in neighborhood
+        have to be stated later.
+        
+        precondition: none
+        Examples:
+
+        $$$ cel = Cell()
+        $$$ cel.is_bomb
+        False
+        $$$ cel.is_revealed
+        False
+        $$$ cel.nbombs_in_neighborhood
+        0
+        """
+        self.is_bomb = False
+        self.is_revealed = False
+        self.nbombs_in_neighborhood = 0
+
+    def incr_number_of_bombs_in_neighborhood(self):
+        """
+        :return: None
+        :side effect: increment the number of bombs in neighborhood of self
+        precondition: none
+        Examples:
+
+        $$$ cel = Cell()
+        $$$ cel.nbombs_in_neighborhood
+        0
+        $$$ cel.incr_number_of_bombs_in_neighborhood()
+        $$$ cel.nbombs_in_neighborhood
+        1
+        """
+        
+        self.nbombs_in_neighborhood +=1
+        
+        
+        
+
+    def reveal(self):
+        """
+        modify reveal state of self
+        precondition: none
+        Examples:
+
+        $$$ cel = Cell()
+        $$$ cel.is_revealed
+        False
+        $$$ cel.reveal()
+        $$$ cel.is_revealed
+        True
+        """
+        self.is_revealed = True
+        
+        
+
+    def set_bomb(self):
+        """
+        put a bomb in self 
+
+        precondition: none
+        Examples:
+
+        $$$ cel = Cell()
+        $$$ cel.is_bomb
+        False
+        $$$ cel.set_bomb()
+        $$$ cel.is_bomb
+        True
+        """
+        self.is_bomb = True
+
+    def __str__(self)->str:
+        """
+        :return: a string representation of self state
+        :rtype: str
+        precondition: none
+        Examples:
+        
+        $$$ cel = Cell()
+        $$$ str(cel) == ' '
+        True
+        $$$ cel.reveal()
+        $$$ str(cel) == '0'
+        True
+        $$$ cel.incr_number_of_bombs_in_neighborhood()
+        $$$ str(cel) == '1'
+        True
+        $$$ cel.set_bomb()
+        $$$ str(cel) == 'B'
+        True
+        """
+        if not(self.is_revealed):
+            return' '  
+        else:
+            if self.is_bomb:
+                return 'B'
+            else:
+                return str(self.nbombs_in_neighborhood)
+        
+            
+            
+def fibo(n:int)->int:
+    """ renvoie le terme fn de la suite
+
+    Précondition :
+    Exemple(s) :
+    $$$
+    """
+    if n==0:
+        return 0
+    elif n==1:
+        return 1
+    else:
+        return fibo(n-1) + fibo(n-2)
+        
+            
+
+
+if (__name__ == '__main__'):
+    import apl1test
+    apl1test.testmod('cell.py')
+
diff --git a/tp5_AP/graphical_main.py b/tp5_AP/graphical_main.py
new file mode 100644
index 0000000..d57cc9f
--- /dev/null
+++ b/tp5_AP/graphical_main.py
@@ -0,0 +1,18 @@
+from minesweeper import Minesweeper
+import graphicalboard
+
+import sys
+
+def main():
+    width = int(sys.argv[1])
+    height = int(sys.argv[2])
+    nb_bomb = int(sys.argv[3])
+    print(f"vous avez une grille de jeu de dimmension {width}*{height} {nb_bomb} nombre de bombes")
+    game = Minesweeper(width, height, nb_bomb)
+    graphicalboard.create(game)
+
+if __name__ == "__main__":
+    if len(sys.argv) != 4:
+        print("Usage : python3 graphical_main.py <width> <height> <nb_bomb>")
+    else:
+        main()
diff --git a/tp5_AP/graphicalboard.py b/tp5_AP/graphicalboard.py
new file mode 100644
index 0000000..7b353af
--- /dev/null
+++ b/tp5_AP/graphicalboard.py
@@ -0,0 +1,174 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+"""
+:mod:`graphicalboard` module
+
+:author: `FIL - IEEA - Univ. Lille1.fr <http://portail.fil.univ-lille1.fr>`_
+
+:date:  2015, september, last revision: 2024, february
+
+This module implements some functions to draw a minesweeper game. The
+graphical board uses buttons to draw each cell and maps the left-click
+and right-click events to interact with the minesweeper.
+
+This module uses from :mod:`minesweeper`:
+
+* :method:`Minesweeper.reveal_all_cells_from`
+
+To draw and run a minesweeper game, one has to:
+
+* create a minesweeper game g
+* create a graphical board from the minesweeper g
+
+"""
+
+import os
+import tkinter as tk
+from functools import partial
+from cell import Cell
+from minesweeper import *
+
+# the list of icons
+img = []
+
+def create(game: Minesweeper):
+    """
+    This function creates the graphical board from a game. It also
+    launches the event loop. Thus, this is the only function to run to
+    have a functional graphical board.
+    """
+    global img
+    # create a new Tk window
+    win = tk.Tk()
+    # define the window title
+    win.title('Minesweeper ({:d} bombs)'.format(game.nbombs))
+    # load images
+    iconpath = os.path.join(os.path.dirname(os.path.abspath(__file__)), "icons")
+    img = [
+        tk.PhotoImage(file=os.path.join(iconpath, "0.gif")),
+        tk.PhotoImage(file=os.path.join(iconpath, "1.gif")),
+        tk.PhotoImage(file=os.path.join(iconpath, "2.gif")),
+        tk.PhotoImage(file=os.path.join(iconpath, "3.gif")),
+        tk.PhotoImage(file=os.path.join(iconpath, "4.gif")),
+        tk.PhotoImage(file=os.path.join(iconpath, "5.gif")),
+        tk.PhotoImage(file=os.path.join(iconpath, "6.gif")),
+        tk.PhotoImage(file=os.path.join(iconpath, "7.gif")),
+        tk.PhotoImage(file=os.path.join(iconpath, "8.gif")),
+        tk.PhotoImage(file=os.path.join(iconpath, "9.gif")),  # unrevealed
+        tk.PhotoImage(file=os.path.join(iconpath, "10.gif")), # bomb explosed
+        tk.PhotoImage(file=os.path.join(iconpath, "11.gif")), # bomb discovered
+        tk.PhotoImage(file=os.path.join(iconpath, "12.gif")), # flag
+        tk.PhotoImage(file=os.path.join(iconpath, "13.gif"))  # question
+    ]
+    # create the graphical board made of Tk buttons
+    width, height = game.width, game.height
+    board = []
+    for i in range(width):
+        board.insert(i, [])
+        for j in range(height):
+            button = tk.Button(win, padx=0, pady=0, width=19, height=19, image=img[9])
+            button.grid(column=i, row=j)
+            board[i].insert(j, button)
+            # bind the right-click event
+            button.bind("<Button-3>",
+                        partial(__changeflag, board=board, game=game, x=i, y=j))
+            # bind the left-click event
+            button.config(command=partial(__changestate, board, game, i, j))
+    # event loop
+    win.mainloop()
+
+def __test_end(board: list[list[tk.Button]], game: Minesweeper):
+    """
+    This function tests if the game is finished or not.  In the first
+    case, depending on the state of the game, all graphical cells are
+    disabled or events are unbinded.
+    """
+    state = game.state
+    if state == GameState.losing:
+        __disable_game(board, game)
+    elif state == GameState.winning:
+        __block_game(board, game)
+
+def __changestate(board: list[list[tk.Button]],
+                  game: Minesweeper,
+                  x: int, y: int):
+    """
+    This function is called on left-click on a button.
+
+    """
+    game.reveal_all_cells_from(x, y)
+    __redraw(board, game, x, y)
+    __test_end(board, game)
+
+def __changeflag(evt, board: list[list[tk.Button]],
+                 game: Minesweeper,
+                 x: int, y: int):
+    """
+    This function is called on right-click on a button.
+    """
+    cel = game.get_cell(x, y)
+    # if not cel.is_hypothetic():
+    #     cel.set_hypothetic()
+    # else:
+    #     cel.unset_hypothetic()
+    __redraw(board, game, x, y)
+    __test_end(board, game)
+
+
+def __block_game(board: list[list[tk.Button]],
+                 game: Minesweeper):
+    """
+    This function is called once the player wins. The chosen behavior
+    is to let the board as it and to unbind events.
+    """
+    width, height = (game.width, game.height)
+    for i in range(width):
+        for j in range(height):
+            button = board[i][j]
+            game.get_cell(i, j).reveal()
+            button.config(command="")
+            button.bind("<Button-3>", "")
+    __redraw(board, game, -1, -1)
+
+def __disable_game(board: list[list[tk.Button]],
+                   game: Minesweeper):
+    """
+    This function is called once the player looses. The chosen behavior
+    is to shade the board and to unbind events.
+    """
+    width, height = game.width, game.height
+    for i in range(width):
+        for j in range(height):
+            button = board[i][j]
+            button.config(state=tk.DISABLED)
+            button.bind("<Button-3>", "")
+
+
+def __redraw(board: list[list[tk.Button]],
+             game: Minesweeper,
+             x: int, y: int):
+    """
+    This function draws the board. Positions x and y are used to test
+    which bomb icon has to be drawn.
+    """
+    width, height = (game.width, game.height)
+    for i in range(width):
+        for j in range(height):
+            cel = game.get_cell(i, j)
+            button = board[i][j]
+            if cel.is_revealed:
+                if cel.is_bomb:
+                    new_img = img[10]
+                    if x == j and y == i:
+                        new_img = img[11]
+                else:
+                    new_img = img[cel.nbombs_in_neighborhood]
+                button.config(relief=tk.FLAT, image=new_img, command="")
+            else:
+                button.config(image=img[9])
+
+
+if __name__ == "__main__":
+    import apl1test
+    apl1test.testmod('graphicalboard.py')
diff --git a/tp5_AP/icons/0.gif b/tp5_AP/icons/0.gif
new file mode 100644
index 0000000000000000000000000000000000000000..26d8a1024c3e988cc71d1f44e5eb9785a24920e8
GIT binary patch
literal 99
zcmZ?wbhEHb6lM@+_{hM}-Q7KB&YYb)ckbG?OYtWQ0|@AV2#`DjlZi{;%Jj$li>;k+
zbbns3^RaBmJoc`|$L40NSeK?f<%8<^LaXbRe6MZqe`3{~^hh}&LPM~DiNP8G+AJkq

literal 0
HcmV?d00001

diff --git a/tp5_AP/icons/1.gif b/tp5_AP/icons/1.gif
new file mode 100644
index 0000000000000000000000000000000000000000..fc817675c6f607b73904f16c369713edf2f914fc
GIT binary patch
literal 404
zcmZ?wbhEHb6lM@+_{zY*$oP+e;Xfnee`e-?tgL^zxqtKW{t^-SE-(LCQu3>$<Tn|a
zFFHE!%*|if+P+Xw_#7X9J1XjKM8v(=*gKh-*K=~NrKH>}E4x%#d9kA6lB?@eH@7F<
z-Q9EM%$_r6&dQbhSFhf;YSsSr>-X;6yM6oiUE8+p-mqcMjvYI9?%cU+*N)x0ckJ4=
zbN6mAZ`ZCpdv@&Ev$LV$Tw~+8&d$>_W*nU}=g9Kq2Ue^&z<>iN{$v5m=zvI&pBUIS
zI`pM`sFYb9U3lSYmR0PUpp!RCc%xV3l$Caw>Zt3kDivMrBH-*Gd~K5LjWw&DNw8dd
z`^MUDlI^?loTO?EEeY0!#>(VWEfFqmPL{6bR1GyVa}(|<dDFDDwG=t#R!xhRUs5r(
zAW3`W(w?;%n)=ELtE9E`HJ7c`HW8N;WiRIu7dO$~6rnH7$iUFRbV*qMjK;an+t+Sr
h8Vd<NdMqepyf@!RSI6M(yLURFa!#IKJ!KpjtO0VirM>_F

literal 0
HcmV?d00001

diff --git a/tp5_AP/icons/10.gif b/tp5_AP/icons/10.gif
new file mode 100644
index 0000000000000000000000000000000000000000..10d928aa589648fbfd4e0c37a997cfa5e0eeaf2f
GIT binary patch
literal 393
zcmZ?wbhEHb6lM@+_{snRjEsy-Oiawo%q%P{tgNhTY-}7H9Gsk-TwGi{JUqO-ynK9o
z{QUevLPEmA!s6oM5)u-Ul9IBrvhwosii(QL%E~G#Dr#zKnwpy0+S>a1`UVCDCMG7P
zrluAa7M7NlR#sLvHZ~3p4vvnFE-o(a?(UwRo_>CQ{{H@ffq@Yb5m8Z5+1c5-xw#<M
zkcbt3vM@3*=ribm^nv`uz_#qb^a2kZsa}>tg_<@BGn}0gU$F47A7?teU_pw3&=H1(
zHd0CpE_XiJX|n9JtH;r#rEW4@hpLv$iO|#4R+AOyXLM!ZV3(}d)sR<}6%$}%VG88n
zkWkUomX}hJ7M;pE!-YXePFYP=NmfFbufv^FTt-$_T0%sKv&M~?S43P)R9J|I`G6}2
nD+j-T0ACW@a#v;+1_nkpHpbhGTLOXt+?lRFd-dAek--`OQ*cI4

literal 0
HcmV?d00001

diff --git a/tp5_AP/icons/11.gif b/tp5_AP/icons/11.gif
new file mode 100644
index 0000000000000000000000000000000000000000..51fb6a928424a34021239bbb290456976666bcc1
GIT binary patch
literal 879
zcmZ?wbhEHb6krfw_|5<U)eH>(8LAno85pXotM~5Rd+*-8{|pTO|1<m_1*0J_tV2Kt
zlmkF{fq^50fty3dW5WUm77k&pn1}>LCk8%2lM;@L4_#OU7&ESP7(R6Ekv7-bvm&su
wX@aP#nogzB688xj$*XE4CM!ElG7YX<V_Br?(`Ti;?2V`4qvIW1%uEc{0D652vj6}9

literal 0
HcmV?d00001

diff --git a/tp5_AP/icons/12.gif b/tp5_AP/icons/12.gif
new file mode 100644
index 0000000000000000000000000000000000000000..2854de27bbf73d5d8a9c21db979ab75f144a8a9f
GIT binary patch
literal 658
zcmZ?wbhEHb6lM@+_{IPN%*@Q}?Cjj!+;Vbqii(OVDk`d~syaG4Mmjo%hK5#FR@T<m
zB_$=LrKOdXl~q+$)z#ItwY3{nRQ@wC{9|VR%f|LyMC7}u=yx%(PfAK}jEo)z1Uv{1
zzL}bOv9hwcxq05adAmD07A#n>aN)v*ix)3iv}oy~MN5_}S-pDonl)?Iu3fus-MYPt
z7VTTJX3x5H+qZAuy?OJVO`CRZ-MVZ0_8mKR>;%D`J9qBfwR6{wUAuPf+O=c%?wz}L
z@7lF%*KQElvuDrg&d%c#CLCP6_|T$7$BrF4e*E~clP6D{IC1IHrEg!q{rLXl=Z~L1
zfByXY=kLG2|3H2oG+6N`3)n3>AQBWO4D9b4{F|CvTKxlj%$odsd;9wPyv+ps{k+`V
zXU_DPHPh2lh}YlO&A@cIm9ewF`EpYWO#!~e?(3~>TxFzOtSt7~X>HoF-cVjjL~_qQ
zivx#z-OY_;#Y9e=+JA8Kc~cW7Y0+zYZ=Bm|VWTG}E^+<L&BObwZIy&|AH99DexJQ6
zr@H;=vs<Qq7G+^&5^-eMb^F+wV;ll(4m~R#KAv|VSjR_0LLi}mNmxfi&xR?Rk&%%h
zh)ZFE0_%iU&jv${ga-}2%&ZbCI5s(nO;NQBTB0DhXvIYVm7p~W9}hSxaSAB7%<!6;
Wb!8c!nrXp-t*fuE=VM}Ium%8KhvqW?

literal 0
HcmV?d00001

diff --git a/tp5_AP/icons/13.gif b/tp5_AP/icons/13.gif
new file mode 100644
index 0000000000000000000000000000000000000000..947d01285d2ba0b83ccd14bf3fde61887798ad16
GIT binary patch
literal 648
zcmZ?wbhEHb6lM@+_{PA%#l^+T%PS-#BrGf}Dk>@`C#R^WsI084qN1Xqp`oLrqpPcH
zY;0_4X=!U~>+bIE?d|RB>zkC6l#-HCP*6}(Qc_x4T3K0HRaI46TU%dW-_p|3*4Eb9
z+1cOUKWWmW$&)8fojP^Kj2Sa$&YU}U?)>@l7cN}5Xwjl2OO~u$xpMXD)oa$QS-W=a
z`t|EKZQ8VX^X4sEwrt(Hb^G@1J9g~Yxnt+fojZ5!+_h`huHCzL@7c3w@7}$~jvYIG
z{P>9zCr+I_b?VfqOP4Nv`}*z2_a8rh{QUXz=ifhn|NZ^PFm!<8PZqFabwDI2P8isq
zHn=u5x3s#tIhi!MIQRDT_c@wKxVku4+sw4Jv$waMX=7_9DeCHMZDee0rY$Kfs&2Z<
zR7*l^nT@fjxh5YICo_kl#cu6wJ9e21F^KEQF!G-~w%vKBnE@}iu7xf;x1O2#<rAhx
zO3KC-vW$Y4j$hqnYVlctl}pw9==+_ff6aAy-U(iI?~S*YQRK+EaIs&(vR*@D#fj(n
zGJD!ga~^DH47{_i;**Vog5iaSN9!z2Bz^>3Qr;@JJMTozM5Q*LnHI|=Ig^}^cFnhs
jWZ=zu)YR%CX`m5%s$^v#_hhYz8D3jgg>pACFjxZsaZJjg

literal 0
HcmV?d00001

diff --git a/tp5_AP/icons/2.gif b/tp5_AP/icons/2.gif
new file mode 100644
index 0000000000000000000000000000000000000000..2ef31056ccd581f2df4fe0f10e03f9ae831ac7ef
GIT binary patch
literal 668
zcmZ?wbhEHb6lM@+_{PA%(7?dZ$iUFVz}Upd)WpQp%*4{n!rIKr*22c#!p_;s$<@Ne
z)yl=)%FWZt!`sHo*TyH)B_rD{tJI^U(xal<tE$$krrxKn(W{}`udCOuXFAc;bdss<
z6kEF~c23irT&B6WO?L~L6%;%>IAnH6*zB<IIpGm=BBJL;$Igq5n-`ZfKPhKXPX6Nj
z!X<@8ONvUDmX<9ot65%CyS%n;MO}Ay_nbL%=FXYhu%e-9WmD^_){fO3-K)FjY?!lT
z^OB{Tm#*2iX6?4M>$a_1zis`7?He|2-?VxA<}KT|Y~HbX%Z@EucWm9ZW83x}+qduB
zzGLT(ojZ5#+PQ1@&fU9q?b^L-_nuvQ_U+ooFrYy3Ckxnq9S{kM69)F54W?$zEv;?M
zO+i7ye%^ik{eHn+%|YJA@-nk#&sMPX32F{D<Y8oFSh12}8NW$zv!^s86SJtC><(FB
zCMHHXUo&%OiPhXT{yrxItT^^cxo*%=RnxK$^!LB6&vx#DSx{hb@bw$PcFF>K*|q(r
z-gqDAV<E=8Oi<5l;r;ji!S+hLKB^oSmAOP}gEkyJU6|;g&uP%-bFgj0e10K5A4P_X
z$y`&)IrKvdG#DOD(h3O*ni<mB+7!toH)nyNbDQsM>nSYClNgsVFtKrQ$Z8#Mnjmf7
vB4B)U%SufKk%l`P7CvF^5{cNH<=eQ3b&{9X;jU0guL}z|w`8#}F<1it-)Pab

literal 0
HcmV?d00001

diff --git a/tp5_AP/icons/3.gif b/tp5_AP/icons/3.gif
new file mode 100644
index 0000000000000000000000000000000000000000..4abac7be126376b0b3c7a8dd202c91e51c401810
GIT binary patch
literal 639
zcmZ?wbhEHb6lM@+_{PBSpMl{&BjZ0NroSvKe_2`ova$VPXaCK`^_!df4=3j@Uf%B_
zB0mKMe+UVEla%}-BlAU0?!A`QJ6+w+3JPzGjbEFXyf!tx8y$ToCgx6T>|<~52Z4bP
z0|Orf1>H_axRsQ2D>?aQYU=f@tn1m?*K%{O=I5WUtGirWe6h0fLUna_clYc$Ah3Vs
z%6+R>?_0BG_vX!eHf-3tVZ)w{8+UKnvU}UMUE8;B-?wk)&Yin<?%c6!*UnwLcI@80
zbNB9DyLRo^vuEd?J?9!4&NnoiYivB*+InK*#1oSy9h))Z@Z7nF=g&VfckY2@%MPqq
z!7x~X;!hT^({w;2C{7sI?=)!XXt%Vswd!;>*_oO4^-nOhw6(PBv{n@nn>}Z)l&gj1
zbQy-F%a$+YcekCcARxS9;|88(at@t#hPu1=?AF&{T`Ijs$I{x$+S<ncjJ>%V`%)R}
zPD_jH7DgUkcRW>C4js96-QJm-_XRKKGR5sjZ`f-xtys$9Xn*yC8W+c34(4SB9f!9a
zcAePl+Ec^8kr1^{_Iim)F`KW{)+CdpGdE5YvhgUgd6g<`b9Q0j)CgWw5}<W}quko#
sqP6IPLqd~W^ipn|-29wV&B|rthl|OJE~ZV<;q*GPWo58yBLjmq08zQwi~s-t

literal 0
HcmV?d00001

diff --git a/tp5_AP/icons/4.gif b/tp5_AP/icons/4.gif
new file mode 100644
index 0000000000000000000000000000000000000000..4e942e211f7d29940e2f0868ad8888d6dc396064
GIT binary patch
literal 649
zcmZ?wbhEHb6lM@+_{PA%z|h3N(9FQl!pPXd%-q7n)XKur%F5cx$=Sxm)y~J)&coBe
z%iF=n*C8O#AuQY}D%vF>(Jd#}D=*)xtlX!f(x<B0Z)iBl*m$yu$z*HmskXLL?d+!6
z+fQ?FnC9d(-P?PnukS2>|Je}{bK~RZCnYUNO<kClwy>aJNoD2o?(Xh6bLPyQJ7?a!
zIrHbwnLmGSW8=!^=2a~%t2#SZcXqCsFk$VKDeI<AT|aHw`svfx&zP}()~pSS7HwL(
zbn~)hTb3{1vSP)SRjanHS+jNR+HD&)Y}>G5`{vEtH*emtWy_9j+jeZ<zGK_Ao!htX
z+_7Wl&Ye4V?E(|KcJ1E1YtNot`}XYu1;Bt}#h)x-`*lDhC{7sIpEYP{H@CF5H8%wY
zbO-u+_WSsGPY4KX4)F5}a8s6$l(Mpsm6T9&@t;03$bf^9LDJQdYn`am3hf#G&f<(r
zoJJv*yiAN+x6cUDU^^o35q#*#vFZM{B76BvgU=sk6mt%m9-zW}#?HafnCFPFnR|1P
zwII`HeqkXYLDtV~0w#Le-VO{L4i`il8b3c1?D*Jpv|m8R%45z8#>0)3+-46lHZJO%
z)URM~we#RwCjsvrMk_-!S)&Z2SB7mW(bQe)6KaxpYmX-D@io(r=cQFKJ#pa_*6djj
ZvSmf)WsO@~TsNw`m=Nlu#l*;94FJ{F(dhsH

literal 0
HcmV?d00001

diff --git a/tp5_AP/icons/5.gif b/tp5_AP/icons/5.gif
new file mode 100644
index 0000000000000000000000000000000000000000..9b6b607be42cfbd7aed2dd30c2bafc1ce9d3e4c9
GIT binary patch
literal 418
zcmZ?wbhEHb6lM@+_{zZ0#K6$Zz|g|L(89>r%FNu#!qUdh-p<L{&duG<!_&df-z_fQ
zEg{jTtUTG+c(SSK6m#<_78X;jtfpF9&v192>FGJk$7hzG-|T>Z*@1y`BO>NSN6(9i
znI9WFKQ3-Ta`K{#jK$g6i}Ui9m6mpQch8wKXJtdf%Erc(O--wsn^$*qteZS}{j_Q8
zr%&H7bLOT63pOuVvSrz_Ez6g0S+Qc<h7CKmZQHqh`_7#^cY*LO5ZJwY*PcDQ_wQ!_
z1I3>#U|I)6g8an5w%;Kr(?dt9-D&RHV>wo{&F+3+E3#R4<IQ2lUA~$P4HZ6o3>x<?
z^$H1a@O164nRj5x^|ua3ufF;ntz%#jUnyg2)6v;s*_@Tb#3*58FlDNNNl!~2C(qn@
zJlq2M*71p{$$5<OHo=O5LK`*;3G*^f5D!wd@b>pH*J7U_)@xzi)n%*Aap;Jyy2gcz
z8k$n96C{^pi88U=y?1vT6SLBqzGcgknE4EEnyX36e*E-FPT6>-s@1XMf2=KnoccIa
JoRl~itN|%@qD24z

literal 0
HcmV?d00001

diff --git a/tp5_AP/icons/6.gif b/tp5_AP/icons/6.gif
new file mode 100644
index 0000000000000000000000000000000000000000..2cc9004893ede6904937f1f6c3fdfea9d517e0de
GIT binary patch
literal 660
zcmZ?wbhEHb6lM@+_{PA%(9p!t(9F=-%+S=r*wn(@+{)72%GT1x-qOa=(#F-=&fVJ1
z)7sA8)*;Z=A<*6-*xo7B-YL@2CDGX}*WDx6-K)^ktJu@4(%Yxr*RRt*QMZ4h>7>b)
zlc!iso?<;^s@wD#9@A%f&Y0;nW2X0vnPIc%#LS%+J8ypC`~?{c7v(KpT(Eda;gTiA
zOP1CwU(wy&J!j6GmX)j8SFP?`y}EbJnh9&yP6VNKlh&@Ay<x-LjT`4}+&F*Z#)X?U
zE!wns+2$=Pw`^ItW$UUfTUT%0x@POvwOhAt+`fI&_U+qt?AX3z$M&5&ckBd#T|0N~
z-nnzvu3fu#?b@?z*S=l5_V3=!FbII+PZqE%bU-91P8irfHs~8Px3so3H~ISq_;~d7
z_xl8NHT!!TDag#4JzK%Z+rK%$SdeKM<BAo_m;{XjntfE5n3?&-wr}TKuI$t7CAXPP
z*TwOuvz~;gu(H=a+07g#!GTu-y<Hvbo%b4eoo8m%w6S{f#M;Tvcj4Xp%$$NBJ_?HK
zc)q^3dCTf$zjzD-&wUaN*s$P16Z0>Zg2V3GM|h<L3fBY}I5@PYz4^3phMR8}Kc}ev
zuU`}Rj|wVl^k2yc_{e-rUG<aWg$)azv2n3zO^aYxb#LopV&D*!N(gI{S)X8&dCB=G
gr*OdHSr!WyweRxkUX^*(N^{Br=LF8Z94rjh0PvmatpET3

literal 0
HcmV?d00001

diff --git a/tp5_AP/icons/7.gif b/tp5_AP/icons/7.gif
new file mode 100644
index 0000000000000000000000000000000000000000..aa755b7661dc088e2c73f8650f3b563bd3f2395e
GIT binary patch
literal 420
zcmZ?wbhEHb6lM@+_{zZ0%+TDz(9*)#(#qW0%GTP((bmr0-p<?JA<)q&*x4o8)vMUs
zr_|T4(LdRE@??|AlT9a2v79o^ZrXIm>9hT3&k3G0Cv?ud=y~&E=FN|tKR<5%{Dk=n
zQx+~vTevWN;iAk%i?S9iDOj?kaLLl5rOT_9cXxNsnKNf)<H}X7tJZX_S<|y-{nYgv
zXK&m%XXD0s8#gW7v~|taZELq}Tfc4lrtLen?bxw>$Icx)L15R;T|0My!0uhU_UziV
zcNYT~DE?#t(>fp$<R=EUg9j#Mdgw^CJI(DqmSZ*B?Cyl}Du;D9bdESa@^x(3P@(g!
z!q=uC;cVV|=e-Z}j;_3IEz10Rg4Oc^o5n_46A`9tW+~GkHB0mU3Fh)FIl@L3md<?>
ztu;8Z8F=-r&1d$`(cxyu=F(cSbk+n51HsjdtjZP>md&;>5o>2;5;NJ=zo*|qiFJXX
z!Lj2Tt+luo@aV4JJ<D33cN?e1&0A_#hC)d!3KJ(Tv(}TAkQ7%mzVOD`%Brc+%JSd;
Qe@i$lohEp6Dlk|B03blLf&c&j

literal 0
HcmV?d00001

diff --git a/tp5_AP/icons/8.gif b/tp5_AP/icons/8.gif
new file mode 100644
index 0000000000000000000000000000000000000000..283c520e31c108effb9d477e4359a3654ce8470e
GIT binary patch
literal 427
zcmZ?wbhEHb6lM@+_{zXgTwGjIQc_x4T2@w8US3{NQBhf0SzTRSQ&Uq{SJ&9s*xcOQ
z*4Eb1(b3h_)!p6Q-`_uB!i33_Cr_C&W%~5#vuDqqGiT1+xpU{wpTB6)qUFn%uUxru
z)v8tN)~#E=e*K0G8#Zs=yk*OlZQHhO-@bjvjvYI9?%cI&*Y4fB8K?vlf3kp0(gBem
zKQXYKIMANzp(EAqG<lOtmepL<rI{I8nF_sY!niNGteoYXz@st!cw=)~mZmEc(?Lha
z<?@djJu*Ft4zNooDl{ufFf%dosnpalu}Z54sY|nVboJDW%FUiF+TPhMrY2O-$FY3*
z)DEE>b@9TEjEoK9>dvYHOF4P=?BT2ss1~a&V3AZ-I;kwlGHv0Jz6q12oU7rl7m<;^
zEh93Yf1#T2Qf9Vi&)PeLbJS$HH*VU@E&E1QUR>nouV3Qw@r%6tIAlBwCJAvn^=YVl
JQs7{)1^}Q{kkkMG

literal 0
HcmV?d00001

diff --git a/tp5_AP/icons/9.gif b/tp5_AP/icons/9.gif
new file mode 100644
index 0000000000000000000000000000000000000000..50ac94d02f9e29ba36133da6281c3f0b9b2026ec
GIT binary patch
literal 337
zcmZ?wbhEHb6lM@+_{zXwYisM^;Na-!=;!Ab5fKp|AD@trkeHa5pPye=R#s6_(b(A7
z)YR16+}zR8(b?JA)z#J0(=&DI)M?YEO`kq}=FFM1XV0E9XU^QYbLY>Wzi{EgMT-_K
zUc7kOvSn-5tXa2i-R8}kckbMI=+L3VhYue+c8r1AK=CIF*hn1^3Gx#ITb{!u4;LM&
z-o*lJS1#tvyPz>e*|9=rQfJxeyFoIn=Tn_DXP<w@bwojJ@qH1~YM%Pjw@bgwo#(&)
zV{K}6USo4(Q+-WqXG?8cdw+LvZ)K6Zr0C39vuBG5vP<%F^DJ4qY$-1n3nw!p)A|h?
LH!?CfGFSrugVS!t

literal 0
HcmV?d00001

diff --git a/tp5_AP/minesweeper.py b/tp5_AP/minesweeper.py
new file mode 100644
index 0000000..f8a9772
--- /dev/null
+++ b/tp5_AP/minesweeper.py
@@ -0,0 +1,278 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+"""
+:mod:`minesweeper` module
+
+:author: gantchou koffi
+
+:date:  13/03/2025
+
+This module provides functions and a class for minesweeper's game's management.
+
+"""
+
+import random
+from enum import Enum
+from cell import Cell
+
+
+################################################
+# Type declaration
+################################################
+
+class GameState(Enum):
+    """
+    A class to define an enumerated type with three values :
+
+    * ``winning``
+    * ``losing``
+    * ``unfinished``
+
+    for the three state of minesweeper game.
+    """
+    winning = 1
+    losing = 2
+    unfinished = 3
+
+
+##############################################
+# Function for game's setup and management
+##############################################
+
+
+def neighborhood(x: int, y: int, width: int, height: int) -> list[tuple[int, int]]:
+    """
+    return the list of coordinates of the neighbors of position (x,y) in a
+             grid of size width*height
+
+    précondition: 0 <= x < width and 0 <= y < height
+
+    examples:
+
+    $$$ neighborhood(3, 3, 10, 10)
+    [(2, 2), (2, 3), (2, 4), (3, 2), (3, 4), (4, 2), (4, 3), (4, 4)]
+    $$$ neighborhood(0, 3, 10, 10)
+    [(0, 2), (0, 4), (1, 2), (1, 3), (1, 4)]
+    $$$ neighborhood(0, 0, 10, 10)
+    [(0, 1), (1, 0), (1, 1)]
+    $$$ neighborhood(9, 9, 10, 10)
+    [(8, 8), (8, 9), (9, 8)]
+    $$$ neighborhood(3, 9, 10, 10)
+    [(2, 8), (2, 9), (3, 8), (4, 8), (4, 9)]
+    """
+    res=[]
+    for dx in [-1,0,1]:
+        for dy in [-1,0,1]:
+            if dx==0 and dy==0:
+                continue
+            nx,ny = x + dx , y + dy
+            
+            if (0 <= nx < width) and (0 <= ny < height):
+                res.append((nx,ny))
+    return res
+    
+    
+    
+    
+    
+    
+    
+
+class Minesweeper():
+    """
+    $$$ game = Minesweeper(20, 10, 4)
+    $$$ game.width
+    20
+    $$$ game.height
+    10
+    $$$ game.nbombs
+    4
+    $$$ game.state == GameState.unfinished 
+    True
+    $$$ cel = game.get_cell(1, 2)
+    $$$ cel.is_revealed
+    False
+    $$$ 
+    """
+    
+    
+    
+    
+    
+    import random
+    def __init__(self, width: int=30, height: int=20, nbombs: int=99):
+        """
+        build a minesweeper grid of size `width*height` of cells
+        with `nbombs` bombs randomly placed.
+
+        for each build cell, this constructor sets the  number of bombs
+        in neighborhood.
+
+        precondition: width and height must be positive integers, and
+             nbombs <= width * height
+
+        example:
+
+        $$$ game = Minesweeper(20, 10, 4)
+        $$$ game.width
+        20
+        $$$ game.height
+        10
+        $$$ game.nbombs
+        4
+        $$$ game.state == GameState.unfinished 
+        True
+        """
+        self.width = width
+        self.height = height
+        self.nbombs = nbombs
+        self.state = GameState.unfinished 
+        self.grille = [[Cell() for _ in range(height)] for _ in range(width)]
+        
+            
+        bombs_cell = random.sample(range(width*height),nbombs)
+        for nub_bomb in bombs_cell:
+            x = nub_bomb//height
+            y = nub_bomb%height 
+            self._put_a_bomb_at(x,y)  
+            
+        
+
+    def get_cell(self, x: int, y: int) -> Cell:
+        """
+        return: the cell of coordinates (x,y) in the game's grid
+
+        precondition: 0 <= x < width of game and O <= y < height of game
+
+        $$$ game = Minesweeper(20, 10, 4)
+        $$$ sum(1 for x in range(20) for y in range(10) if game.get_cell(x, y).is_bomb)
+        4
+        """
+        if x>=0 and x < self.width  and y>=0 and y < self.height:
+            return self.grille[x][y]
+        
+     
+        
+        
+        
+
+    def _put_a_bomb_at(self, x: int, y: int):
+        """
+        this method change the cells's state at x, y to a bomb,
+
+        if the cell is already a bomb, nothing append.
+        otherwise it change cell's state and increments by one every
+        cells in its neighborhood.
+
+        precondition: 0 <= x < self.width and 0 <= y < self.height
+
+        exemples:
+
+        $$$ game = Minesweeper(10, 5, 0)
+        $$$ voisins = neighborhood(1, 1, game.width, game.height)
+        $$$ all(game.get_cell(x, y).nbombs_in_neighborhood == 0 for x, y in voisins)
+        True
+        $$$ game._put_a_bomb_at(1, 1)
+        $$$ all(game.get_cell(x, y).nbombs_in_neighborhood == 1 for x, y in voisins)
+        True
+        $$$ game._put_a_bomb_at(1, 1)
+        $$$ all(game.get_cell(x, y).nbombs_in_neighborhood == 1 for x, y in voisins)
+        True
+        """
+        cell = self.get_cell(x,y)
+        
+        if cell.is_bomb:
+            return
+        cell.is_bomb = True
+        voisins = neighborhood(x,y,self.width,self.height)
+        for nx,ny in voisins:
+            neighbor_cell = self.get_cell(nx,ny)
+            neighbor_cell.nbombs_in_neighborhood+=1
+            
+        
+        
+
+    def all_cells_are_revealed_or_bomb(self) -> bool:
+        """
+        return True iff all cells are revealed or bomb.
+
+        précondition: none
+
+        """
+        for i in range(self.width):
+            for j in range(self.height):
+                if self.grille[i][j].is_revealed or self.grille[i][j].is_bomb:
+                    continue
+                else:
+                    return False
+        return True  
+        
+
+    def reveal_all_cells_from(self, x, y):
+        """
+        recursively reveal all cells of game game from the initial cell (x,y).
+
+        * if the cell is a bomb one, update game's state to losing.
+        * otherwise if the cell's neighborhood doesn't contains bomb,
+          recursively reveal all neighboors.
+        * and finally, if all cell's are revealed, update game's state to
+          winning
+        
+        precondition: 0 <= x < width of game and O <= y < height of game
+
+        exemples:
+
+        $$$ game = Minesweeper(20, 10, 0)
+        $$$ game._put_a_bomb_at(1, 1)
+        $$$ game.state
+        GameState.unfinished
+        $$$ game.all_cells_are_revealed_or_bomb()
+        False
+        $$$ game.reveal_all_cells_from(5, 5)
+        $$$ game.all_cells_are_revealed_or_bomb()
+        False
+        $$$ game.reveal_all_cells_from(0, 0)
+        $$$ game.reveal_all_cells_from(1, 0)
+        $$$ game.reveal_all_cells_from(0, 1) 
+        $$$ game.all_cells_are_revealed_or_bomb()
+        True
+        $$$ game.state
+        GameState.winning
+        $$$ game = Minesweeper(20, 10, 0)
+        $$$ game._put_a_bomb_at(1, 1)
+        $$$ game.reveal_all_cells_from(1, 1)
+        $$$ game.state
+        GameState.losing
+        """
+        if self.grille[x][y].is_bomb:
+            self.state = GameState.losing
+            print('vous avez perdu !')
+            return
+        else:
+            self.grille[x][y].is_revealed = True 
+            voisins=neighborhood(x,y,self.width,self.height)
+            
+            if all(not(self.get_cell(elt[0],elt[1]).is_bomb) for elt in voisins):
+                for vx,vy in voisins:
+                    if not(self.get_cell(vx,vy).is_revealed):
+                        self.reveal_all_cells_from(vx,vy)             
+        if self.all_cells_are_revealed_or_bomb():
+            self.state = GameState.winning
+            print('vous avez gagné')
+            
+            
+        
+        
+        
+        
+        
+        
+        
+        
+
+
+if (__name__ == '__main__'):
+    import apl1test
+    apl1test.testmod('minesweeper.py')
+
diff --git a/tp5_AP/p1.py b/tp5_AP/p1.py
new file mode 100644
index 0000000..e69de29
-- 
GitLab