2 Commits

2 changed files with 53 additions and 45 deletions

View File

@@ -4,9 +4,11 @@
Date de création : 16/10/25 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**. Le jeu de notre groupe est **Avalam**.
@@ -17,6 +19,11 @@ Le jeu de notre groupe est **Avalam**.
make build make build
``` ```
### Tests
```bash
make test
```
### Exécution ### Exécution
```bash ```bash
make run 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. 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** \ **Régle de base** \
Chaque joueur choisit sa couleur. 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. 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. 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. 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)** \ **Mouvement interdit (1)** \

View File

@@ -10,7 +10,7 @@ import fr.iut_fbleau.Avalam.Color;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
//import org.mockito.Mockito; //À retirer si Mockito absent //import org.mockito.Mockito; //Mockito absent
import static org.junit.Assert.*; import static org.junit.Assert.*;
@@ -25,98 +25,99 @@ public class AvalamBoardTest {
@Before @Before
public void setUp() { public void setUp() {
grid = new Tower[AvalamBoard.SIZE][AvalamBoard.SIZE]; 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() { 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)); assertFalse(board.isLegal(fake));
}*/ }*/
@Test @Test
public void outOfBounds_returnsFalse() { public void outOfBounds_returnsFalse() {
grid[2][2] = new Tower(1, Color.YELLOW); //Source "out of box"
grid[2][3] = new Tower(1, Color.RED); AvalamPly p = new AvalamPly(Player.PLAYER1, -1, 2, 4, 2);
AvalamPly p = new AvalamPly(Player.PLAYER1, -1, 2, 2, 3);
assertFalse(board.isLegal(p)); 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)); assertFalse(board.isLegal(p2));
} }
@Test @Test
public void sameCell_returnsFalse() { public void sameCell_returnsFalse() {
grid[4][4] = new Tower(1, Color.YELLOW); AvalamPly p = new AvalamPly(Player.PLAYER1, 5, 4, 5, 4);
AvalamPly p = new AvalamPly(Player.PLAYER1, 4, 4, 4, 4);
assertFalse(board.isLegal(p)); assertFalse(board.isLegal(p));
} }
@Test @Test
public void emptySourceOrDest_returnsFalse() { public void emptySourceOrDest_returnsFalse() {
// source null //Source null
grid[3][3] = null; AvalamPly p1 = new AvalamPly(Player.PLAYER1, 5, 5, 5, 4);
grid[3][4] = new Tower(1, Color.RED);
AvalamPly p1 = new AvalamPly(Player.PLAYER1, 3, 3, 3, 4);
assertFalse(board.isLegal(p1)); assertFalse(board.isLegal(p1));
// dest null //Destination null
grid[5][5] = new Tower(1, Color.YELLOW); AvalamPly p2 = new AvalamPly(Player.PLAYER1, 6, 4, 6, 3);
grid[5][6] = null;
AvalamPly p2 = new AvalamPly(Player.PLAYER1, 5, 5, 5, 6);
assertFalse(board.isLegal(p2)); assertFalse(board.isLegal(p2));
} }
@Test @Test
public void sourceNotOwned_returnsFalse() { public void sourceNotOwned_returnsFalse() {
// current player = PLAYER1 -> color must be YELLOW //Le joueur courant n'est pas rouge
grid[2][2] = new Tower(1, Color.RED); // not owned AvalamPly p = new AvalamPly(Player.PLAYER1, 5, 4, 6, 4);
grid[2][3] = new Tower(1, Color.YELLOW);
AvalamPly p = new AvalamPly(Player.PLAYER1, 2, 2, 2, 3);
assertFalse(board.isLegal(p)); assertFalse(board.isLegal(p));
} }
@Test @Test
public void notAdjacent_returnsFalse() { public void notAdjacent_returnsFalse() {
grid[0][0] = new Tower(1, Color.YELLOW); AvalamPly p = new AvalamPly(Player.PLAYER1, 4, 2, 6, 2);
grid[0][2] = new Tower(1, Color.RED);
AvalamPly p = new AvalamPly(Player.PLAYER1, 0, 0, 0, 2);
assertFalse(board.isLegal(p)); assertFalse(board.isLegal(p));
} }
@Test @Test
public void sameColor_returnsFalse() { public void sameColor_returnsFalse() {
grid[6][6] = new Tower(1, Color.YELLOW); //La couleur des tours est identique
grid[6][7] = new Tower(1, Color.YELLOW); // same color as source AvalamPly p = new AvalamPly(Player.PLAYER1, 4, 2, 5, 3);
AvalamPly p = new AvalamPly(Player.PLAYER1, 6, 6, 6, 7);
assertFalse(board.isLegal(p)); assertFalse(board.isLegal(p));
} }
@Test @Test
public void tooTallAfterMerge_returnsFalse() { public void tooTallAfterMerge_returnsFalse() {
grid[1][1] = new Tower(3, Color.YELLOW); //Hauteur maximale dépassé : 3+3 = 6 > MAX_HEIGHT (5)
grid[1][2] = new Tower(3, Color.RED); // 3+3 = 6 > MAX_HEIGHT (5) AvalamPly p = new AvalamPly(Player.PLAYER1, 5, 3, 6, 2);
AvalamPly p = new AvalamPly(Player.PLAYER1, 1, 1, 1, 2);
assertFalse(board.isLegal(p)); assertFalse(board.isLegal(p));
} }
@Test @Test
public void validMove_returnsTrue() { public void validMove_returnsTrue() {
grid[4][4] = new Tower(2, Color.YELLOW); // owned by PLAYER1 AvalamPly p = new AvalamPly(Player.PLAYER1, 5, 3, 4, 3); //Hauteur limite à 5
grid[4][5] = new Tower(2, Color.RED); // opposite color
AvalamPly p = new AvalamPly(Player.PLAYER1, 4, 4, 4, 5);
assertTrue(board.isLegal(p)); assertTrue(board.isLegal(p));
} }
@Test @Test //À vérifier
public void currentPlayerMismatchInPlyDoesNotAffectOwnershipCheck() { public void currentPlayerMismatchInPlyDoesNotAffectOwnershipCheck() {
// Even if AvalamPly is constructed with a player value, isLegal uses board.getCurrentPlayer() //Si le coup est construit avec le mauvais joueur
grid[7][7] = new Tower(1, Color.YELLOW); // owned by PLAYER1 (board default) AvalamPly p = new AvalamPly(Player.PLAYER2, 4, 2, 4, 3);
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)); assertFalse(board.isLegal(p));
} }
} }