From 14e5df43326b98b183bb428a610abb9ee68487a0 Mon Sep 17 00:00:00 2001 From: amary Date: Tue, 3 Feb 2026 10:38:14 +0100 Subject: [PATCH 1/4] =?UTF-8?q?Test=20de=20isLegal=20(=C3=A0=20debug)=20[w?= =?UTF-8?q?ip]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 15 ++- fr/iut_fbleau/Tests/AvalamBoardTest.java | 122 +++++++++++++++++++++++ 2 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 fr/iut_fbleau/Tests/AvalamBoardTest.java diff --git a/Makefile b/Makefile index 1719ab9..a748833 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,6 @@ +# === Environnements === +TEST_ENV = "bin:/usr/share/java/junit.jar:/usr/share/java/hamcrest-core.jar" + # === Répertoires === SRC_DIR = fr BIN_DIR = bin @@ -12,12 +15,16 @@ SOURCES := $(shell find $(SRC_DIR) -name "*.java") # === Classe principale === MAIN_CLASS = fr.iut_fbleau.Avalam.Main +# === Classe de test === +TEST_CLASS = fr.iut_fbleau.Tests.AvalamBoardTest + # === Commandes Java === JC = javac -JCFLAGS = -d $(BIN_DIR) +JCFLAGS = -d $(BIN_DIR) -cp $(TEST_ENV) JAVA = java JAVAFLAGS = -cp $(BIN_DIR) +JAVAFLAGS_TESTS = -cp $(TEST_ENV) # === Règle par défaut === all: build @@ -43,6 +50,12 @@ run: @echo "===> Lancement du jeu Avalam..." @$(JAVA) $(JAVAFLAGS) $(MAIN_CLASS) +# === Tests === +test: + @echo "===> Lancement des tests..." + @$(JAVA) $(JAVAFLAGS_TESTS) org.junit.runner.JUnitCore $(TEST_CLASS) + @echo "... Fin des tests." + # === Nettoyage === clean: @echo "===> Suppression des fichiers compilés..." diff --git a/fr/iut_fbleau/Tests/AvalamBoardTest.java b/fr/iut_fbleau/Tests/AvalamBoardTest.java new file mode 100644 index 0000000..47de29e --- /dev/null +++ b/fr/iut_fbleau/Tests/AvalamBoardTest.java @@ -0,0 +1,122 @@ +package fr.iut_fbleau.Tests; + +import fr.iut_fbleau.GameAPI.AbstractPly; +import fr.iut_fbleau.GameAPI.Player; + +import fr.iut_fbleau.Avalam.AvalamBoard; +import fr.iut_fbleau.Avalam.AvalamPly; +import fr.iut_fbleau.Avalam.Tower; +import fr.iut_fbleau.Avalam.Color; + +import org.junit.Before; +import org.junit.Test; +//import org.mockito.Mockito; //À retirer si Mockito absent + +import static org.junit.Assert.*; + +/** +* La classe AvalamBoardTest test si la méthode isLegal() fonctionne comme prévu. +*/ +public class AvalamBoardTest { + + private Tower[][] grid; + private AvalamBoard board; + + @Before + public void setUp() { + grid = new Tower[AvalamBoard.SIZE][AvalamBoard.SIZE]; + // Par défaut, current player sera PLAYER1 via constructeur sans joueur + board = new AvalamBoard(grid); + } + + /* + @Test //À retirer si Mockito absent + public void nonAvalamPly_returnsFalse() { + AbstractPly fake = Mockito.mock(AbstractPly.class); // instance non-AvalamPly + assertFalse(board.isLegal(fake)); + }*/ + + @Test + public void outOfBounds_returnsFalse() { + grid[2][2] = new Tower(1, Color.YELLOW); + grid[2][3] = new Tower(1, Color.RED); + AvalamPly p = new AvalamPly(Player.PLAYER1, -1, 2, 2, 3); + assertFalse(board.isLegal(p)); + + AvalamPly p2 = new AvalamPly(Player.PLAYER1, 2, 2, 9, 3); + assertFalse(board.isLegal(p2)); + } + + @Test + public void sameCell_returnsFalse() { + grid[4][4] = new Tower(1, Color.YELLOW); + AvalamPly p = new AvalamPly(Player.PLAYER1, 4, 4, 4, 4); + assertFalse(board.isLegal(p)); + } + + @Test + public void emptySourceOrDest_returnsFalse() { + // source null + grid[3][3] = null; + grid[3][4] = new Tower(1, Color.RED); + AvalamPly p1 = new AvalamPly(Player.PLAYER1, 3, 3, 3, 4); + assertFalse(board.isLegal(p1)); + + // dest null + grid[5][5] = new Tower(1, Color.YELLOW); + grid[5][6] = null; + AvalamPly p2 = new AvalamPly(Player.PLAYER1, 5, 5, 5, 6); + assertFalse(board.isLegal(p2)); + } + + @Test + public void sourceNotOwned_returnsFalse() { + // current player = PLAYER1 -> color must be YELLOW + grid[2][2] = new Tower(1, Color.RED); // not owned + grid[2][3] = new Tower(1, Color.YELLOW); + AvalamPly p = new AvalamPly(Player.PLAYER1, 2, 2, 2, 3); + assertFalse(board.isLegal(p)); + } + + @Test + public void notAdjacent_returnsFalse() { + grid[0][0] = new Tower(1, Color.YELLOW); + grid[0][2] = new Tower(1, Color.RED); + AvalamPly p = new AvalamPly(Player.PLAYER1, 0, 0, 0, 2); + assertFalse(board.isLegal(p)); + } + + @Test + public void sameColor_returnsFalse() { + grid[6][6] = new Tower(1, Color.YELLOW); + grid[6][7] = new Tower(1, Color.YELLOW); // same color as source + AvalamPly p = new AvalamPly(Player.PLAYER1, 6, 6, 6, 7); + assertFalse(board.isLegal(p)); + } + + @Test + public void tooTallAfterMerge_returnsFalse() { + grid[1][1] = new Tower(3, Color.YELLOW); + grid[1][2] = new Tower(3, Color.RED); // 3+3 = 6 > MAX_HEIGHT (5) + AvalamPly p = new AvalamPly(Player.PLAYER1, 1, 1, 1, 2); + assertFalse(board.isLegal(p)); + } + + @Test + public void validMove_returnsTrue() { + grid[4][4] = new Tower(2, Color.YELLOW); // owned by PLAYER1 + grid[4][5] = new Tower(2, Color.RED); // opposite color + AvalamPly p = new AvalamPly(Player.PLAYER1, 4, 4, 4, 5); + assertTrue(board.isLegal(p)); + } + + @Test + public void currentPlayerMismatchInPlyDoesNotAffectOwnershipCheck() { + // Even if AvalamPly is constructed with a player value, isLegal uses board.getCurrentPlayer() + grid[7][7] = new Tower(1, Color.YELLOW); // owned by PLAYER1 (board default) + grid[7][8] = new Tower(1, Color.RED); + // Construct ply with PLAYER2 explicitly — ownership check should still compare to board.getCurrentPlayer() + AvalamPly p = new AvalamPly(Player.PLAYER2, 7, 7, 7, 8); + assertFalse(board.isLegal(p)); + } +} From fa578b86d2cb1e16f819fc21394b935fbdbc2724 Mon Sep 17 00:00:00 2001 From: amary Date: Thu, 5 Feb 2026 11:50:15 +0100 Subject: [PATCH 2/4] =?UTF-8?q?Adaptation=20du=20test=20(Board=20copie=20l?= =?UTF-8?q?a=20grille)=20(=C3=A0=20tester)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fr/iut_fbleau/Tests/AvalamBoardTest.java | 83 ++++++++++++------------ 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/fr/iut_fbleau/Tests/AvalamBoardTest.java b/fr/iut_fbleau/Tests/AvalamBoardTest.java index 47de29e..36e4ffd 100644 --- a/fr/iut_fbleau/Tests/AvalamBoardTest.java +++ b/fr/iut_fbleau/Tests/AvalamBoardTest.java @@ -10,7 +10,7 @@ import fr.iut_fbleau.Avalam.Color; import org.junit.Before; import org.junit.Test; -//import org.mockito.Mockito; //À retirer si Mockito absent +//import org.mockito.Mockito; //Mockito absent import static org.junit.Assert.*; @@ -25,98 +25,99 @@ public class AvalamBoardTest { @Before public void setUp() { grid = new Tower[AvalamBoard.SIZE][AvalamBoard.SIZE]; - // Par défaut, current player sera PLAYER1 via constructeur sans joueur - board = new AvalamBoard(grid); + + //Création des tours de tests + /* Motif + 1,0,2 | 2,0,3 + 2,1,0 | 2,3,0 + 0,2,1 | 0,1,1 + */ + grid[4][2] = new Tower(2, Color.YELLOW); + grid[6][2] = new Tower(3, Color.RED); + + grid[4][3] = new Tower(2, Color.RED); + grid[5][3] = new Tower(3, Color.YELLOW); + + grid[5][4] = new Tower(1, Color.RED); + grid[6][4] = new Tower(1, Color.YELLOW); + + //Joueur courant initialisé à 1, soit jaune + board = new AvalamBoard(grid); //AvalamBoard copie la grille } /* - @Test //À retirer si Mockito absent + @Test //Mockito absent public void nonAvalamPly_returnsFalse() { - AbstractPly fake = Mockito.mock(AbstractPly.class); // instance non-AvalamPly + //Vérifie si l'instance est bien AvalamPly + AbstractPly fake = Mockito.mock(AbstractPly.class); //Crée une instance non-AvalamPly assertFalse(board.isLegal(fake)); }*/ @Test public void outOfBounds_returnsFalse() { - grid[2][2] = new Tower(1, Color.YELLOW); - grid[2][3] = new Tower(1, Color.RED); - AvalamPly p = new AvalamPly(Player.PLAYER1, -1, 2, 2, 3); + //Source "out of box" + AvalamPly p = new AvalamPly(Player.PLAYER1, -1, 2, 4, 2); assertFalse(board.isLegal(p)); - AvalamPly p2 = new AvalamPly(Player.PLAYER1, 2, 2, 9, 3); + //Destination "out of box" + AvalamPly p2 = new AvalamPly(Player.PLAYER1, 6, 4, 9, 4); assertFalse(board.isLegal(p2)); } @Test public void sameCell_returnsFalse() { - grid[4][4] = new Tower(1, Color.YELLOW); - AvalamPly p = new AvalamPly(Player.PLAYER1, 4, 4, 4, 4); + AvalamPly p = new AvalamPly(Player.PLAYER1, 5, 4, 5, 4); assertFalse(board.isLegal(p)); } @Test public void emptySourceOrDest_returnsFalse() { - // source null - grid[3][3] = null; - grid[3][4] = new Tower(1, Color.RED); - AvalamPly p1 = new AvalamPly(Player.PLAYER1, 3, 3, 3, 4); + //Source null + AvalamPly p1 = new AvalamPly(Player.PLAYER1, 5, 5, 5, 4); assertFalse(board.isLegal(p1)); - // dest null - grid[5][5] = new Tower(1, Color.YELLOW); - grid[5][6] = null; - AvalamPly p2 = new AvalamPly(Player.PLAYER1, 5, 5, 5, 6); + //Destination null + AvalamPly p2 = new AvalamPly(Player.PLAYER1, 6, 4, 6, 3); assertFalse(board.isLegal(p2)); } @Test public void sourceNotOwned_returnsFalse() { - // current player = PLAYER1 -> color must be YELLOW - grid[2][2] = new Tower(1, Color.RED); // not owned - grid[2][3] = new Tower(1, Color.YELLOW); - AvalamPly p = new AvalamPly(Player.PLAYER1, 2, 2, 2, 3); + //Le joueur courant n'est pas rouge + AvalamPly p = new AvalamPly(Player.PLAYER1, 5, 4, 6, 4); assertFalse(board.isLegal(p)); } @Test public void notAdjacent_returnsFalse() { - grid[0][0] = new Tower(1, Color.YELLOW); - grid[0][2] = new Tower(1, Color.RED); - AvalamPly p = new AvalamPly(Player.PLAYER1, 0, 0, 0, 2); + AvalamPly p = new AvalamPly(Player.PLAYER1, 4, 2, 6, 2); assertFalse(board.isLegal(p)); } @Test public void sameColor_returnsFalse() { - grid[6][6] = new Tower(1, Color.YELLOW); - grid[6][7] = new Tower(1, Color.YELLOW); // same color as source - AvalamPly p = new AvalamPly(Player.PLAYER1, 6, 6, 6, 7); + //La couleur des tours est identique + AvalamPly p = new AvalamPly(Player.PLAYER1, 4, 2, 5, 3); assertFalse(board.isLegal(p)); } @Test public void tooTallAfterMerge_returnsFalse() { - grid[1][1] = new Tower(3, Color.YELLOW); - grid[1][2] = new Tower(3, Color.RED); // 3+3 = 6 > MAX_HEIGHT (5) - AvalamPly p = new AvalamPly(Player.PLAYER1, 1, 1, 1, 2); + //Hauteur maximale dépassé : 3+3 = 6 > MAX_HEIGHT (5) + AvalamPly p = new AvalamPly(Player.PLAYER1, 5, 3, 6, 2); assertFalse(board.isLegal(p)); } @Test public void validMove_returnsTrue() { - grid[4][4] = new Tower(2, Color.YELLOW); // owned by PLAYER1 - grid[4][5] = new Tower(2, Color.RED); // opposite color - AvalamPly p = new AvalamPly(Player.PLAYER1, 4, 4, 4, 5); + AvalamPly p = new AvalamPly(Player.PLAYER1, 5, 3, 4, 3); //Hauteur limite à 5 assertTrue(board.isLegal(p)); } - @Test + @Test //À vérifier public void currentPlayerMismatchInPlyDoesNotAffectOwnershipCheck() { - // Even if AvalamPly is constructed with a player value, isLegal uses board.getCurrentPlayer() - grid[7][7] = new Tower(1, Color.YELLOW); // owned by PLAYER1 (board default) - grid[7][8] = new Tower(1, Color.RED); - // Construct ply with PLAYER2 explicitly — ownership check should still compare to board.getCurrentPlayer() - AvalamPly p = new AvalamPly(Player.PLAYER2, 7, 7, 7, 8); + //Si le coup est construit avec le mauvais joueur + AvalamPly p = new AvalamPly(Player.PLAYER2, 4, 2, 4, 3); assertFalse(board.isLegal(p)); } } From c0cd120b1ec1e27da38f346b5801bbb2d4cbbef6 Mon Sep 17 00:00:00 2001 From: amary Date: Thu, 5 Feb 2026 11:52:12 +0100 Subject: [PATCH 3/4] =?UTF-8?q?Ajout=20de=20la=20commande=20de=20test=20au?= =?UTF-8?q?=20ReadMe=20+=20l=C3=A9g=C3=A8res=20corrections=20de=20langue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3b63058..4531d8c 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,11 @@ Date de création : 16/10/25 -Le but est de mettre en oeuvre des jeux plus intéressants que le jeu de Nim, toujours en suivant l'API. +Date de rendu : 06/02/26 -Dans un second temps, on fera des bots le plus efficace possible (probablement un alpha beta avec cut-off plus fonction d'évaluation qui peut être faite à la main ou par MonteCarlo). +Le but est de mettre en oeuvre un jeu plus intéressants que le jeu de Nim, en suivant l'API de Florent Madelaine. + +Dans un second temps, nous développerons des bots les plus efficaces possible, probablement en utilisant un algorithme alpha-bêta avec cut-off et une fonction d'évaluation réalisé à la main ou par MonteCarlo. Le jeu de notre groupe est **Avalam**. @@ -17,6 +19,11 @@ Le jeu de notre groupe est **Avalam**. make build ``` +### Tests +```bash +make test +``` + ### Exécution ```bash make run @@ -78,13 +85,13 @@ Le plateau est représenté par une grille 9x9 où chaque case contient : Sur un plateau de jeu, les joueurs disposent de 24 pions chacun. Le but est de créer de petites tours avec son pion de couleur au-dessus. Pour ce faire, chaque joueur déplace son pion sur une tour ou déplace une tour sur un autre pion. La personne ayant le plus de pions sur le dessus des tours gagne. -### Régles officiel : +### Règles officielles : **Régle de base** \ Chaque joueur choisit sa couleur. Le but du jeu est de constituer un maximum de tours de 1 à 5 pions, jamais plus, surmontées par un pion de sa couleur. Un joueur est le propriétaire d'une tour lorsqu'un pion de sa couleur en occupe le sommet. Un pion isolé constitue également une tour. -**Deplacements** \ +**Déplacements** \ Chaque joueur en effectue un seul mouvement, dans n'importe quel sens (horizontal, vertical, diagonal) avec n'importe quel pion (ou pile de pions), quelle qu'en soit la couleur. Ce mouvement consiste à empiler le ou les pions déplacés sur un trou directement voisin déjà occupé par un ou plusieurs pions. **Mouvement interdit (1)** \ From f43361a48f27f34d08fcfac81449fa54254691fe Mon Sep 17 00:00:00 2001 From: amary Date: Thu, 5 Feb 2026 16:06:03 +0100 Subject: [PATCH 4/4] =?UTF-8?q?Ajout=20v=C3=A9rification=20correspondance?= =?UTF-8?q?=20du=20Joueur=20(Test=20Ok)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fr/iut_fbleau/Avalam/AvalamBoard.java | 1 + 1 file changed, 1 insertion(+) diff --git a/fr/iut_fbleau/Avalam/AvalamBoard.java b/fr/iut_fbleau/Avalam/AvalamBoard.java index a91a8a9..9ef33e1 100644 --- a/fr/iut_fbleau/Avalam/AvalamBoard.java +++ b/fr/iut_fbleau/Avalam/AvalamBoard.java @@ -205,6 +205,7 @@ public class AvalamBoard extends AbstractBoard { Tower dst = grid[xT][yT]; if (src == null || dst == null) return false; + if (p.getPlayer() != getCurrentPlayer()) return false; if (src.getColor() != colorForPlayer(getCurrentPlayer())) return false; if (!areAdjacent(xF, yF, xT, yT)) return false; if (src.getColor() == dst.getColor()) return false;