1 :-use_module(library(clpfd)).
4 /* init7(Coul,Jeu),successeurs(Jeu,Coul,L),length(L,N),aff_coup_possible(L).
5 init3(Coul,Jeu),successeurs(Jeu,Coul,L),length(L,N),aff_coup_possible(L).
6 init5(Coul,Jeu),successeurs(Jeu,Coul,L),length(L,N),aff_coup_possible(L). */
36 /*****************************/
37 /* Colonnes, lignes et cases */
38 /*****************************/
40 /* accesseurs sur ligne et colonne*/
42 ligcol(1,[A,_,_,_,_,_,_],A).
43 ligcol(2,[_,A,_,_,_,_,_],A).
44 ligcol(3,[_,_,A,_,_,_,_],A).
45 ligcol(4,[_,_,_,A,_,_,_],A).
46 ligcol(5,[_,_,_,_,A,_,_],A).
47 ligcol(6,[_,_,_,_,_,A,_],A).
48 ligcol(7,[_,_,_,_,_,_,A],A).
50 ligcol(1,[A,_,_,_,_],A).
51 ligcol(2,[_,A,_,_,_],A).
52 ligcol(3,[_,_,A,_,_],A).
53 ligcol(4,[_,_,_,A,_],A).
54 ligcol(5,[_,_,_,_,A],A).
67 /* retourne le contenu "Contenu_case" de la case
68 situé à la colonne "Col" et la ligne "Lig" du jeux en cours
71 case(Lig,Col,Contenu_jeu,Contenu_case) :-
72 ligcol(Lig,Contenu_jeu,Ligne),
73 ligcol(Col,Ligne,Contenu_case).
78 changeContenuLigCol(1,X,[_,B,C,D,E,F,G],[X,B,C,D,E,F,G]).
79 changeContenuLigCol(2,X,[A,_,C,D,E,F,G],[A,X,C,D,E,F,G]).
80 changeContenuLigCol(3,X,[A,B,_,D,E,F,G],[A,B,X,D,E,F,G]).
81 changeContenuLigCol(4,X,[A,B,C,_,E,F,G],[A,B,C,X,E,F,G]).
82 changeContenuLigCol(5,X,[A,B,C,D,_,F,G],[A,B,C,D,X,F,G]).
83 changeContenuLigCol(6,X,[A,B,C,D,E,_,G],[A,B,C,D,E,X,G]).
84 changeContenuLigCol(7,X,[A,B,C,D,E,F,_],[A,B,C,D,E,F,X]).
86 changeContenuLigCol(1,X,[_,B,C,D,E],[X,B,C,D,E]).
87 changeContenuLigCol(2,X,[A,_,C,D,E],[A,X,C,D,E]).
88 changeContenuLigCol(3,X,[A,B,_,D,E],[A,B,X,D,E]).
89 changeContenuLigCol(4,X,[A,B,C,_,E],[A,B,C,X,E]).
90 changeContenuLigCol(5,X,[A,B,C,D,_],[A,B,C,D,X]).
92 changeContenuLigCol(1,X,[_,B,C],[X,B,C]).
93 changeContenuLigCol(2,X,[A,_,C],[A,X,C]).
94 changeContenuLigCol(3,X,[A,B,_],[A,B,X]).
100 changeContenu(Conf1,Piece,Y,X,Conf2):-
101 ligcol(Y,Conf1,Ligne),
102 changeContenuLigCol(X,Piece,Ligne,Lignep),
103 changeContenuLigCol(Y,Lignep,Conf1,Conf2).
112 /*********************/
113 /* position initiale */
114 /*********************/
144 init7_test_victoire(b,
153 init7_test_victoire2(b,
194 affligne:-write('-----------------------------'),nl.
202 affiche2([Prem_ligne|Reste]):-
203 write('|'),affpions(Prem_ligne),nl,affligne,
231 aff_coup_possible([]).
233 aff_coup_possible([P|R]):-
235 aff_coup_possible(R).
241 test_victoire(Coul,Jeu,true):-
244 test_victoire(Coul,Jeu,false):-
245 not(victoire(Coul,Jeu)).
249 victoire(n,Contenu_jeu):-
250 case(1,_,Contenu_jeu,nb).
252 victoire(b,Contenu_jeu):-
253 case(7,_,Contenu_jeu,bb).
256 /*************************/
257 /* deplacement possibles */
258 /*************************/
260 deplacement(0,_,Contenu_jeu,Contenu_jeu).
264 deplacement(1,Coul,Contenu_jeu,Nouv_Contenu_jeu):-
265 case(Lig,Col,Contenu_jeu,Coul),
266 Ligp is Lig-1, Ligp >= 1,
267 case(Ligp,Col,Contenu_jeu,v),
268 changeContenu(Contenu_jeu,v,Lig,Col,Contenu_jeu1),
269 changeContenu(Contenu_jeu1,Coul,Ligp,Col,Nouv_Contenu_jeu).
273 deplacement(1,Coul,Contenu_jeu,Nouv_Contenu_jeu):-
274 case(Lig,Col,Contenu_jeu,Coul),
275 Colp is Col-1, Colp >= 1,
276 case(Lig,Colp,Contenu_jeu,v),
277 changeContenu(Contenu_jeu,v,Lig,Col,Contenu_jeu1),
278 changeContenu(Contenu_jeu1,Coul,Lig,Colp,Nouv_Contenu_jeu).
285 depl(X,Coul,Contenu_jeu,Nouv_Contenu_jeu):-
286 deplacement(X,Coul,Contenu_jeu,Nouv_Contenu_jeu).
287 depl(X,Coul,Contenu_jeu,Nouv_Contenu_jeu):-
288 deplacement(X,Coul,Nouv_Contenu_jeu,Contenu_jeu).
291 /*************************/
292 /* lancer de balle */
293 /*************************/
312 aucun_adversaire_ligne(_,_,_,_,0).
313 aucun_adversaire_ligne(Coul,Lig,Col,Contenu_jeu,Delta):-
315 case(Lig,Colp,Contenu_jeu,Coulp),
318 aucun_adversaire_ligne(Coul,Lig,Col,Contenu_jeu,Deltap).
320 aucun_adversaire_col(_,_,_,_,0).
321 aucun_adversaire_col(Coul,Lig,Col,Contenu_jeu,Delta):-
323 case(Ligp,Col,Contenu_jeu,Coulp),
326 aucun_adversaire_col(Coul,Lig,Col,Contenu_jeu,Deltap).
336 aucun_adversaire_diag1(_,_,_,_,0).
337 aucun_adversaire_diag1(Coul,Lig,Col,Contenu_jeu,Delta):-
338 Ligp is Lig + Delta, Colp is Col + Delta,
339 case(Ligp,Colp,Contenu_jeu,Coulp),
343 aucun_adversaire_diag1(Coul,Lig,Col,Contenu_jeu,Deltap).
345 aucun_adversaire_diag2(_,_,_,_,0).
346 aucun_adversaire_diag2(Coul,Lig,Col,Contenu_jeu,Delta):-
347 Ligp is Lig + Delta, Colp is Col - Delta,
348 case(Ligp,Colp,Contenu_jeu,Coulp),
352 aucun_adversaire_diag2(Coul,Lig,Col,Contenu_jeu,Deltap).
359 lancerh(Coul,Contenu_jeu,Nouv_Contenu_jeu):-
361 case(Lig,Col,Contenu_jeu,Coulb),
362 case(Lig,Colp,Contenu_jeu,Coul),
366 aucun_adversaire_ligne(Coul,Lig,Min,Contenu_jeu,Delta),
368 changeContenu(Contenu_jeu,Coul,Lig,Col,Contenu_jeu1),
369 changeContenu(Contenu_jeu1,Coulb,Lig,Colp,Nouv_Contenu_jeu).
371 /* case(Lig,Col,Nouv_Contenu_jeu,Coul),
372 case(Lig,Colp,Nouv_Contenu_jeu,Coulb).*/
376 lancerv(Coul,Contenu_jeu,Nouv_Contenu_jeu):-
378 case(Lig,Col,Contenu_jeu,Coulb),
379 case(Ligp,Col,Contenu_jeu,Coul),
383 aucun_adversaire_col(Coul,Lig,Min,Contenu_jeu,Delta),
385 changeContenu(Contenu_jeu,Coul,Lig,Col,Contenu_jeu1),
386 changeContenu(Contenu_jeu1,Coulb,Ligp,Col,Nouv_Contenu_jeu).
387 /*case(Lig,Col,Nouv_Contenu_jeu,Coul),
388 case(Ligp,Col,Nouv_Contenu_jeu,Coulb).*/
391 /* diag haut droite */
392 lancerd1(Coul,Contenu_jeu,Nouv_Contenu_jeu):-
394 case(Lig,Col,Contenu_jeu,Coulb),
395 case(Ligp,Colp,Contenu_jeu,Coul),
396 Delta is Ligp-Lig -1,
397 Delta is Colp-Col -1,
398 aucun_adversaire_diag1(Coul,Lig,Col,Contenu_jeu,Delta),
400 changeContenu(Contenu_jeu,Coul,Lig,Col,Contenu_jeu1),
401 changeContenu(Contenu_jeu1,Coulb,Ligp,Colp,Nouv_Contenu_jeu).
403 /*case(Lig,Col,Nouv_Contenu_jeu,Coul),
404 case(Ligp,Colp,Nouv_Contenu_jeu,Coulb).*/
410 /* diag haut gauche */
411 lancerd2(Coul,Contenu_jeu,Nouv_Contenu_jeu):-
413 case(Lig,Col,Contenu_jeu,Coulb),
414 case(Ligp,Colp,Contenu_jeu,Coul),
415 Delta is -(Ligp-Lig -1),
416 Delta is Colp-Col -1,
417 aucun_adversaire_diag2(Coul,Lig,Col,Contenu_jeu,Delta),
419 changeContenu(Contenu_jeu,Coul,Lig,Col,Contenu_jeu1),
420 changeContenu(Contenu_jeu1,Coulb,Ligp,Colp,Nouv_Contenu_jeu).
422 /*case(Lig,Col,Nouv_Contenu_jeu,Coul),
423 case(Ligp,Colp,Nouv_Contenu_jeu,Coulb).*/
428 lancer(0,_,Contenu_jeu,Contenu_jeu).
430 lancer(1,Coul,Contenu_jeu,Nouv_Contenu_jeu):-
431 lancerv(Coul,Contenu_jeu,Nouv_Contenu_jeu);
432 lancerh(Coul,Contenu_jeu,Nouv_Contenu_jeu);
433 lancerd1(Coul,Contenu_jeu,Nouv_Contenu_jeu);
434 lancerd2(Coul,Contenu_jeu,Nouv_Contenu_jeu).
438 coup(Coul,Contenu_Jeu,Nouv_Contenu_jeu):-
439 lancer(L1,Coul,Contenu_Jeu,Contenu_jeu1),
440 depl(D1,Coul,Contenu_jeu1,Contenu_jeu2),
441 lancer(L2,Coul,Contenu_jeu2,Contenu_jeu3),
442 depl(D2,Coul,Contenu_jeu3,Contenu_jeu4),
443 lancer(L3,Coul,Contenu_jeu4,Nouv_Contenu_jeu),
456 /************ TODO à affiner **********/
459 valeur(b,Conf,1000):-
463 maplist(nb_ele(b),Conf,L1),
466 maplist(poids_ligne,L1,L2,L3),
470 /* pour une ligne de poids X, de rang Y, son poids est P */
479 maplist(nb_ele(n),Conf,L1),
482 maplist(poids_ligne2(N),L1,L2,L3),
488 /* pour une ligne de poids X, de rang Y, son poids est N */
493 poids_ligne2(N,X,Y,R):-
496 /*nbre d elements N de la couleur Coul dans la liste L */
498 sublist(ma_couleur(Coul),L,Lp),
501 successeurs(N,Coul,L) :-
502 findall(NP,coup(Coul,N,NP),Lp),
507 choisit la meilleur conf à partir de Conf parmi les susccesseurs
508 alpha est la valeur minimum estimée jusqu'à présent
509 beta est la valeur maximum estimée jusqu'à présent
511 evaluate_and_choose(Coul,[Succ|Succs],Conf,D,Alpha,Beta,Record,MeilleurSuccVal):-
512 joueur_suivant(Coul,Coulp),
513 alpha_beta(Coulp,D,Succ,Alpha,Beta,_,Valeur),
515 cutoff(Coul,Succ,Valeurp,D,Alpha,Beta,Succs,Conf,Record,MeilleurSuccVal).
517 evaluate_and_choose(_,[],_,_,Alpha,_,Record,(Record,Alpha)).
520 /* implantation alpha beta du minimax */
521 alpha_beta(Coul,0,Conf,_,_,_,Valeur) :-
522 valeur(Coul,Conf,Valeur).
524 alpha_beta(Coul,D,Conf,Alpha,Beta,Succ,Valeur) :-
526 successeurs(Conf,Coul,Succs),
530 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]),
531 evaluate_and_choose(Coul,Succs,Conf,D1,Alpha1,Beta1,nil,(Succ,Valeur)).
534 cutoff(_,Succ,Valeur,_,_,Beta,_,_,_,(Succ,Valeur)):-
536 cutoff(Coul,Succ,Valeur,D,Alpha,Beta,Succs,Conf,_Record,MeilleurSuccVal):-
537 Alpha < Value, Value < Beta,
538 evaluate_and_choose(Coul,Succs,Conf,D,Valeur,Beta,Succ,MeilleurSuccVal).
539 cutoff(Coul,_,Valeur,D,Alpha,Beta,Succs,Conf,Record,MeilleurSuccVal) :-
541 evaluate_and_choose(Coul,Succs,Conf,D,Alpha,Beta,Record,MeilleurSuccVal).
546 [A1,A2,A3,A4,A5,A6,A7],
547 [B1,B2,B3,B4,B5,B6,B7],
548 [C1,C2,C3,C4,C5,C6,C7],
549 [D1,D2,D3,D4,D5,D6,D7],
550 [E1,E2,E3,E4,E5,E6,E7],
551 [F1,F2,F3,F4,F5,F6,F7],
552 [G1,G2,G3,G4,G5,G6,G7]],
553 [[A7,A6,A5,A4,A3,A2,A1],
554 [B7,B6,B5,B4,B3,B2,B1],
555 [C7,C6,C5,C4,C3,C2,C1],
556 [D7,D6,D5,D4,D3,D2,D1],
557 [E7,E6,E5,E4,E3,E2,E1],
558 [F7,F6,F5,F4,F3,F2,F1],
559 [G7,G6,G5,G4,G3,G2,G1]]).
583 non_symetrique_de(X,Y):- not(symetrique(X,Y)).
586 filtre_sym([X|T],[X|R]):-
587 sublist(non_symetrique_de(X),T,Ns),
592 tour(Contenu_Jeu, Coul) :-
593 victoire(Coul,Contenu_Jeu).
595 tour(Contenu_Jeu, Coul) :-
596 coup(Coul,Contenu_Jeu,Nouv_Contenu_jeu),
597 victoire(Coul,Nouv_Contenu_jeu).
600 tour(Contenu_Jeu, Coul) :-
601 coup(Coul,Contenu_Jeu,Nouv_Contenu_jeu),
602 joueur_suivant(Coul,Coulp),
603 not(victoire(Coul,Nouv_Contenu_jeu)),
604 tour(Nouv_Contenu_jeu,Coulp).