From 2b114b3d51eed921bed5849996033d9deff21858 Mon Sep 17 00:00:00 2001 From: Axel Pietrois Date: Fri, 20 Sep 2024 14:07:50 +0200 Subject: [PATCH] e --- .idea/.gitignore | 3 + .idea/misc.xml | 6 + .idea/modules.xml | 8 ++ .idea/vcs.xml | 6 + BUT3JeuR5.5.iml | 11 ++ MiniMax.class | Bin 0 -> 1911 bytes MiniMax.java | 77 ++++++++++--- MiniMaxOptiCarnet.class | Bin 0 -> 1942 bytes MiniMaxOptiCarnet.java | 104 ++++++++++++++++++ MiniMaxPetiteOpti.java | 22 ++++ README.md | 12 +- out/production/BUT3JeuR5.5/.idea/.gitignore | 3 + out/production/BUT3JeuR5.5/.idea/misc.xml | 6 + out/production/BUT3JeuR5.5/.idea/modules.xml | 8 ++ out/production/BUT3JeuR5.5/.idea/vcs.xml | 6 + out/production/BUT3JeuR5.5/BUT3JeuR5.5.iml | 11 ++ out/production/BUT3JeuR5.5/MiniMax.class | Bin 0 -> 2066 bytes .../BUT3JeuR5.5/MiniMaxOptiCarnet.class | Bin 0 -> 2209 bytes out/production/BUT3JeuR5.5/README.md | 21 ++++ 19 files changed, 286 insertions(+), 18 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 BUT3JeuR5.5.iml create mode 100644 MiniMax.class create mode 100644 MiniMaxOptiCarnet.class create mode 100644 MiniMaxOptiCarnet.java create mode 100644 MiniMaxPetiteOpti.java create mode 100644 out/production/BUT3JeuR5.5/.idea/.gitignore create mode 100644 out/production/BUT3JeuR5.5/.idea/misc.xml create mode 100644 out/production/BUT3JeuR5.5/.idea/modules.xml create mode 100644 out/production/BUT3JeuR5.5/.idea/vcs.xml create mode 100644 out/production/BUT3JeuR5.5/BUT3JeuR5.5.iml create mode 100644 out/production/BUT3JeuR5.5/MiniMax.class create mode 100644 out/production/BUT3JeuR5.5/MiniMaxOptiCarnet.class create mode 100644 out/production/BUT3JeuR5.5/README.md diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..20f033c --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..a5c2172 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/BUT3JeuR5.5.iml b/BUT3JeuR5.5.iml new file mode 100644 index 0000000..b107a2d --- /dev/null +++ b/BUT3JeuR5.5.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/MiniMax.class b/MiniMax.class new file mode 100644 index 0000000000000000000000000000000000000000..2e46e50225fbf9f752f0c673438fb5c3b59ca2f1 GIT binary patch literal 1911 zcmaJ>TT>fl7=AvoWRrA(Ksl9D140Y6f$K~5E<1zO9JZ0SO>o7rrzc-()ls-1?@GbOnL~re(TA0)h69r7%JWtB7d008K!h;eRvwQ=-yl z#&itG(KxPq%H+BJ0Gn!v?#{0kIkXWxVD&%KLrtM=5w`AHP#?x%tb_|w8ng=wN_@vpiWF0=ya2t1cebLFwimgcF zh=x&VEKca@oFOd<4db$g!IY8J9fqik*eT-6rcKM3&1cpPXHj2I)1qW_(-Np|Up+4e z0wrD;GkVs?hX#^qzo{Y%cHT)E2~+yf{C4V;31F#*ZQIScj-H({+$VM_R~E!)5iDR) z#pkl7O9HLOxiYP7d&}r56t7U`gr0P5XGh@clhyHo1*a3bl}a1A)@j?`%4g$e12|zh zb#ZYgYn%f=nS#Oy#ZR`D?_xwxrx!Rc@euBF7DOzB73L{6;*U#gFeaFfNy{>vk+h!6 z895aX1=`MpdtMYO9tkx4Ka_PXgp6j^x`<<lTnd^h!37#4$1!eKIpCMjR5t#Hr;6q_d;Zq;_7XseXUj_D|?m>;FzJpGwtno}+ ziKqV(*+=w9tEBb@H3NI7r*=U4c#XDt<$ILURPjC!ySO0L52$*mk^^)})Q7u=-|j-0 zE?iYouW|DgnJCyq2EAk=c_vWKZxyXI46YWH+(@;kM+^7Rbq3dqCMM@HaWUMbbs25g zKsSB#(n}94+`tZQVwzr}2r7SLTBvW?%qjtlp8L&@{wPs(Z_xje@RNz^CzLboLw{nT ziisfg5}6z(CR*3|4Z@y$SvOELs0`I9FL0$X_#Dm8a7dr=KBY=&cma)|dS$Lk8GIHH zyN7?sW5Zm7e6bMnEtFEf%|5t8%ER2qqYQbBuP3-|#<~6`n7~N}HHA2fH$?j=W_g

uvaBOa5)>kGvDJ>t(1{Fm~dd#F53 zxeq0ze4mt;NqL2oACU4xzWW6!KO*HdQr1a%9sRTo!644q?K)Vp1zEq`Uo zK8DzU!{t|_`xra!;!?&V8(!hKgxDVera`804)c_y)b7&7J@31WRoWsvKOloOT>1xE CCx(&$ literal 0 HcmV?d00001 diff --git a/MiniMax.java b/MiniMax.java index 085aef6..267cf01 100644 --- a/MiniMax.java +++ b/MiniMax.java @@ -1,52 +1,95 @@ + 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) { - 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){ 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==1){ - return v; + if (v > max){ + 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 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==-1){ - return v; + if (v < min){ + min = v; } } - return 1; + J2[n] = min; + return min; } } \ No newline at end of file diff --git a/MiniMaxOptiCarnet.class b/MiniMaxOptiCarnet.class new file mode 100644 index 0000000000000000000000000000000000000000..16b3d37bcaf311cdd3db7e0f1e7d2e96d43ecba4 GIT binary patch literal 1942 zcmb7ET~ixX7=BK&$tLOY5lWy0f~ln~K^la%DJ2xNQA&^iZ78+H50;QT|q4S%-$xb=jCyiD>AO-U0=?RCbJ7C5SWV zQ4!V9i@w)D<+rMiQ6d(*#t4yl7p`fKELBX)$vYK8FQr3t*{|UZ#HqJnQd=3!CbA*C ziE}CjG@Qo;fzv0L3aDl2sA$z~Rst9l@Xd|JC*sn4NZP)|xP$e;Zk-s_v>v7tD;=!p zB@Ic82y~b9O(SDl1>L!4I*-Uz9o=%O(l(oDwwB&UHH=B`J{NLmRSL$8DPwds4N_9}hrPdP+fLP~=;fT@JhC^cZGPMdA&+GhcV)2&VBlzI zP3wuhX^hl+Qm_AvUU2NnmcWoNXPo6kcsRg*1m&!d3(E0uDOa5|B=^{*++CM)X-WN@NxmKYzt2;Q zRFL|HeuVgejKEAoN%BG5!YnCOMT`Ocy!&Ps>SV97_ETsNEe#s>?xAxR-Mudm+s9dQ z9T)eJ*hNcj_~n#0r9_n2bMy^Ilw``s+lcP~!@xe?-d4o-hrd#^kIT~Rs%sYhpJu!0 zJis;SFd>uhxJk?)Og;hy-OT(9I?=;_l#AMnA@s3sG2}?|e0%OA4xLr~jJMmQpJM=D zaGSrz1!UZLlWYV-xhcW8dRstKy{F=(iM z3oiizx0r&m=2o#Kn*0hu)-IadiB2jvqRMwT*XMtZ{%su6V|ps4Ji{p}^eT(W&bEgY z{6(HTiyj%Qo_z`}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; + } + +} \ No newline at end of file diff --git a/MiniMaxPetiteOpti.java b/MiniMaxPetiteOpti.java new file mode 100644 index 0000000..2d0cf9c --- /dev/null +++ b/MiniMaxPetiteOpti.java @@ -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); + } +} diff --git a/README.md b/README.md index 6e7c0e4..33c7cf1 100644 --- a/README.md +++ b/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 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. \ No newline at end of file +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. + + diff --git a/out/production/BUT3JeuR5.5/.idea/.gitignore b/out/production/BUT3JeuR5.5/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/out/production/BUT3JeuR5.5/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/out/production/BUT3JeuR5.5/.idea/misc.xml b/out/production/BUT3JeuR5.5/.idea/misc.xml new file mode 100644 index 0000000..20f033c --- /dev/null +++ b/out/production/BUT3JeuR5.5/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/out/production/BUT3JeuR5.5/.idea/modules.xml b/out/production/BUT3JeuR5.5/.idea/modules.xml new file mode 100644 index 0000000..a5c2172 --- /dev/null +++ b/out/production/BUT3JeuR5.5/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/out/production/BUT3JeuR5.5/.idea/vcs.xml b/out/production/BUT3JeuR5.5/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/out/production/BUT3JeuR5.5/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/out/production/BUT3JeuR5.5/BUT3JeuR5.5.iml b/out/production/BUT3JeuR5.5/BUT3JeuR5.5.iml new file mode 100644 index 0000000..b107a2d --- /dev/null +++ b/out/production/BUT3JeuR5.5/BUT3JeuR5.5.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/out/production/BUT3JeuR5.5/MiniMax.class b/out/production/BUT3JeuR5.5/MiniMax.class new file mode 100644 index 0000000000000000000000000000000000000000..a09c87771ed1d5e835f5842e2e64b88eceeaa6b7 GIT binary patch literal 2066 zcmbVMU2hXt5Ixskdu_A%AR!;v0SqKJo9Bvgr)CQ^%{sxQ3tFZ8K@qpG0iu24ReqwEPpbEa*2lLFzM=ZIe~EMqt4y3O1TC1(r$tv3UnKA)zEZI!yMo7u z|9J(bz3prnndbF38)aHAdycy!@NMh;29C{qcXYdA8TH|!<7_o**~0|2SPmRq+^HFD z+*>(pzRPTDa|R&_B(22P#>>%WY};@PmR_$Lbrlu%)*(#oN>%Z-z{&r1W%o95;WYay z#Mh)EE<27|TsE06IUgt!@_GA`PuiE90lwsTpp3HXIe7RjaFwAHl#z2kL;Of3gqwkr z)NfJOnhu!8ZLZ?DgPGv)YkJ6HR(7H8p(DJ9?p<^!YriD+(ECmsp!N#M+%8U1+s82Q z6Gl_Y_voalXPk={I3m@LsQO;r`?w&zF3O6+ensOPe;~9dK_xJVW1Ltgk;Dj6xX5wE z$4Wq_@EIw3$Wb9H?{8LzyR>ou@sSsOG_zc(2>peEkUVnM1%TeMk$i=Tm-K37BXfX_ zIiJk9pSMZn@2oV!Gt;~1R@QtjdXwYdA-)UBm&sfxAD&Dq&yhY6eTLLiyk(ZF6H1>l z^c>MXCI2)mUcCK--l?JaA(_32d;%TRFZ1HBpc_|-Dogx1V$bvKOmco*<27C^Q=}O&@)(|7M4}wb05JV#v!o?#ygLD)IyN_bU^8UgNP6!^(TYG z<=6{YY6Em207^-qN*kaPKG0_efDW_+I!B=M1iC<=_XxDa!WIeiK7lR~%rb#KAkaku zT_w;*{|jj8-+;y#xb<<63Un!Z$g#VxA3gic9#q+s!f(n>pUNnyRavzp_CEJQtaF*N WliDMCKJdRQSf?$)br}XWaQtuY!;iB7 literal 0 HcmV?d00001 diff --git a/out/production/BUT3JeuR5.5/MiniMaxOptiCarnet.class b/out/production/BUT3JeuR5.5/MiniMaxOptiCarnet.class new file mode 100644 index 0000000000000000000000000000000000000000..337a8cc153424658ade475b193031fdfd25b6d46 GIT binary patch literal 2209 zcmbVNT~iZh6n@@h$tH0Fh=R(8O(|AT3k5%l1yVH#VuN6z_(4@(l2=&S>}EC_3itkq z_O9dTFrD#6nX!)3=}qtY7kbsd(dkH^cau>VVlO%jd(NIc=e*~6&UsJ%c>Crz0GHt= z5kb_1VW9yrf#yeYT@E``mWOcj$O0^B_O7>ccX-U<`2v%)UdnmVWT1J?vC~a4ut#`2=YpjWphV)l-f;uh&sgRjzSqe`xag#Aj zDAxIJ3nZlDREjFl6B#Ya4gJ&y#z*r`ZLpJbUd7L=30os*+gD`2ZUV>cisuF8z?Y?I z6|8!NavTphydoV3zoydJ+I*+S(xNGbd=dpH6A$&stqAnIZ>8<7duwW-I$PB#oRImz z^EU;4*gZTo$Le|4q+4)QxhLm&Yn9T-ezta5_5{vvmQ)@0-DFnp`pE9ducgS6zByiJ zcFLM^UFByTSuU%xiAMq__F<}5stHHn_LI?h!<2Mn5sEx{W^84>VU72<68pLxKRs! zi)dJk7u|;W5~i_4Nj(+nzb3cQ{7ySe?KO^!zC;JLHw1!LIMHGJghrZLPV;382ekSb z)zB;ThUL-g^R1m{xoVtIc!l#Xc)WpS{+(q3y4(zxD9}plQI>lQ&FDZo*I^I3a2m&P zkt;ESG<~~q6DRNhgNz_b9tqFV5u#L>W*iI+%e5=mfld;gC}gz|a&Xk;v! zX*ZrC-4%O+j>p*HDI*t*R-^MNVy(v5aV4fnnM*Z062=q3A-XYLM z0{xEX-XqZa1p0trmIzd0n6?bJ&p6co0($2|K;yW(=U$O2G#T5-@Jd`cc(QpLSM?1O q;m9_IRK`fH$*MK6i~JU0&G#r9sV&p 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, + +