ajout TP3

This commit is contained in:
James Boutaric
2025-10-09 10:20:53 +02:00
parent 84f5b7d973
commit b9c926f493
60 changed files with 1425 additions and 304 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -1,95 +0,0 @@
# 📘 README Minimax pour le jeu de Nim
## 🎯 Objectif
Ce TP a pour but dimplémenter lalgorithme **Minimax** dans le jeu de **Nim** (variante à 1 tas où lon peut retirer 1, 2 ou 3 objets).
On développe plusieurs versions de lalgorithme pour comprendre ses optimisations possibles.
---
## 📂 Fichiers
Le projet contient **4 fichiers Java**, correspondant chacun à une variante de Minimax :
1. **`MinimaxSimple.java`**
- Version de base.
- Explore toutes les possibilités jusquà la fin de la partie.
- Pas doptimisation → explore parfois plus que nécessaire.
2. **`MinimaxEarlyStop.java`**
- Optimisation par **arrêt anticipé** .
- Si un coup gagnant (pour Max) ou perdant (pour Min) est trouvé, la recherche sarrête immédiatement.
- Même résultat que la version simple, mais plus rapide.
```bash
boutaric@MacBook-James TP1 % time java MinimaxSimple
Résultat pour n=8 → -1
java MinimaxSimple 0,03s user 0,03s system 49% cpu 0,136 total
```
```bash
boutaric@MacBook-James TP1 % time java MinimaxStop
Résultat pour n=71
java MinimaxStop 0,04s user 0,02s system 93% cpu 0,062 total
```
3. **`MinimaxProfondeur.java`**
- Variante avec **profondeur maximale fixée**.
- Quand la profondeur limite est atteinte, on utilise une **fonction dévaluation heuristique**.
- Heuristique utilisée : une position est perdante si `n % 4 == 0`, sinon gagnante.
4. **`MinimaxMemo.java`**
- Optimisation par **mémoïsation**.
- Utilise deux tableaux (`memoMax` et `memoMin`) pour stocker les résultats déjà calculés.
- Évite les recalculs et accélère lalgorithme pour des valeurs de `n` plus grandes.
---
## ▶️ Exécution
Compiler et lancer chaque fichier séparément :
```bash
javac MinimaxSimple.java
java MinimaxSimple
```
```bash
javac MinimaxEarlyStop.java
java MinimaxEarlyStop
```
```bash
javac MinimaxProfondeur.java
java MinimaxProfondeur
```
```bash
javac MinimaxMemo.java
java MinimaxMemo
```
Chaque programme affiche le résultat pour une valeur donnée de `n` (taille initiale du tas).
- `+1` → Position gagnante pour Max (le joueur qui commence).
- `-1` → Position perdante pour Max.
---
## 📊 Exemple de résultats
Pour les premières positions de Nim (1 tas) :
| n | Résultat | Commentaire |
|----|----------|-------------|
| 1 | +1 | Max peut tout prendre et gagne |
| 2 | +1 | Max peut tout prendre et gagne |
| 3 | +1 | Max peut tout prendre et gagne |
| 4 | -1 | Position perdante (Min gagne) |
| 5 | +1 | Max enlève 1 → reste 4 (perdant pour Min) |
| 6 | +1 | Max enlève 2 → reste 4 |
| 7 | +1 | Max enlève 3 → reste 4 |
| 8 | -1 | Position perdante |
| ...| ... | ... |
---
## 🧠 Conclusion
- Le **Minimax simple** permet de comprendre la logique de base.
- Le **Minimax stop** améliore la performance sans changer le résultat.
- La **profondeur fixe + heuristique** est utile si larbre est trop grand.
- La **mémoïsation** accélère énormément le calcul pour des valeurs de `n` élevées.

Binary file not shown.

View File

