From 353163005704843ac96f8875a85efb6bcb0ea367 Mon Sep 17 00:00:00 2001
From: l21211714 <tom.larguier@etu.univ-amu.fr>
Date: Fri, 8 Dec 2023 17:18:18 +0100
Subject: [PATCH] Ce con sait pas faire de git

---
 __pycache__/puissance4.cpython-310.pyc      | Bin 0 -> 3232 bytes
 __pycache__/test_puissance4.cpython-310.pyc | Bin 0 -> 1963 bytes
 puissance4.py                               | 140 ++++++++++++++++++++
 test_puissance4.py                          |  51 +++++++
 4 files changed, 191 insertions(+)
 create mode 100644 __pycache__/puissance4.cpython-310.pyc
 create mode 100644 __pycache__/test_puissance4.cpython-310.pyc
 create mode 100644 puissance4.py
 create mode 100644 test_puissance4.py

diff --git a/__pycache__/puissance4.cpython-310.pyc b/__pycache__/puissance4.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b1015cf425bb15d7419ab92b9e42e8f458fbe8b6
GIT binary patch
literal 3232
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

literal 0
HcmV?d00001

diff --git a/__pycache__/test_puissance4.cpython-310.pyc b/__pycache__/test_puissance4.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..68241a7089fc93ded2a8e6c79ab4c72b6010ec30
GIT binary patch
literal 1963
zcmd1j<>g{vU|`r|S)3}u#=!6x#6iX^3=9ko3=9m#VGIlmDGVu$ISf${nlXwgg&~D0
zhdGxeiY1pdiZz!liY=EtianPjii45Cogsxeg{6fdg(a0Ci?f+IiYt{ng*BV0NHdjT
z0nb7PMurr|U@+EXdkM19Pm}c)PjXReVo7RzQhs7l$}Pdn;`p+}oXnK?oc!d(lFa<P
zTU;qc`33O>nW@RCxA=-u%TkMqQ{$8Kb4qjbZt;|7=H+GPrN`&ym!&3yj6}vvFprop
zFfgPtL@}l?L@}i>rZBZIL@`608pV>rn!?t?5XG9pp2E?>5XF|lnZnh=5XGLt9n7G~
zbBiw|wYVgpG_$xkF)umQB$*M(0+9Kjz;Xr!mKFm8LkUAOLoH(s!ve+{#w?~3#)V9b
z3^fc3m}?kQn6jA`uq<R)$jHc$!Vt`$$?T`e^pcH%f#D@P0|P@5$XHF*B9Mu<xD$(u
zQ;SMm3riDoZm||;Bo?IJ;(~~U6qTmlVouD-S;=&Zr8qSw?G`II+*UFa2{JG+e061D
zU~smI2`x@7Dvl}1&&^4U@eB=#2{w%hEKSVGEIGVVAu%UCKPDtV0q!RSlbDj!;*$6R
zxF_`rDsKsb#gO9$<k(^m!N$nPD8^W&fEqG-7#c9biWTHK%&;n9s$ooFY-R$54Jfq0
zd?pAV8dfhs;q#J%fq_Aj1sq64JfKixW?*1|1(#c5PH}1xA4nJ!6yWeE5&|g@1G@|(
zVR3_80`ZRkqX=V_DmMRM=)&+6JOQY|6F><g$U`ZN&CKBF2YHW4k^zz&pdKm`0r`dL
zB`8QBk<SeA7s$9GQ2xZ~6@IW+5E()M;Rha&ALOw40ihhl@u0v1Sr1OVpd128y(OTy
zV02-K<)~$X#6$`c$Rma9;J9G{rDfE(0XrG&A7}z*ElSKwPb~tAgX0Ml%9_kY{GiAI
zIr$c2JS2X=F$In!NP0ug&Y~c{fufv^k%y5F<U6b>4p|F^|2SbOt_B=A3mDTGQWzJ3
zNG34J3?`A;AQ85OjJ1qlzq2$mF*1}eAn60iGo(OBWPKnuNFNh8lo%GU)G*dCEd-}&
zaFnz9X|jVO8b1M5^b%AM;8Y1!1WrRZ6&1;WQW)zkro4hE*2JQs#L6O2Y=bjS6gOBP
zJ{45NAV*9Te`-ZRYH~?xN_<gjacNEodNc`x6Ci3SEDee%6$S<d7DhH?_=}5^g$Y$e
zjI&A!TM|Vz&`*=&7Ds%1USe))eEco0`1suXl+qj!n<qXV<Yb6UkuWGdiGv795Fra9
z6hH(xSs@5e0xJR)v!DPd2Bk<21`b9JRuJT21IvKy%T3J8i;vgjjp8WH%PawTG>SE^
zG`FC#NS=X#A&Lu8Kti%AC<8$fImp~1P$Iv@0rH)5VsR?i)FMSt`NIM-7%3pZ4g<OA
d7KaVQXLg|Ctr%2xfgC2oD8$5}%fra>9{_i^v2p+a

literal 0
HcmV?d00001

diff --git a/puissance4.py b/puissance4.py
new file mode 100644
index 0000000..c0600bb
--- /dev/null
+++ b/puissance4.py
@@ -0,0 +1,140 @@
+import numpy as np
+
+def create_board():
+    return np.zeros((6, 7), dtype=int)
+
+def print_board(board):
+    for row in board:
+        print("|", end="")
+        for col in row:
+            if col == 0:
+                print("   ", end="|")
+            elif col == 1:
+                print(" X ", end="|")
+            elif col == 2:
+                print(" O ", end="|")
+        print()
+        print("+---" * 7)
+
+def is_valid_location(board, col):
+    return board[0, col - 1] == 0 if 1 <= col <= 7 else False
+
+def drop_piece(board, col, player):
+    for row in range(5, -1, -1):
+        if board[row, col - 1] == 0:
+            board[row, col - 1] = player
+            break
+
+def winning_move(board, player):
+    for col in range(4):
+        for row in range(6):
+            if (
+                board[row, col] == player
+                and board[row, col + 1] == player
+                and board[row, col + 2] == player
+                and board[row, col + 3] == player
+            ):
+                return True
+
+    for col in range(7):
+        for row in range(3):
+            if (
+                board[row, col] == player
+                and board[row + 1, col] == player
+                and board[row + 2, col] == player
+                and board[row + 3, col] == player
+            ):
+                return True
+
+    for col in range(4):
+        for row in range(3):
+            if (
+                board[row, col] == player
+                and board[row + 1, col + 1] == player
+                and board[row + 2, col + 2] == player
+                and board[row + 3, col + 3] == player
+            ):
+                return True
+
+    for col in range(4):
+        for row in range(3, 6):
+            if (
+                board[row, col] == player
+                and board[row - 1, col + 1] == player
+                and board[row - 2, col + 2] == player
+                and board[row - 3, col + 3] == player
+            ):
+                return True
+
+    return False
+
+def reverse_column(board, col, turn):
+    board[:, col - 1] = np.flip(board[:, col - 1])
+
+    for col_index in range(col - 1, col):
+        col_data = board[:, col_index]
+        non_zero_elements = col_data[col_data != 0]
+        num_zeros = 6 - len(non_zero_elements)
+        new_col = np.concatenate((np.zeros(num_zeros, dtype=int), non_zero_elements))
+        board[:, col_index] = new_col
+
+    return 3 - turn
+
+
+def play_game():
+    board = create_board()
+    game_over = False
+    turn = 1
+
+    while not game_over:
+        print_board(board)
+
+        if turn == 1:
+            user_input = input("Joueur 1 (X), choisissez une colonne (1-7, -1 pour quitter, r1 pour inverser verticalement la colonne 1) : ")
+        else:
+            print("Tour de l'IA :")
+            col_input = str(np.random.randint(1, 8))
+
+            if np.random.rand() < 0.2:
+                available_cols = [col for col in range(1, 8) if board[5, col - 1] != 0]
+                if available_cols:
+                    col_to_reverse = np.random.choice(available_cols)
+                    turn = reverse_column(board, col_to_reverse, turn)
+                    print(f"Colonne {col_to_reverse} inversée (IA).")
+                    continue
+
+            user_input = col_input
+
+        try:
+            if user_input.startswith("r") and 1 <= int(user_input[1:]) <= 7:
+                col_to_reverse = int(user_input[1:])
+                turn = reverse_column(board, col_to_reverse, turn)
+                print(f"Colonne {col_to_reverse} inversée.")
+            else:
+                col = int(user_input)
+
+                if col == -1:
+                    print("Partie interrompue.")
+                    game_over = True
+                elif is_valid_location(board, col):
+                    drop_piece(board, col, turn)
+
+                    if winning_move(board, turn):
+                        print_board(board)
+                        print(f"Joueur {turn} a gagné!")
+                        game_over = True
+                    else:
+                        turn = 3 - turn
+
+                    if np.all(board != 0):
+                        print_board(board)
+                        print("Match nul!")
+                        game_over = True
+                else:
+                    print("Colonne invalide. Choisissez à nouveau.")
+        except ValueError:
+            print("Entrée invalide. Veuillez saisir un nombre de colonne (1-7, -1 pour quitter, r1 pour inverser la colonne 1).")
+
+
+if __name__ == "__main__":
+    play_game()
diff --git a/test_puissance4.py b/test_puissance4.py
new file mode 100644
index 0000000..dfc534b
--- /dev/null
+++ b/test_puissance4.py
@@ -0,0 +1,51 @@
+import unittest
+import numpy as np
+from puissance4 import create_board, is_valid_location, drop_piece, reverse_column, winning_move
+
+class TestPuissance4(unittest.TestCase):
+    def test_create_board(self):
+        board = create_board()
+        self.assertEqual(board.shape, (6, 7))
+        self.assertTrue((board == 0).all())
+
+    def test_is_valid_location(self):
+        board = create_board()
+        self.assertTrue(is_valid_location(board, 1))
+        self.assertFalse(is_valid_location(board, 8))
+
+    def test_drop_piece(self):
+        board = create_board()
+        drop_piece(board, 1, 1)
+        self.assertEqual(board[5, 0], 1)
+
+    def test_winning_move(self):
+        board = create_board()
+        for _ in range(4):
+            drop_piece(board, 1, 1)
+        self.assertTrue(winning_move(board, 1))
+
+    def test_reverse_column(self):
+        board = np.array([
+            [0, 0, 0, 0, 0, 0, 0],
+            [0, 2, 0, 0, 0, 0, 0],
+            [0, 1, 0, 0, 0, 0, 0],
+            [0, 2, 0, 0, 0, 0, 0],
+            [0, 1, 0, 0, 0, 0, 0],
+            [0, 1, 0, 0, 0, 0, 0]
+        ])
+
+        reverse_column(board, 2)
+
+        expected_result = np.array([
+            [0, 0, 0, 0, 0, 0, 0],
+            [0, 1, 0, 0, 0, 0, 0],
+            [0, 1, 0, 0, 0, 0, 0],
+            [0, 2, 0, 0, 0, 0, 0],
+            [0, 1, 0, 0, 0, 0, 0],
+            [0, 2, 0, 0, 0, 0, 0]
+        ])
+
+        self.assertTrue(np.array_equal(board, expected_result))
+
+if __name__ == '__main__':
+    unittest.main()
-- 
GitLab