This commit is contained in:
SimonSayeBabu 2024-09-17 16:45:49 +02:00
parent 5de3f13ab5
commit 9862082bf2
9 changed files with 224 additions and 40 deletions

81
MiniMax.java Normal file
View File

@ -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;
}
}

View File

@ -2,7 +2,14 @@
Question 1 fait *(voir nim.java)* 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. 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 Question 2 pas fait
Stocker tous les états possibles. Stocker tous les états possibles.
### 17/09/2024
Optimisation du *nim.java* </br>
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.

View File

@ -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;
}
}

BIN
testraté/AbreNim.class Normal file

Binary file not shown.

13
testraté/AbreNim.java Normal file
View File

@ -0,0 +1,13 @@
public class AbreNim {
private Noeud root;
public AbreNim(int valeur) {
this.root = new Noeud(valeur);
}
public Noeud getRoot() {
return root;
}
}

17
testraté/Etat.java Normal file
View File

@ -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;
}
}

BIN
testraté/Noeud.class Normal file

Binary file not shown.

22
testraté/Noeud.java Normal file
View File

@ -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;
}
}

82
testraté/nim.java Normal file
View File

@ -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;
}
}