@@ -0,0 +1,42 @@
public class MIniMax_versionprofondeur {
private static int ExploreMax(int nbr_allumettes, int profondeur){
if (nbr_allumettes <= 0){
return 1;
}
if (profondeur == 0){
return 0;
}
int meilleurres = -2;
for (int coup = 1; coup <= 3; coup++){
int res = ExploreMin(nbr_allumettes - coup, profondeur - coup);
if (res > meilleurres){
meilleurres = res;
}
}
return meilleurres;
}
private static int ExploreMin(int nbr_allumettes, int profondeur){
if (nbr_allumettes <= 0){
return -1;
}
if (profondeur == 0){
return 0;
}
int pire = 2;
for (int coup = 1; coup <= 3; coup++){
int res = ExploreMax(nbr_allumettes - coup, profondeur - coup);
if (res < pire){
pire = res;
}
}
return pire;
}
public static void main(String[] args) {
int nbr_allumettes = 5;
int profondeur = 6;
System.out.println(ExploreMax(nbr_allumettes, profondeur));
}
}

Binary file not shown.

View File

@@ -0,0 +1,35 @@
public class MiniMax_versionBase {
private static int ExploreMax(int nbr_allumettes){
if (nbr_allumettes <= 0){
return 1;
}
int meilleurres = -2;
for (int coup = 1; coup <= 3; coup++){
int res = ExploreMin(nbr_allumettes - coup);
if (res > meilleurres){
meilleurres = res;
}
}
return meilleurres;
}
private static int ExploreMin(int nbr_allumettes){
if (nbr_allumettes <= 0){
return -1;
}
int pire = 2;
for (int coup = 1; coup <= 3; coup++){
int res = ExploreMax(nbr_allumettes - coup);
if (res < pire){
pire = res;
}
}
return pire;
}
public static void main(String[] args) {
int nbr_allumettes = 5;
System.out.println(ExploreMax(nbr_allumettes));
}
}

Binary file not shown.

View File

@@ -0,0 +1,59 @@
import java.util.ArrayList;
public class MiniMax_versionMemoisation{
private static ArrayList<Integer> max = new ArrayList<Integer>();
private static ArrayList<Integer> min = new ArrayList<Integer>();
private static int Allumete;
public MiniMax_versionMemoisation(int n){
Allumete = n;
for(int i=0;i<n;i++){
max.add(-2);
min.add(-2);
}
}
public static int explorMax(int nbAllumete){
if (nbAllumete <=0){
return +1;
}
if (max.get(nbAllumete)!=-2){
return max.get(nbAllumete);
}
int meilleurRes = -2;
for (int coup =1;coup <=3;coup ++){
int res = explorMin(nbAllumete-coup);
if (meilleurRes < res){
meilleurRes =res;
}
}
max.set(nbAllumete,meilleurRes);
return meilleurRes;
}
public static int explorMin(int nbAllumete){
if (nbAllumete <=0){
return -1;
}
if (min.get(nbAllumete)!=-2){
return min.get(nbAllumete);
}
int mepireRes = 2;
for (int coup =1;coup <=3;coup ++){
int res = explorMax(nbAllumete-coup);
if ( res < mepireRes){
mepireRes = res;
}
}
min.set(nbAllumete,mepireRes);
return mepireRes;
}
public static void main(String[]arg){
MiniMax_versionMemoisation newCLass = new MiniMax_versionMemoisation(1904);
System.out.println(explorMax(1903));
}
}

Binary file not shown.

View File

@@ -0,0 +1,41 @@
public class MiniMax_version_AlphaBeta {
private static int ExploreMax(int nbr_allumettes, int alpha, int beta){
if (nbr_allumettes <= 0){
return 1;
}
int localAlpha = alpha;
for (int coup = 1; coup <= 3; coup++){
int res = ExploreMin(nbr_allumettes - coup, localAlpha, beta);
if (res > localAlpha){
localAlpha = res;
if (localAlpha >= beta){
return localAlpha;
}
}
}
return localAlpha;
}
private static int ExploreMin(int nbr_allumettes, int alpha, int beta){
if (nbr_allumettes <= 0){
return -1;
}
int localBeta = beta;
for (int coup = 1; coup <= 3; coup++){
int res = ExploreMax(nbr_allumettes - coup, alpha, localBeta);
if (res < localBeta){
localBeta = res;
if (localBeta <= alpha){
return localBeta;
}
}
}
return localBeta;
}
public static void main(String[] args) {
int nbr_allumettes = 5;
System.out.println(ExploreMax(nbr_allumettes, Integer.MIN_VALUE, Integer.MAX_VALUE));
}
}

