:-use_module(library(clpfd)). /* init7(Coul,Jeu),successeurs(Jeu,Coul,L),length(L,N),aff_coup_possible(L). init3(Coul,Jeu),successeurs(Jeu,Coul,L),length(L,N),aff_coup_possible(L). init5(Coul,Jeu),successeurs(Jeu,Coul,L),length(L,N),aff_coup_possible(L). */ /***************/ /* aritmétique */ /***************/ abs(X,X):- X >= 0. abs(X,A):- A is 0 - X. min(X,Y,X):- X =< Y. min(_,Y,Y). max(X,Y,X):- X > Y . max(_,Y,Y). /* types de case v : vide b : blanc n : noire bb: blanc + balle nb: noire + balle */ /*****************************/ /* Colonnes, lignes et cases */ /*****************************/ /* accesseurs sur ligne et colonne*/ ligcol(1,[A,_,_,_,_,_,_],A). ligcol(2,[_,A,_,_,_,_,_],A). ligcol(3,[_,_,A,_,_,_,_],A). ligcol(4,[_,_,_,A,_,_,_],A). ligcol(5,[_,_,_,_,A,_,_],A). ligcol(6,[_,_,_,_,_,A,_],A). ligcol(7,[_,_,_,_,_,_,A],A). ligcol(1,[A,_,_,_,_],A). ligcol(2,[_,A,_,_,_],A). ligcol(3,[_,_,A,_,_],A). ligcol(4,[_,_,_,A,_],A). ligcol(5,[_,_,_,_,A],A). ligcol(1,[A,_,_],A). ligcol(2,[_,A,_],A). ligcol(3,[_,_,A],A). /* retourne le contenu "Contenu_case" de la case situé à la colonne "Col" et la ligne "Lig" du jeux en cours "Contenu_jeu" */ case(Lig,Col,Contenu_jeu,Contenu_case) :- ligcol(Lig,Contenu_jeu,Ligne), ligcol(Col,Ligne,Contenu_case). changeContenuLigCol(1,X,[_,B,C,D,E,F,G],[X,B,C,D,E,F,G]). changeContenuLigCol(2,X,[A,_,C,D,E,F,G],[A,X,C,D,E,F,G]). changeContenuLigCol(3,X,[A,B,_,D,E,F,G],[A,B,X,D,E,F,G]). changeContenuLigCol(4,X,[A,B,C,_,E,F,G],[A,B,C,X,E,F,G]). changeContenuLigCol(5,X,[A,B,C,D,_,F,G],[A,B,C,D,X,F,G]). changeContenuLigCol(6,X,[A,B,C,D,E,_,G],[A,B,C,D,E,X,G]). changeContenuLigCol(7,X,[A,B,C,D,E,F,_],[A,B,C,D,E,F,X]). changeContenuLigCol(1,X,[_,B,C,D,E],[X,B,C,D,E]). changeContenuLigCol(2,X,[A,_,C,D,E],[A,X,C,D,E]). changeContenuLigCol(3,X,[A,B,_,D,E],[A,B,X,D,E]). changeContenuLigCol(4,X,[A,B,C,_,E],[A,B,C,X,E]). changeContenuLigCol(5,X,[A,B,C,D,_],[A,B,C,D,X]). changeContenuLigCol(1,X,[_,B,C],[X,B,C]). changeContenuLigCol(2,X,[A,_,C],[A,X,C]). changeContenuLigCol(3,X,[A,B,_],[A,B,X]). changeContenu(Conf1,Piece,Y,X,Conf2):- ligcol(Y,Conf1,Ligne), changeContenuLigCol(X,Piece,Ligne,Lignep), changeContenuLigCol(Y,Lignep,Conf1,Conf2). sans_balle(b). sans_balle(n). /*********************/ /* position initiale */ /*********************/ init7(b, [[b,b,b,bb,b,b,b], [v,v,v,v,v,v,v], [v,v,v,v,v,v,v], [v,v,v,v,v,v,v], [v,v,v,v,v,v,v], [v,v,v,v,v,v,v], [n,n,n,nb,n,n,n]]). init7_2(b, [[b,n,b,bb,b,n,b], [v,v,v,v,v,v,v], [v,v,v,v,v,v,v], [v,v,v,v,v,v,v], [v,v,v,v,v,v,v], [v,v,v,v,v,v,v], [n,b,n,nb,n,b,n]]). init7_test1(b, [[v,n,v,v,v,n,b], [v,v,v,v,v,v,v], [b,v,b,b,b,bb,v], [v,v,v,v,v,v,v], [v,v,v,v,v,v,v], [v,v,v,v,n,b,n], [n,v,n,nb,v,v,v]]). init7_test_victoire(b, [[v,n,v,v,v,n,b], [v,v,v,v,v,v,v], [b,v,b,b,b,b,v], [v,v,v,v,v,v,v], [v,v,v,v,v,v,v], [v,v,v,v,n,b,n], [n,bb,n,nb,v,v,v]]). init7_test_victoire2(b, [[v,n,v,v,v,nb,b], [v,v,v,v,v,v,v], [b,v,b,v,b,b,v], [v,v,v,v,v,v,v], [v,v,v,v,v,v,v], [v,v,v,v,n,b,n], [n,bb,n,n,v,v,v]]). init5(b, [[b,b,bb,b,b], [v,v,v,v,v], [v,v,v,v,v], [v,v,v,v,v], [n,n,nb,n,n]]). init5_2(b, [[n,b,bb,b,n], [v,v,v,v,v], [v,v,v,v,v], [v,v,v,v,v], [b,n,nb,n,b]]). init3(b, [[b,bb,b], [v,v,v], [n,nb,n]]). init3_2(b, [[n,bb,n], [v,v,v], [b,nb,b]]). /* affichage */ affligne:-write('-----------------------------'),nl. affiche(Jeu):- affligne, affiche2(Jeu). affiche2([]). affiche2([Prem_ligne|Reste]):- write('|'),affpions(Prem_ligne),nl,affligne, affiche2(Reste). affpions([]). affpions([b|R]):- write(' b |'), affpions(R). affpions([v|R]):- write(' |'), affpions(R). affpions([n|R]):- write(' n |'), affpions(R). affpions([bb|R]):- write(' bb|'), affpions(R). affpions([nb|R]):- write(' nb|'), affpions(R). aff_coup_possible([]). aff_coup_possible([P|R]):- affiche(P), aff_coup_possible(R). /* victoire */ test_victoire(Coul,Jeu,true):- victoire(Coul,Jeu). test_victoire(Coul,Jeu,false):- not(victoire(Coul,Jeu)). victoire(n,Contenu_jeu):- case(1,_,Contenu_jeu,nb). victoire(b,Contenu_jeu):- case(7,_,Contenu_jeu,bb). /*************************/ /* deplacement possibles */ /*************************/ deplacement(0,_,Contenu_jeu,Contenu_jeu). /*monter un */ deplacement(1,Coul,Contenu_jeu,Nouv_Contenu_jeu):- case(Lig,Col,Contenu_jeu,Coul), Ligp is Lig-1, Ligp >= 1, case(Ligp,Col,Contenu_jeu,v), changeContenu(Contenu_jeu,v,Lig,Col,Contenu_jeu1), changeContenu(Contenu_jeu1,Coul,Ligp,Col,Nouv_Contenu_jeu). /*gauche un */ deplacement(1,Coul,Contenu_jeu,Nouv_Contenu_jeu):- case(Lig,Col,Contenu_jeu,Coul), Colp is Col-1, Colp >= 1, case(Lig,Colp,Contenu_jeu,v), changeContenu(Contenu_jeu,v,Lig,Col,Contenu_jeu1), changeContenu(Contenu_jeu1,Coul,Lig,Colp,Nouv_Contenu_jeu). /* descendre */ depl(X,Coul,Contenu_jeu,Nouv_Contenu_jeu):- deplacement(X,Coul,Contenu_jeu,Nouv_Contenu_jeu). depl(X,Coul,Contenu_jeu,Nouv_Contenu_jeu):- deplacement(X,Coul,Nouv_Contenu_jeu,Contenu_jeu). /*************************/ /* lancer de balle */ /*************************/ amis(n,n). amis(n,v). amis(b,b). amis(b,v). ma_couleur(b,b). ma_couleur(b,bb). ma_couleur(n,n). ma_couleur(n,nb). balon(n,nb). balon(b,bb). aucun_adversaire_ligne(_,_,_,_,0). aucun_adversaire_ligne(Coul,Lig,Col,Contenu_jeu,Delta):- Colp is Col + Delta, case(Lig,Colp,Contenu_jeu,Coulp), amis(Coul,Coulp), Deltap is Delta -1, aucun_adversaire_ligne(Coul,Lig,Col,Contenu_jeu,Deltap). aucun_adversaire_col(_,_,_,_,0). aucun_adversaire_col(Coul,Lig,Col,Contenu_jeu,Delta):- Ligp is Lig + Delta, case(Ligp,Col,Contenu_jeu,Coulp), amis(Coul,Coulp), Deltap is Delta -1, aucun_adversaire_col(Coul,Lig,Col,Contenu_jeu,Deltap). sign(x,1):- x >= 0. sign(x,-1):- x < 0. aucun_adversaire_diag1(_,_,_,_,0). aucun_adversaire_diag1(Coul,Lig,Col,Contenu_jeu,Delta):- Ligp is Lig + Delta, Colp is Col + Delta, case(Ligp,Colp,Contenu_jeu,Coulp), amis(Coul,Coulp), sign(Delta,s), Deltap is Delta -s, aucun_adversaire_diag1(Coul,Lig,Col,Contenu_jeu,Deltap). aucun_adversaire_diag2(_,_,_,_,0). aucun_adversaire_diag2(Coul,Lig,Col,Contenu_jeu,Delta):- Ligp is Lig + Delta, Colp is Col - Delta, case(Ligp,Colp,Contenu_jeu,Coulp), amis(Coul,Coulp), sign(Delta,s), Deltap is Delta -s, aucun_adversaire_diag2(Coul,Lig,Col,Contenu_jeu,Deltap). /* horizontal */ lancerh(Coul,Contenu_jeu,Nouv_Contenu_jeu):- balon(Coul,Coulb), case(Lig,Col,Contenu_jeu,Coulb), case(Lig,Colp,Contenu_jeu,Coul), min(Col,Colp,Min), max(Col,Colp,Max), Delta is Max-Min -1, aucun_adversaire_ligne(Coul,Lig,Min,Contenu_jeu,Delta), changeContenu(Contenu_jeu,Coul,Lig,Col,Contenu_jeu1), changeContenu(Contenu_jeu1,Coulb,Lig,Colp,Nouv_Contenu_jeu). /* case(Lig,Col,Nouv_Contenu_jeu,Coul), case(Lig,Colp,Nouv_Contenu_jeu,Coulb).*/ /* vertical */ lancerv(Coul,Contenu_jeu,Nouv_Contenu_jeu):- balon(Coul,Coulb), case(Lig,Col,Contenu_jeu,Coulb), case(Ligp,Col,Contenu_jeu,Coul), min(Lig,Ligp,Min), max(Lig,Ligp,Max), Delta is Max-Min -1, aucun_adversaire_col(Coul,Lig,Min,Contenu_jeu,Delta), changeContenu(Contenu_jeu,Coul,Lig,Col,Contenu_jeu1), changeContenu(Contenu_jeu1,Coulb,Ligp,Col,Nouv_Contenu_jeu). /*case(Lig,Col,Nouv_Contenu_jeu,Coul), case(Ligp,Col,Nouv_Contenu_jeu,Coulb).*/ /* diag haut droite */ lancerd1(Coul,Contenu_jeu,Nouv_Contenu_jeu):- balon(Coul,Coulb), case(Lig,Col,Contenu_jeu,Coulb), case(Ligp,Colp,Contenu_jeu,Coul), Delta is Ligp-Lig -1, Delta is Colp-Col -1, aucun_adversaire_diag1(Coul,Lig,Col,Contenu_jeu,Delta), changeContenu(Contenu_jeu,Coul,Lig,Col,Contenu_jeu1), changeContenu(Contenu_jeu1,Coulb,Ligp,Colp,Nouv_Contenu_jeu). /*case(Lig,Col,Nouv_Contenu_jeu,Coul), case(Ligp,Colp,Nouv_Contenu_jeu,Coulb).*/ /* diag haut gauche */ lancerd2(Coul,Contenu_jeu,Nouv_Contenu_jeu):- balon(Coul,Coulb), case(Lig,Col,Contenu_jeu,Coulb), case(Ligp,Colp,Contenu_jeu,Coul), Delta is -(Ligp-Lig -1), Delta is Colp-Col -1, aucun_adversaire_diag2(Coul,Lig,Col,Contenu_jeu,Delta), changeContenu(Contenu_jeu,Coul,Lig,Col,Contenu_jeu1), changeContenu(Contenu_jeu1,Coulb,Ligp,Colp,Nouv_Contenu_jeu). /*case(Lig,Col,Nouv_Contenu_jeu,Coul), case(Ligp,Colp,Nouv_Contenu_jeu,Coulb).*/ lancer(0,_,Contenu_jeu,Contenu_jeu). lancer(1,Coul,Contenu_jeu,Nouv_Contenu_jeu):- lancerv(Coul,Contenu_jeu,Nouv_Contenu_jeu); lancerh(Coul,Contenu_jeu,Nouv_Contenu_jeu); lancerd1(Coul,Contenu_jeu,Nouv_Contenu_jeu); lancerd2(Coul,Contenu_jeu,Nouv_Contenu_jeu). coup(Coul,Contenu_Jeu,Nouv_Contenu_jeu):- lancer(L1,Coul,Contenu_Jeu,Contenu_jeu1), depl(D1,Coul,Contenu_jeu1,Contenu_jeu2), lancer(L2,Coul,Contenu_jeu2,Contenu_jeu3), depl(D2,Coul,Contenu_jeu3,Contenu_jeu4), lancer(L3,Coul,Contenu_jeu4,Nouv_Contenu_jeu), L is L1+L2+L3, L=<1, D is D1+D2, D =< 2. /* tour */ joueur_suivant(n,b). joueur_suivant(b,n). /************ TODO à affiner **********/ valeur(b,Conf,1000):- victoire(b,Conf). valeur(b,Conf,T):- maplist(nb_ele(b),Conf,L1), length(Conf,N), numlist(1,N,L2), maplist(poids_ligne,L1,L2,L3), sumlist(L3,T),!. <<<<<<< .mine /* pour une ligne de poids X, de rang Y, son poids est P */ poids_ligne(X,Y,P):- P is 10*X*Y,!. ======= valeur(n,Conf,T):- victoire(n,Conf), T is -1000. valeur(n,Conf,Tp):- maplist(nb_ele(n),Conf,L1), length(Conf,N), numlist(1,N,L2), maplist(poids_ligne2(N),L1,L2,L3), sumlist(L3,T), Tp is -T, !. /* pour une ligne de poids X, de rang Y, son poids est N */ poids_ligne(X,Y,N):- N is 10*X*Y,!. >>>>>>> .r7 poids_ligne2(N,X,Y,R):- R is (N+1-Y)*10*X,!. /*nbre d elements N de la couleur Coul dans la liste L */ nb_ele(Coul,L,N):- sublist(ma_couleur(Coul),L,Lp), length(Lp,N). successeurs(N,Coul,L) :- findall(NP,coup(Coul,N,NP),Lp), list_to_set(Lp,Lpp), filtre_sym(Lpp,L). /* choisit la meilleur conf à partir de Conf parmi les susccesseurs alpha est la valeur minimum estimée jusqu'à présent beta est la valeur maximum estimée jusqu'à présent */ evaluate_and_choose(Coul,[Succ|Succs],Conf,D,Alpha,Beta,Record,MeilleurSuccVal):- joueur_suivant(Coul,Coulp), alpha_beta(Coulp,D,Succ,Alpha,Beta,_,Valeur), Valeurp is -Valeur, cutoff(Coul,Succ,Valeurp,D,Alpha,Beta,Succs,Conf,Record,MeilleurSuccVal). evaluate_and_choose(_,[],_,_,Alpha,_,Record,(Record,Alpha)). /* implantation alpha beta du minimax */ alpha_beta(Coul,0,Conf,_,_,_,Valeur) :- valeur(Coul,Conf,Valeur). alpha_beta(Coul,D,Conf,Alpha,Beta,Succ,Valeur) :- D > 0, successeurs(Conf,Coul,Succs), Alpha1 is -Beta, Beta1 is -Alpha, D1 is D-1, writef('%w\n %w\n %w\n%w\n %w\n %w\n%w\n %w\n',[Coul,Conf,D1,Alpha1,Beta1,nil,Succ,Valeur]), evaluate_and_choose(Coul,Succs,Conf,D1,Alpha1,Beta1,nil,(Succ,Valeur)). cutoff(_,Succ,Valeur,_,_,Beta,_,_,_,(Succ,Valeur)):- Valeur >= Beta,!. cutoff(Coul,Succ,Valeur,D,Alpha,Beta,Succs,Conf,_Record,MeilleurSuccVal):- Alpha < Value, Value < Beta, evaluate_and_choose(Coul,Succs,Conf,D,Valeur,Beta,Succ,MeilleurSuccVal). cutoff(Coul,_,Valeur,D,Alpha,Beta,Succs,Conf,Record,MeilleurSuccVal) :- Valeur =< Alpha,!, evaluate_and_choose(Coul,Succs,Conf,D,Alpha,Beta,Record,MeilleurSuccVal). symetrique( [ [A1,A2,A3,A4,A5,A6,A7], [B1,B2,B3,B4,B5,B6,B7], [C1,C2,C3,C4,C5,C6,C7], [D1,D2,D3,D4,D5,D6,D7], [E1,E2,E3,E4,E5,E6,E7], [F1,F2,F3,F4,F5,F6,F7], [G1,G2,G3,G4,G5,G6,G7]], [[A7,A6,A5,A4,A3,A2,A1], [B7,B6,B5,B4,B3,B2,B1], [C7,C6,C5,C4,C3,C2,C1], [D7,D6,D5,D4,D3,D2,D1], [E7,E6,E5,E4,E3,E2,E1], [F7,F6,F5,F4,F3,F2,F1], [G7,G6,G5,G4,G3,G2,G1]]). symetrique( [ [A1,A2,A3,A4,A5], [B1,B2,B3,B4,B5], [C1,C2,C3,C4,C5], [D1,D2,D3,D4,D5], [E1,E2,E3,E4,E5]], [[A5,A4,A3,A2,A1], [B5,B4,B3,B2,B1], [C5,C4,C3,C2,C1], [D5,D4,D3,D2,D1], [E5,E4,E3,E2,E1]]). symetrique( [ [A1,A2,A3], [B1,B2,B3], [C1,C2,C3]], [[A3,A2,A1], [B3,B2,B1], [C3,C2,C1]]). non_symetrique_de(X,Y):- not(symetrique(X,Y)). filtre_sym([],[]). filtre_sym([X|T],[X|R]):- sublist(non_symetrique_de(X),T,Ns), filtre_sym(Ns,R). /* tour(Contenu_Jeu, Coul) :- victoire(Coul,Contenu_Jeu). tour(Contenu_Jeu, Coul) :- coup(Coul,Contenu_Jeu,Nouv_Contenu_jeu), victoire(Coul,Nouv_Contenu_jeu). tour(Contenu_Jeu, Coul) :- coup(Coul,Contenu_Jeu,Nouv_Contenu_jeu), joueur_suivant(Coul,Coulp), not(victoire(Coul,Nouv_Contenu_jeu)), tour(Nouv_Contenu_jeu,Coulp). */