diff --git a/MiniMax.java b/MiniMax.java new file mode 100644 index 0000000..68d815c --- /dev/null +++ b/MiniMax.java @@ -0,0 +1,81 @@ + +public class MiniMax { + + /* + Variable donnant le nombre d'allumettes au départ du jeu (remplacée par un argument en ligne de commande) + */ + public static int depart = 5000; + + private static int[] J1; + private static int[] J2; + + private static int compteur; + + public static void main(String[] args) { + compteur = 0; + int n = depart; + //int n = Integer.parseInt(args[0]); + J1 = new int[n+1]; + J2 = new int[n+1]; + System.out.println(Nim(n)); + System.out.println("J1 : "); + for (int nb: J1) { + System.out.print(nb+" ; "); + } + System.out.println(); + System.out.println("J2 : "); + for (int nb: J2) { + System.out.print(nb+" ; "); + } + System.out.println(); + System.out.println("Compteur : "+compteur); + } + + public static int Nim(int n){ + return exploreMax(n); + } + + /* + Vérifie les issues des coups jouables par le J1 et renvoie 1 si le J1 a une opportunité de gagner a coup sur + */ + public static int exploreMax(int allumette) { + compteur++; + if (J1[allumette] != 0){ + return J1[allumette]; + } + int n = allumette; + for (int i=1;allumette>1&&i<3;i++){ + allumette--; + int v=exploreMin(allumette); + if (v == 1){ + J1[n]=1; + return 1; + } + } + J1[n] = -1; + return -1; + } + + + /* + Vérifie les issues possibles des coups du J2 et renvoie -1 si le J2 a une opportunité de gagner a coup sur + */ + public static int exploreMin(int allumette){ + compteur++; + if (J2[allumette] != 0){ + return J2[allumette]; + } + int n = allumette; + for (int i=0;allumette>1&&i<3;i++){ + allumette--; + int v=exploreMax(allumette); + if (v == -1){ + J2[n]=-1; + return v; + } + } + J2[n] = 1; + return 1; + } + +} \ No newline at end of file diff --git a/README.md b/README.md index aa095bc..29c820e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,14 @@ Question 1 fait *(voir nim.java)* Le joueur1 va faire un explore max de ces choix possible et lance exploreMin sur ces choix et ensuite exploreMax sur sont choix etc jusqua que l'un des joueur doit choisir 1 ce qui garantie la victoire/la perte de cette branche. Dans exploreMax, si il y a une possibilité de perdre dans une branche elle vaudra -1 si elle est obligatoirement victorieuse elle vaudra 1 et inversement pour exploreMin. -exploreMin represente le meilleur choix du joueur2 (qui est le pire choix pour joueur1 d'ou explore**MIN**). +exploreMin represente le meilleur choix du joueur2 (qui est le pire choix pour joueur1 d'ou explore**MIN**). Question 2 pas fait -Stocker tous les états possibles. \ No newline at end of file +Stocker tous les états possibles. + +### 17/09/2024 +Optimisation du *nim.java*
+au lieu de faire les coup NBallumette-1, NBallumette-2 et NBallumette-3 le code execute les coups NBallumette-3, NBallumette-2 et NBallumette-1 dans cette ordre maintenant. + +Optimisation 2 +Stockes les different resultats a l'instar du carnet dans des array de int si le nombre d'allumette en particulier est perdant. Au prochaine executions d'exploreMax ou exploreMin si le resultat a deja été calculer il ne sera pas calculer a nouveau. \ No newline at end of file diff --git a/nim.java b/nim.java deleted file mode 100644 index b084cda..0000000 --- a/nim.java +++ /dev/null @@ -1,38 +0,0 @@ -public class nim { - public static void main(String[] args) { - System.out.println(exploreMax(5)); - } - - /** - * Determine si le joueur gagne ou perd grace a exploreMin. - * @param allumette le nombre d'allumette au tour du joueur - * @return -1 si perdant ou 1 si gagnant - */ - public static int exploreMax(int allumette) { - for (int i=0;allumette>1&&i<3;i++){ //si il y a plus d'une allumette - allumette--; - int v=exploreMin(allumette); - if (v==1){ - return v; - } - } - return -1; - } - - /** - * Determine si le joueur gagne ou perd grace a exploreMax. - * @param allumette le nombre d'allumette au tour du joueur - * @return -1 si gagnant ou 1 si perdant - */ - public static int exploreMin(int allumette){ - for (int i=0;allumette>1&&i<3;i++){ - allumette--; - int v=exploreMax(allumette); - if (v==-1){ - return v; - } - } - return 1; - } - -} \ No newline at end of file diff --git a/testraté/AbreNim.class b/testraté/AbreNim.class new file mode 100644 index 0000000..5fd7835 Binary files /dev/null and b/testraté/AbreNim.class differ diff --git a/testraté/AbreNim.java b/testraté/AbreNim.java new file mode 100644 index 0000000..c8ebbb5 --- /dev/null +++ b/testraté/AbreNim.java @@ -0,0 +1,13 @@ +public class AbreNim { + + private Noeud root; + + public AbreNim(int valeur) { + this.root = new Noeud(valeur); + } + + public Noeud getRoot() { + return root; + } + +} diff --git a/testraté/Etat.java b/testraté/Etat.java new file mode 100644 index 0000000..d29d93a --- /dev/null +++ b/testraté/Etat.java @@ -0,0 +1,17 @@ +public class Etat { + private int nb_alumettes; + private int statut; + + public Etat(int nb,int statut){ + this.nb_alumettes = nb; + this.statut = statut; + } + + public int getNb_alumettes() { + return nb_alumettes; + } + + public int getStatut() { + return statut; + } +} \ No newline at end of file diff --git a/testraté/Noeud.class b/testraté/Noeud.class new file mode 100644 index 0000000..59507a7 Binary files /dev/null and b/testraté/Noeud.class differ diff --git a/testraté/Noeud.java b/testraté/Noeud.java new file mode 100644 index 0000000..b4978aa --- /dev/null +++ b/testraté/Noeud.java @@ -0,0 +1,22 @@ +public class Noeud { + private Integer valeur; + public Noeud[] child = new Noeud[3]; + private int Etat; + + public Noeud(Integer etiquette) { + this.valeur = etiquette; + } + + public int getValeur() + { + return valeur; + } + + public int getEtat(){ + return Etat; + } + + public void setEtat(int newEtat){ + this.Etat = newEtat; + } +} diff --git a/testraté/nim.java b/testraté/nim.java new file mode 100644 index 0000000..886309b --- /dev/null +++ b/testraté/nim.java @@ -0,0 +1,82 @@ +import java.util.ArrayList; +import java.util.List; +import AbreNim; +import Noeud; + +public class nim { + + + public static void main(String[] args) { + AbreNim AN = AbreNim(5); + System.out.println(exploreMax(AN.getRoot())); + } + + /** + * Determine si le joueur gagne ou perd grace a exploreMin. + * @param allumette le nombre d'allumette au tour du joueur + * @return -1 si perdant ou 1 si gagnant + */ + public static boolean exploreMax(Noeud root) { + allumette = root.getValeur(); + allumette -= 3; + for(int i=0;allumette>1&&i<3;i++) { + root.child[i] = new Noeud(allumette); + if (checkEtat(root.child[i])==1) { + return true; + } + allumette++; + } + boolean childtest; + for (int i = 2; i >=0; i--) { + if (root.child[i].getEtat()==0) { + childtest = exploreMin(root.child[i]); + if (childtest) { + return true; + } + } + } + } + + + + /** + * Determine si le joueur gagne ou perd grace a exploreMax. + * @param allumette le nombre d'allumette au tour du joueur + * @return -1 si gagnant ou 1 si perdant + */ + public static boolean exploreMin(Noeud root){ + allumette = root.getValeur(); + allumette -= 3; + for(int i=0;allumette>1&&i<3;i++) { + root.child[i] = new Noeud(allumette); + if (checkEtat(root.child[i])==-1) { + return true; + } + allumette++; + } + boolean childtest = false; + for (int i = 2; i >=0; i--) { + if (root.child[i].getEtat()==0) { + childtest = exploreMax(root.child[i]); + if (childtest) { + return true; + } + } + } + } + + public static int checkEtat(Noeud node){ + if(node.getValeur()<1){ + node.setEtat(-1); + return -1; + } + else if (node.getValeur()==1) { + node.setEtat(1); + return 1; + } + node.setEtat(0); + return 0; + } + + +} \ No newline at end of file