Binary file not shown.

View File

@@ -0,0 +1,41 @@
public class MiniMax_versionarret {
private static int ExploreMax(int nbr_allumettes){
if (nbr_allumettes <= 0){
return 1;
}
int meilleurres = -2;
for (int coup = 1; coup <= 3; coup++){
int res = ExploreMin(nbr_allumettes - coup);
if (res > meilleurres){
meilleurres = res;
if (meilleurres == 1){
break;
}
}
}
return meilleurres;
}
private static int ExploreMin(int nbr_allumettes){
if (nbr_allumettes <= 0){
return -1;
}
int pire = 2;
for (int coup = 1; coup <= 3; coup++){
int res = ExploreMax(nbr_allumettes - coup);
if (res < pire){
pire = res;
if (pire == -1){
break;
}
}
}
return pire;
}
public static void main(String[] args) {
int nbr_allumettes = 4;
System.out.println(ExploreMax(nbr_allumettes));
}
}

97
TP1&TP2/Readme.md Normal file
View File

@@ -0,0 +1,97 @@
Ce fichier repertorie et explique les code qui se trouve dans ce fichier.
## MiniMax_versionBase
Ce code est la version de base vu en cours du jeu de Nim.
Il fonctionne et donne bien -1 en resultat.
# Tableau d'états visité
| n (allumettes) | Nombre de nœuds explorés |
|----------------|--------------------------|
| 5 | 46 |
| 7 | 157 |
| 13 | 6 094 |
| 19 | 235 957 |
| 31 | 353 693 521 |
## MiniMax_versionprofondeur
Ce code est une version optimisé de la version vu en cours du jeu de Nim.
Celui-ci a un autre paramètre qui est profoncdeur qui limite les calcul et donne une approximation.
Il fonctionne et donne bien 0 en resultat si la profonceur est inférieur à 6 et si elle est de 6 ou plus elle donne bien -1 car 6 est la profondeur maximal de l'abre du jeu de Nim.
# Tableau d'états visité
| Nombre dallumettes | Profondeur max | Nombre de nœuds (états) |
|---------------------|----------------|-------------------------|
| 5 | 6 | 46 |
| 7 | 8 | 157 |
| 13 | 14 | 6 094 |
| 19 | 20 | 235 957 |
| 31 | 32 | 353 693 521 |
## MiniMax_versionarret
Ce code est une version optimisé de la version vu en cours du jeu de Nim.
Celui-ci a une autre condition d'arret qui limite les calcul qui est donné par un chemin où il y a une victiore ou une défaite.
Il fonctionne et donne bien -1 en resultat si le nombre d'allumettes est de 5 et si elle est de 4, elle donne bien 1.
# Tableau d'états visité
| Nombre dallumettes | Nœuds visités |
|---------------------:|-------------:|
| 5 | 36 |
| 7 | 74 |
| 13 | 1 828 |
| 19 | 25 610 |
| 31 | 8 784 458 |
## MiniMax_versionMemoisation
Ce code est une version optimisé de la version vu en cours du jeu de Nim.
Celui-ci garde en mémoire avec un tableau pour le min et le max pour éviter de recalculer des sous-arbres déjà vu précédemment.
Il fonctionne avec les tests effectué.
# Tableau d'états visité
| Nombre dallumettes | Nœuds distincts (états) visités |
|---------------------:|-------------------------------:|
| 5 | 25 |
| 7 | 37 |
| 13 | 73 |
| 19 | 109 |
| 31 | 181 |
## MiniMax_version_AlphaBeta
Ce code est une version optimisé de la version vu en cours du jeu de Nim.
Celui-ci permet de coupé des partie de l'arbre de jeux, donc de visité moins de noeuds.
Il fonctionne avec les tests effectué.
# Tableau d'états visité
| Nombre dallumettes | Nœuds visités |
|--------------------:|--------------:|
| 5 | 41 |
| 7 | 107 |
| 13 | 2 244 |
| 19 | 31 898 |
| 31 | 9 523 124 |
## Différence de noeud visité entre MiniMax_version_AlphaBeta et MiniMax_versionBase
La différence entre le nombre de noeuds visité car alpha_beta ne regarde pas tous les sous-arbres, contrairement à la version de base, cela se voit surtout avec une grande longueur de l'arbre de jeux.
## Nombre d'états visités dans chaque version
| Version | Paramètres initiaux | États explorés |
|--------------------------------|-----------------------------------|----------------|
| MiniMax_versionBase | `nbr_allumettes = 5` | 46 |
| MiniMax_versionarret | `nbr_allumettes = 5` | 36 |
| MiniMax_versionprofondeur | `nbr_allumettes = 5, profondeur=6`| 46 |
| MiniMax_versionMemoisation | `nbr_allumettes = 5` | 25 |
| MiniMax_version_AlphaBeta | `nbr_allumettes = 5` | 41 |

