e
This commit is contained in:
parent
2230b9cd64
commit
2b114b3d51
3
.idea/.gitignore
vendored
Normal file
3
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
6
.idea/misc.xml
Normal file
6
.idea/misc.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="21" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/BUT3JeuR5.5.iml" filepath="$PROJECT_DIR$/BUT3JeuR5.5.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
11
BUT3JeuR5.5.iml
Normal file
11
BUT3JeuR5.5.iml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
BIN
MiniMax.class
Normal file
BIN
MiniMax.class
Normal file
Binary file not shown.
77
MiniMax.java
77
MiniMax.java
@ -1,52 +1,95 @@
|
|||||||
|
|
||||||
public class MiniMax {
|
public class MiniMax {
|
||||||
|
|
||||||
/*
|
|
||||||
Variable donnant le nombre d'allumettes au départ du jeu
|
|
||||||
*/
|
|
||||||
public static int depart = 5;
|
|
||||||
|
|
||||||
|
// J'aime bien les majuscules
|
||||||
|
public static boolean True = true;
|
||||||
|
public static boolean False = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Variable donnant le nombre d'allumettes au départ du jeu (remplacée par un argument en ligne de commande)
|
||||||
|
*/
|
||||||
|
public static int depart = 9099;
|
||||||
|
|
||||||
|
private static int[] J1;
|
||||||
|
private static int[] J2;
|
||||||
|
|
||||||
|
private static int compteur;
|
||||||
|
private static int limite;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.out.println(Nim(depart));
|
limite = depart;
|
||||||
|
compteur = 0;
|
||||||
|
//int n = depart;
|
||||||
|
J1 = new int[limite + 1];
|
||||||
|
J2 = new int[limite + 1];
|
||||||
|
int s = Nim(limite);
|
||||||
|
System.out.print(limite+" ");
|
||||||
|
if (s == 1){
|
||||||
|
System.out.print("Gagné");
|
||||||
|
} else {
|
||||||
|
System.out.print("Perdu");
|
||||||
|
}
|
||||||
|
System.out.println(" Compteur = "+compteur);
|
||||||
|
/*
|
||||||
|
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+" ; ");
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Fonction de démarrage du jeu, donner un nombre d'allumettes de démarrage
|
|
||||||
*/
|
|
||||||
public static int Nim(int n){
|
public static int Nim(int n){
|
||||||
return exploreMax(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
|
Vérifie les issues des coups jouables par le J1 et renvoie 1 si le J1 a une opportunité de gagner a coup sur
|
||||||
|
Vérifie si le coup a déjà été joué avant de continuer l'arbre, si il verifie l'arbre il ajoute au tableau
|
||||||
*/
|
*/
|
||||||
public static int exploreMax(int allumette) {
|
public static int exploreMax(int allumette) {
|
||||||
|
compteur++;
|
||||||
|
if (J1[allumette] != 0){
|
||||||
|
return J1[allumette];
|
||||||
|
}
|
||||||
|
int n = allumette;
|
||||||
|
int max = -1;
|
||||||
for (int i=0;allumette>1&&i<3;i++){
|
for (int i=0;allumette>1&&i<3;i++){
|
||||||
allumette--;
|
allumette--;
|
||||||
int v=exploreMin(allumette);
|
int v=exploreMin(allumette);
|
||||||
if (v==1){
|
if (v > max){
|
||||||
return v;
|
max = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return -1;
|
J1[n] = max;
|
||||||
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Vérifie les issues possibles des coups du J2 et renvoie -1 si le J2 a une opportunité de gagner a coup sur
|
Vérifie les issues possibles des coups du J2 et renvoie -1 si le J2 a une opportunité de gagner a coup sur
|
||||||
|
Vérifie si le coup a déjà été joué avant de continuer l'arbre, si il verifie l'arbre il ajoute au tableau
|
||||||
*/
|
*/
|
||||||
public static int exploreMin(int allumette){
|
public static int exploreMin(int allumette){
|
||||||
|
compteur++;
|
||||||
|
if (J2[allumette] != 0){
|
||||||
|
return J2[allumette];
|
||||||
|
}
|
||||||
|
int n = allumette;
|
||||||
|
int min = 1;
|
||||||
for (int i=0;allumette>1&&i<3;i++){
|
for (int i=0;allumette>1&&i<3;i++){
|
||||||
allumette--;
|
allumette--;
|
||||||
int v=exploreMax(allumette);
|
int v=exploreMax(allumette);
|
||||||
if (v==-1){
|
if (v < min){
|
||||||
return v;
|
min = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
J2[n] = min;
|
||||||
|
return min;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
BIN
MiniMaxOptiCarnet.class
Normal file
BIN
MiniMaxOptiCarnet.class
Normal file
Binary file not shown.
104
MiniMaxOptiCarnet.java
Normal file
104
MiniMaxOptiCarnet.java
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
|
||||||
|
public class MiniMaxOptiCarnet {
|
||||||
|
|
||||||
|
|
||||||
|
// J'aime bien les majuscules
|
||||||
|
public static boolean True = true;
|
||||||
|
public static boolean False = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Variable donnant le nombre d'allumettes au départ du jeu (remplacée par un argument en ligne de commande)
|
||||||
|
*/
|
||||||
|
public static int depart = 10000;
|
||||||
|
|
||||||
|
private static int[] J1;
|
||||||
|
private static int[] J2;
|
||||||
|
|
||||||
|
private static int compteur;
|
||||||
|
private static int limite;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
limite = 0;
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
limite++;
|
||||||
|
compteur = 0;
|
||||||
|
//int n = depart;
|
||||||
|
J1 = new int[limite + 1];
|
||||||
|
J2 = new int[limite + 1];
|
||||||
|
int s = Nim(limite);
|
||||||
|
System.out.print(limite+" ");
|
||||||
|
if (s == 1){
|
||||||
|
System.out.print("Gagné");
|
||||||
|
} else {
|
||||||
|
System.out.print("Perdu");
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(" Compteur = "+compteur);
|
||||||
|
|
||||||
|
/*
|
||||||
|
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+" ; ");
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
} catch (StackOverflowError e){
|
||||||
|
}
|
||||||
|
System.out.println(limite-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
Vérifie si le coup a déjà été joué avant de continuer l'arbre, si il verifie l'arbre il ajoute au tableau
|
||||||
|
*/
|
||||||
|
public static int exploreMax(int allumette) {
|
||||||
|
compteur++;
|
||||||
|
if (J1[allumette] != 0){
|
||||||
|
return J1[allumette];
|
||||||
|
}
|
||||||
|
int n = allumette;
|
||||||
|
int max = -1;
|
||||||
|
for (int i=0;allumette>1&&i<3;i++){
|
||||||
|
allumette--;
|
||||||
|
int v=exploreMin(allumette);
|
||||||
|
if (v > max){
|
||||||
|
max = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
J1[n] = max;
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Vérifie les issues possibles des coups du J2 et renvoie -1 si le J2 a une opportunité de gagner a coup sur
|
||||||
|
Vérifie si le coup a déjà été joué avant de continuer l'arbre, si il verifie l'arbre il ajoute au tableau
|
||||||
|
*/
|
||||||
|
public static int exploreMin(int allumette){
|
||||||
|
compteur++;
|
||||||
|
if (J2[allumette] != 0){
|
||||||
|
return J2[allumette];
|
||||||
|
}
|
||||||
|
int n = allumette;
|
||||||
|
int min = 1;
|
||||||
|
for (int i=0;allumette>1&&i<3;i++){
|
||||||
|
allumette--;
|
||||||
|
int v=exploreMax(allumette);
|
||||||
|
if (v < min){
|
||||||
|
min = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
J2[n] = min;
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
22
MiniMaxPetiteOpti.java
Normal file
22
MiniMaxPetiteOpti.java
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
public class MiniMaxPetiteOpti {
|
||||||
|
|
||||||
|
public static int depart = 5;
|
||||||
|
|
||||||
|
private static int compteur;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int n = depart;
|
||||||
|
compteur = 0;
|
||||||
|
int s = Nim(n);
|
||||||
|
if (s == 1){
|
||||||
|
System.out.print("Gagné");
|
||||||
|
} else {
|
||||||
|
System.out.print("Perdu");
|
||||||
|
}
|
||||||
|
System.out.println(" Compteur = "+compteur);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int Nim(int n){
|
||||||
|
return exploreMax(n);
|
||||||
|
}
|
||||||
|
}
|
12
README.md
12
README.md
@ -9,4 +9,14 @@ Utilisation de deux fonctions récursives pour dire si le premier joueur peut ga
|
|||||||
ExplorationMax -> Tour du joueur 1, vérifie si il a un coup permettant de gagner à coup sûr
|
ExplorationMax -> Tour du joueur 1, vérifie si il a un coup permettant de gagner à coup sûr
|
||||||
ExplorationMin -> Tour du joueur 2, vérifie si le joueur 2 perd à coup sûr
|
ExplorationMin -> Tour du joueur 2, vérifie si le joueur 2 perd à coup sûr
|
||||||
|
|
||||||
Optimisations faites : Si le joueur 1 possède un coup permettant de gagner à coup sûr, la fonction remontera directement pour finir la fonction.
|
Optimisations faites : Si le joueur 1 possède un coup permettant de gagner à coup sûr, la fonction remontera directement pour finir la fonction.
|
||||||
|
|
||||||
|
## Optimisation en utilisant le systeme de cahier (MiniMaxOptiCarnet.java)
|
||||||
|
|
||||||
|
Cette optimisation utilise le système de carnet demandé afin de vérifier qu'une seule fois chaque situation.
|
||||||
|
Ainsi, l'algorithme vérifie a chaque fois exactement n*6-17 noeuds, n étant le nombre d'allumettes au démarrage du jeu.
|
||||||
|
Le carnet existe sous la forme de deux tableaux d'entiers, un par joueur. Chaque joueur à n-1 situations car le Joueur 1 ne peut pas se retrouver avec n-1 allumette et le Joueur 2 ne peut pas avoir n allumettes
|
||||||
|
La limite du nombre d'allumettes est de 33736 (testé grace au bloc try/catch lançant en batch). Cependant lorsque le programme est lancé avec une valeur simple, la limite est beaucoup plus basse, étant à 9099 (sur ma machine).
|
||||||
|
Cette limite est causée par la limite de récursivité de Java, causant une StackOverflowError.
|
||||||
|
|
||||||
|
|
||||||
|
3
out/production/BUT3JeuR5.5/.idea/.gitignore
vendored
Normal file
3
out/production/BUT3JeuR5.5/.idea/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
6
out/production/BUT3JeuR5.5/.idea/misc.xml
Normal file
6
out/production/BUT3JeuR5.5/.idea/misc.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="21" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
8
out/production/BUT3JeuR5.5/.idea/modules.xml
Normal file
8
out/production/BUT3JeuR5.5/.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/BUT3JeuR5.5.iml" filepath="$PROJECT_DIR$/BUT3JeuR5.5.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
out/production/BUT3JeuR5.5/.idea/vcs.xml
Normal file
6
out/production/BUT3JeuR5.5/.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
11
out/production/BUT3JeuR5.5/BUT3JeuR5.5.iml
Normal file
11
out/production/BUT3JeuR5.5/BUT3JeuR5.5.iml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
BIN
out/production/BUT3JeuR5.5/MiniMax.class
Normal file
BIN
out/production/BUT3JeuR5.5/MiniMax.class
Normal file
Binary file not shown.
BIN
out/production/BUT3JeuR5.5/MiniMaxOptiCarnet.class
Normal file
BIN
out/production/BUT3JeuR5.5/MiniMaxOptiCarnet.class
Normal file
Binary file not shown.
21
out/production/BUT3JeuR5.5/README.md
Normal file
21
out/production/BUT3JeuR5.5/README.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# BUT3JeuR5.5
|
||||||
|
|
||||||
|
## Jeu de Nim : MiniMax
|
||||||
|
|
||||||
|
Utilisation de deux fonctions récursives pour dire si le premier joueur peut gagner à coup sûr au jeu de Nim
|
||||||
|
+1 = J1 peut Gagner à coup sur
|
||||||
|
-1 = J1 peut perdre à coup sur
|
||||||
|
|
||||||
|
ExplorationMax -> Tour du joueur 1, vérifie si il a un coup permettant de gagner à coup sûr
|
||||||
|
ExplorationMin -> Tour du joueur 2, vérifie si le joueur 2 perd à coup sûr
|
||||||
|
|
||||||
|
Optimisations faites : Si le joueur 1 possède un coup permettant de gagner à coup sûr, la fonction remontera directement pour finir la fonction.
|
||||||
|
|
||||||
|
## Optimisation en utilisant le systeme de cahier (MiniMaxOptiCarnet.java)
|
||||||
|
|
||||||
|
Cette optimisation utilise le système de carnet demandé afin de vérifier qu'une seule fois chaque situation.
|
||||||
|
Ainsi, l'algorithme vérifie a chaque fois exactement n*6-17 noeuds, n étant le nombre d'allumettes au démarrage du jeu.
|
||||||
|
Le carnet existe sous la forme de deux tableaux d'entiers, un par joueur. Chaque joueur à n-1 situations car le Joueur 1 ne peut pas se retrouver avec n-1 allumette et le Joueur 2 ne peut pas avoir n allumettes
|
||||||
|
La limite du nombre d'allumettes est de 33736 (testé grace au bloc try/catch lançant en batch). Cependant lorsque le programme est lancé avec une valeur simple, la limite est beaucoup plus basse,
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user