View File

@@ -0,0 +1,47 @@
public class MIniMax_versionprofondeur_compteur {
public static int compteur_noeud = 0;
private static int ExploreMax(int nbr_allumettes, int profondeur){
compteur_noeud++;
if (nbr_allumettes <= 0){
return 1;
}
if (profondeur == 0){
return 0;
}
int meilleurres = -2;
for (int coup = 1; coup <= 3; coup++){
int res = ExploreMin(nbr_allumettes - coup, profondeur - coup);
if (res > meilleurres){
meilleurres = res;
}
}
return meilleurres;
}
private static int ExploreMin(int nbr_allumettes, int profondeur){
compteur_noeud++;
if (nbr_allumettes <= 0){
return -1;
}
if (profondeur == 0){
return 0;
}
int pire = 2;
for (int coup = 1; coup <= 3; coup++){
int res = ExploreMax(nbr_allumettes - coup, profondeur - coup);
if (res < pire){
pire = res;
}
}
return pire;
}
public static void main(String[] args) {
int nbr_allumettes = 5;
int profondeur = 6;
System.out.println(ExploreMax(nbr_allumettes, profondeur));
System.out.println(compteur_noeud);
}
}

Binary file not shown.

View File

@@ -0,0 +1,40 @@
public class MiniMax_versionBase_compteur {
public static int compteur_noeud = 0;
private static int ExploreMax(int nbr_allumettes){
compteur_noeud++;
if (nbr_allumettes <= 0){
return 1;
}
int meilleurres = -2;
for (int coup = 1; coup <= 3; coup++){
int res = ExploreMin(nbr_allumettes - coup);
if (res > meilleurres){
meilleurres = res;
}
}
return meilleurres;
}
private static int ExploreMin(int nbr_allumettes){
compteur_noeud++;
if (nbr_allumettes <= 0){
return -1;
}
int pire = 2;
for (int coup = 1; coup <= 3; coup++){
int res = ExploreMax(nbr_allumettes - coup);
if (res < pire){
pire = res;
}
}
return pire;
}
public static void main(String[] args) {
int nbr_allumettes = 19;
System.out.println(ExploreMax(nbr_allumettes));
System.out.println(compteur_noeud);
}
}

View File

@@ -0,0 +1,63 @@
import java.util.ArrayList;
public class MiniMax_versionMemoisation_compteur{
private static ArrayList<Integer> max = new ArrayList<Integer>();
private static ArrayList<Integer> min = new ArrayList<Integer>();
private static int Allumete;
public static int compteur_noeud = 0;
public MiniMax_versionMemoisation_compteur(int n){
Allumete = n;
for(int i=0;i<n;i++){
max.add(-2);
min.add(-2);
}
}
public static int explorMax(int nbAllumete){
compteur_noeud++;
if (nbAllumete <=0){
return +1;
}
if (max.get(nbAllumete)!=-2){
return max.get(nbAllumete);
}
int meilleurRes = -2;
for (int coup =1;coup <=3;coup ++){
int res = explorMin(nbAllumete-coup);
if (meilleurRes < res){
meilleurRes =res;
}
}
max.set(nbAllumete,meilleurRes);
return meilleurRes;
}
public static int explorMin(int nbAllumete){
compteur_noeud++;
if (nbAllumete <=0){
return -1;
}
if (min.get(nbAllumete)!=-2){
return min.get(nbAllumete);
}
int mepireRes = 2;
for (int coup =1;coup <=3;coup ++){
int res = explorMax(nbAllumete-coup);
if ( res < mepireRes){
mepireRes = res;
}
}
min.set(nbAllumete,mepireRes);
return mepireRes;
}
public static void main(String[]arg){
MiniMax_versionMemoisation_compteur newCLass = new MiniMax_versionMemoisation_compteur(32);
System.out.println(explorMax(31));
System.out.println(compteur_noeud);
}
}

View File

@@ -0,0 +1,46 @@
public class MiniMax_version_AlphaBeta_compteur {
public static int compteur_noeud = 0;
private static int ExploreMax(int nbr_allumettes, int alpha, int beta){
compteur_noeud++;
if (nbr_allumettes <= 0){
return 1;
}
int localAlpha = alpha;
for (int coup = 1; coup <= 3; coup++){
int res = ExploreMin(nbr_allumettes - coup, localAlpha, beta);
if (res > localAlpha){
localAlpha = res;
if (localAlpha >= beta){
return localAlpha;
}
}
}
return localAlpha;
}
private static int ExploreMin(int nbr_allumettes, int alpha, int beta){
compteur_noeud++;
if (nbr_allumettes <= 0){
return -1;
}
int localBeta = beta;
for (int coup = 1; coup <= 3; coup++){
int res = ExploreMax(nbr_allumettes - coup, alpha, localBeta);
if (res < localBeta){
localBeta = res;
if (localBeta <= alpha){
return localBeta;
}
}
}
return localBeta;
}
public static void main(String[] args) {
int nbr_allumettes = 31;
System.out.println(ExploreMax(nbr_allumettes, Integer.MIN_VALUE, Integer.MAX_VALUE));
System.out.println(compteur_noeud);
}
}

Binary file not shown.

View File

@@ -0,0 +1,46 @@
public class MiniMax_versionarret_compteur {
public static int compteur_noeud = 0;
private static int ExploreMax(int nbr_allumettes){
compteur_noeud++;
if (nbr_allumettes <= 0){
return 1;
}
int meilleurres = -2;
for (int coup = 1; coup <= 3; coup++){
int res = ExploreMin(nbr_allumettes - coup);
if (res > meilleurres){
meilleurres = res;
if (meilleurres == 1){
break;
}
}
}
return meilleurres;
}
private static int ExploreMin(int nbr_allumettes){
compteur_noeud++;
if (nbr_allumettes <= 0){
return -1;
}
int pire = 2;
for (int coup = 1; coup <= 3; coup++){
int res = ExploreMax(nbr_allumettes - coup);
if (res < pire){
pire = res;
if (pire == -1){
break;
}
}
}
return pire;
}
public static void main(String[] args) {
int nbr_allumettes = 19;
System.out.println(ExploreMax(nbr_allumettes));
System.out.println(compteur_noeud);
}
}

View File

@@ -0,0 +1,50 @@
import java.util.ArrayList;
import java.util.Collections;
public class MiniMax_version_AlphaBeta_melange {
private static ArrayList<Integer> list = new ArrayList<Integer>();
private static int ExploreMax(int nbr_allumettes, int alpha, int beta){
if (nbr_allumettes <= 0){
return 1;
}
int localAlpha = alpha;
for (Integer coup : list){
int res = ExploreMin(nbr_allumettes - coup, localAlpha, beta);
if (res > localAlpha){
localAlpha = res;
if (localAlpha >= beta){
return localAlpha;
}
}
}
return localAlpha;
}
private static int ExploreMin(int nbr_allumettes, int alpha, int beta){
if (nbr_allumettes <= 0){
return -1;
}
int localBeta = beta;
for (Integer coup : list){
int res = ExploreMax(nbr_allumettes - coup, alpha, localBeta);
if (res < localBeta){
localBeta = res;
if (localBeta <= alpha){
return localBeta;
}
}
}
return localBeta;
}
public static void main(String[] args) {
list.add(1);
list.add(2);
list.add(3);
Collections.shuffle(list);
int nbr_allumettes = 5;
System.out.println(list);
System.out.println(ExploreMax(nbr_allumettes, Integer.MIN_VALUE, Integer.MAX_VALUE));
}
}

View File

@@ -0,0 +1,54 @@
import java.util.ArrayList;
import java.util.Collections;
public class MiniMax_version_AlphaBeta_melange_compteur {
private static ArrayList<Integer> list = new ArrayList<Integer>();
public static int compteur_noeud = 0;
private static int ExploreMax(int nbr_allumettes, int alpha, int beta){
compteur_noeud++;
if (nbr_allumettes <= 0){
return 1;
}
int localAlpha = alpha;
for (Integer coup : list){
int res = ExploreMin(nbr_allumettes - coup, localAlpha, beta);
if (res > localAlpha){
localAlpha = res;
if (localAlpha >= beta){
return localAlpha;
}
}
}
return localAlpha;
}
private static int ExploreMin(int nbr_allumettes, int alpha, int beta){
compteur_noeud++;
if (nbr_allumettes <= 0){
return -1;
}
int localBeta = beta;
for (Integer coup : list){
int res = ExploreMax(nbr_allumettes - coup, alpha, localBeta);
if (res < localBeta){
localBeta = res;
if (localBeta <= alpha){
return localBeta;
}
}
}
return localBeta;
}
public static void main(String[] args) {
list.add(1);
list.add(2);
list.add(3);
Collections.shuffle(list);
int nbr_allumettes = 5;
System.out.println(list);
System.out.println(ExploreMax(nbr_allumettes, Integer.MIN_VALUE, Integer.MAX_VALUE));
System.out.println(compteur_noeud);
}
}

Binary file not shown.

View File

@@ -1,58 +0,0 @@
import java.util.*;
public class MinimaxAlphaBeta {
public static int compteur = 0; // nombre d'états visités
public static Random random = new Random();
public static int exploreMax(int n, int alpha, int beta) {
compteur++;
if (n <= 0) return -1;
int meilleur = Integer.MIN_VALUE;
// coups possibles
List<Integer> coups = Arrays.asList(1, 2, 3);
Collections.shuffle(coups, random); // ordre aléatoire
for (int c : coups) {
int res = exploreMin(n - c, alpha, beta);
meilleur = Math.max(meilleur, res);
alpha = Math.max(alpha, meilleur);
// coupure alpha-beta
if (alpha >= beta) break;
}
return meilleur;
}
public static int exploreMin(int n, int alpha, int beta) {
compteur++;
if (n <= 0) return +1;
int pire = Integer.MAX_VALUE;
// coups possibles
List<Integer> coups = Arrays.asList(1, 2, 3);
Collections.shuffle(coups, random); // ordre aléatoire
for (int c : coups) {
int res = exploreMax(n - c, alpha, beta);
pire = Math.min(pire, res);
beta = Math.min(beta, pire);
// coupure alpha-beta
if (alpha >= beta) break;
}
return pire;
}
public static void main(String[] args) {
int[] tests = {5, 7, 13, 19, 31};
for (int n : tests) {
compteur = 0;
int resultat = exploreMax(n, Integer.MIN_VALUE, Integer.MAX_VALUE);
System.out.println("n=" + n + "" + resultat + " | états visités=" + compteur);
}
}
}

Binary file not shown.

View File

@@ -1,43 +0,0 @@
public class MinimaxMemo {
// Minimax avec mémo (on évite de recalculer les mêmes positions)
public static Integer[] memoMax;
public static Integer[] memoMin;
public static int exploreMax(int n) {
if (n <= 0) return -1;
if (memoMax[n] != null) return memoMax[n];
int meilleur = Integer.MIN_VALUE;
for (int coups = 1; coups <= 3; coups++) {
int res = exploreMin(n - coups);
meilleur = Math.max(meilleur, res);
}
memoMax[n] = meilleur;
return meilleur;
}
public static int exploreMin(int n) {
if (n <= 0) return +1;
if (memoMin[n] != null) return memoMin[n];
int pire = Integer.MAX_VALUE;
for (int coups = 1; coups <= 3; coups++) {
int res = exploreMax(n - coups);
pire = Math.min(pire, res);
}
memoMin[n] = pire;
return pire;
}
public static void main(String[] args) {
int n = 25; // taille du tas initial
memoMax = new Integer[n + 1];
memoMin = new Integer[n + 1];
int resultat = exploreMax(n);
System.out.println("Résultat pour n=" + n + "" + resultat);
}
}

Binary file not shown.

View File

@@ -1,41 +0,0 @@
public class MinimaxProfondeur {
// Minimax avec profondeur fixe
public static int PROFONDEUR_MAX = 4;
public static int exploreMax(int n, int profondeur) {
if (n <= 0) return -1;
if (profondeur == 0) return evaluer(n);
int meilleur = Integer.MIN_VALUE;
for (int coups = 1; coups <= 3; coups++) {
int res = exploreMin(n - coups, profondeur - 1);
meilleur = Math.max(meilleur, res);
}
return meilleur;
}
public static int exploreMin(int n, int profondeur) {
if (n <= 0) return +1;
if (profondeur == 0) return evaluer(n);
int pire = Integer.MAX_VALUE;
for (int coups = 1; coups <= 3; coups++) {
int res = exploreMax(n - coups, profondeur - 1);
pire = Math.min(pire, res);
}
return pire;
}
// Fonction hsimple : perdant si n % 4 == 0
public static int evaluer(int n) {
return (n % 4 == 0) ? -1 : +1;
}
public static void main(String[] args) {
int n = 8;
int profondeur = PROFONDEUR_MAX;
int resultat = exploreMax(n, profondeur);
System.out.println("Résultat (profondeur fixe) pour n=" + n + "" + resultat);
}
}

Binary file not shown.

View File

@@ -1,33 +0,0 @@
public class MinimaxSimple {
// Max = moi, Min = adversaire
// Retourne +1 si Max gagne, -1 si Max perd
public static int exploreMax(int n) {
if (n <= 0) return -1; // défaite pour Max
int meilleur = Integer.MIN_VALUE;
for (int coups = 1; coups <= 3; coups++) {
int res = exploreMin(n - coups);
meilleur = Math.max(meilleur, res);
}
return meilleur;
}
public static int exploreMin(int n) {
if (n <= 0) return +1; // victoire pour Max
int pire = Integer.MAX_VALUE;
for (int coups = 1; coups <= 3; coups++) {
int res = exploreMax(n - coups);
pire = Math.min(pire, res);
}
return pire;
}
public static void main(String[] args) {
int n = 8; // tas initial
int resultat = exploreMax(n);
System.out.println("Résultat pour n=" + n + "" + resultat);
}
}

Binary file not shown.

View File

@@ -1,34 +0,0 @@
public class MinimaxStop {
// Minimax avec détection de victoire immédiate
public static int exploreMax(int n) {
if (n <= 0) return -1;
int meilleur = Integer.MIN_VALUE;
for (int coups = 1; coups <= 3; coups++) {
int res = exploreMin(n - coups);
if (res == +1) return +1; // victoire immédiate
meilleur = Math.max(meilleur, res);
}
return meilleur;
}
public static int exploreMin(int n) {
if (n <= 0) return +1;
int pire = Integer.MAX_VALUE;
for (int coups = 1; coups <= 3; coups++) {
int res = exploreMax(n - coups);
if (res == -1) return -1; // défaite immédiate pour Max
pire = Math.min(pire, res);
}
return pire;
}
public static void main(String[] args) {
int n = 7;
int resultat = exploreMax(n);
System.out.println("Résultat pour n=" + n + "" + resultat);
}
}

Binary file not shown.

View File

@@ -0,0 +1,99 @@
package fr.iut_fbleau.GameAPI;
import java.util.Iterator;
import java.util.Deque;
/**
* An abstract class implementing the interface IBoard.
*
* used to implement some things to do with the update of the next player
* which is the same for all games and provides also a minimal
* implantation of the history mechanism.
*/
public abstract class AbstractBoard implements IBoard{
private Player currentPlayer ;
private Deque<AbstractPly> history;
private void setNextPlayer(){
if (this.currentPlayer==Player.PLAYER1){
this.currentPlayer= Player.PLAYER2;
}
else
this.currentPlayer= Player.PLAYER1;
}
// Beware not checking if move is legal.
// To be used in do(AbstractPly c)
private void addPlyToHistory(AbstractPly c){
this.history.addLast(c);
}
// Beware not checking if history is not empty
// To be used in undo()
private void removePlyFromHistory(){
this.history.removeLast();
}
/**
* @return the current player
*/
public Player getcurrentPlayer(){
return this.currentPlayer;
}
/**
* Returns the game status
*
* @return true iff the game is over
*/
public abstract boolean isGameOver();
/**
*
* @return the result (null if not over)
*/
public abstract Result getResult();
/**
* checker of legal moves from this position
*
* @throws NullPointerException if the game is over
* @return the iterator
*/
public abstract boolean isLegal(AbstractPly c);
/**
* constructor of Iterator over legal moves from this position
*
* @throws NullPointerException if the game is over
* @return the iterator
*/
public abstract Iterator<AbstractPly> iterator();
/**
* Plays a given move on the plateau.
* Should update history using
* @throws IllegalArgumentException if the move is always illegal (say from the wrong game)
* @throws IllegalStateException if the move is not legal in this position
*
* @param AbstractPly to be played
*
*/
public abstract void doPly(AbstractPly c);
/**
* Resets the plateau to the position before the last move.
*
* @throws IllegalStateException if nothing to undo in history
*
*/
public abstract void undoPly();
}

Binary file not shown.

View File

@@ -0,0 +1,26 @@
package fr.iut_fbleau.GameAPI;
import java.util.Iterator;
/**
* The abstract class for a game Player.
*/
public abstract class AbstractGamePlayer {
// not a band, but which type of player I am in the game (PLAYER1 or PLAYER2).
private Player iAm;
// Le joueur réel pourrait avoir besoin de connaître un constructeur de coup?
// pas pour l'instant.
/**
*
*
* @throws UnsupportedOperationException if the method is not yet implemented
*
* @throws IllegalStateException if the Situation is already in the bookmarks
*/
public abstract AbstractPly giveYourMove(IBoard p);
}

Binary file not shown.

View File

@@ -0,0 +1,5 @@
package fr.iut_fbleau.GameAPI;
public abstract class AbstractPly {
private Player joueur;
}

Binary file not shown.

View File

@@ -0,0 +1,69 @@
package fr.iut_fbleau.GameAPI;
import java.util.Iterator;
/**
* The interface Board.
*/
public interface IBoard {
/**
* @return the current player
*/
public Player getcurrentPlayer();
/**
* Returns the game status
*
* @return true iff the game is over
*/
public boolean isGameOver();
/**
*
* @return the result (null if not over)
*/
public Result getResult();
/**
* checker of legal moves from this position
*
* @throws NullPointerException if the game is over
* @return the iterator
*/
public boolean isLegal(AbstractPly c);
/**
* constructor of Iterator over legal moves from this position
*
* @throws NullPointerException if the game is over
* @return the iterator
*/
public Iterator<AbstractPly> iterator();
/**
* Plays a given move on the plateau.
* Should update history using
* @throws IllegalArgumentException if the move is always illegal (say from the wrong game)
* @throws IllegalStateException if the move is not legal in this position
*
* @param AbstractPly to be played
*
*/
public void doPly(AbstractPly c);
/**
* Resets the plateau to the position before the last move.
*
* @throws IllegalStateException if nothing to undo in history
*
*/
public void undoPly();
}

Binary file not shown.

View File

@@ -0,0 +1,6 @@
package fr.iut_fbleau.GameAPI;
public enum Player {
PLAYER1,
PLAYER2
}

Binary file not shown.

View File

@@ -0,0 +1,11 @@
package fr.iut_fbleau.GameAPI;
/**
* To output the result of a 2 player game that is symmetric.
* from the perspective of the player PLAYER1.
*/
public enum Result {
WIN,
DRAW,
LOSS;
}

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More