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,
185 affligne:-write('-----------------------------'),nl.
193 affiche2([Prem_ligne|Reste]):-
194 write('|'),affpions(Prem_ligne),nl,affligne,
222 aff_coup_possible([]).
224 aff_coup_possible([P|R]):-
226 aff_coup_possible(R).
232 test_victoire(Coul,Jeu,true):-
235 test_victoire(Coul,Jeu,false):-
236 not(victoire(Coul,Jeu)).
240 victoire(n,Contenu_jeu):-
241 case(1,_,Contenu_jeu,nb).
243 victoire(b,Contenu_jeu):-
244 case(7,_,Contenu_jeu,bb).
247 /*************************/
248 /* deplacement possibles */
249 /*************************/
251 deplacement(0,_,Contenu_jeu,Contenu_jeu).
255 deplacement(1,Coul,Contenu_jeu,Nouv_Contenu_jeu):-
256 case(Lig,Col,Contenu_jeu,Coul),
257 Ligp is Lig-1, Ligp >= 1,
258 case(Ligp,Col,Contenu_jeu,v),
259 changeContenu(Contenu_jeu,v,Lig,Col,Contenu_jeu1),
260 changeContenu(Contenu_jeu1,Coul,Ligp,Col,Nouv_Contenu_jeu).
264 deplacement(1,Coul,Contenu_jeu,Nouv_Contenu_jeu):-
265 case(Lig,Col,Contenu_jeu,Coul),
266 Colp is Col-1, Colp >= 1,
267 case(Lig,Colp,Contenu_jeu,v),
268 changeContenu(Contenu_jeu,v,Lig,Col,Contenu_jeu1),
269 changeContenu(Contenu_jeu1,Coul,Lig,Colp,Nouv_Contenu_jeu).
276 depl(X,Coul,Contenu_jeu,Nouv_Contenu_jeu):-
277 deplacement(X,Coul,Contenu_jeu,Nouv_Contenu_jeu).
278 depl(X,Coul,Contenu_jeu,Nouv_Contenu_jeu):-
279 deplacement(X,Coul,Nouv_Contenu_jeu,Contenu_jeu).
282 /*************************/
283 /* lancer de balle */
284 /*************************/
303 aucun_adversaire_ligne(_,_,_,_,0).
304 aucun_adversaire_ligne(Coul,Lig,Col,Contenu_jeu,Delta):-
306 case(Lig,Colp,Contenu_jeu,Coulp),
309 aucun_adversaire_ligne(Coul,Lig,Col,Contenu_jeu,Deltap).
311 aucun_adversaire_col(_,_,_,_,0).
312 aucun_adversaire_col(Coul,Lig,Col,Contenu_jeu,Delta):-
314 case(Ligp,Col,Contenu_jeu,Coulp),
317 aucun_adversaire_col(Coul,Lig,Col,Contenu_jeu,Deltap).
327 aucun_adversaire_diag1(_,_,_,_,0).
328 aucun_adversaire_diag1(Coul,Lig,Col,Contenu_jeu,Delta):-
329 Ligp is Lig + Delta, Colp is Col + Delta,
330 case(Ligp,Colp,Contenu_jeu,Coulp),
334 aucun_adversaire_diag1(Coul,Lig,Col,Contenu_jeu,Deltap).
336 aucun_adversaire_diag2(_,_,_,_,0).
337 aucun_adversaire_diag2(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_diag2(Coul,Lig,Col,Contenu_jeu,Deltap).
350 lancerh(Coul,Contenu_jeu,Nouv_Contenu_jeu):-
352 case(Lig,Col,Contenu_jeu,Coulb),
353 case(Lig,Colp,Contenu_jeu,Coul),
357 aucun_adversaire_ligne(Coul,Lig,Min,Contenu_jeu,Delta),
359 changeContenu(Contenu_jeu,Coul,Lig,Col,Contenu_jeu1),
360 changeContenu(Contenu_jeu1,Coulb,Lig,Colp,Nouv_Contenu_jeu).
362 /* case(Lig,Col,Nouv_Contenu_jeu,Coul),
363 case(Lig,Colp,Nouv_Contenu_jeu,Coulb).*/
367 lancerv(Coul,Contenu_jeu,Nouv_Contenu_jeu):-
369 case(Lig,Col,Contenu_jeu,Coulb),
370 case(Ligp,Col,Contenu_jeu,Coul),
374 aucun_adversaire_col(Coul,Lig,Min,Contenu_jeu,Delta),
376 changeContenu(Contenu_jeu,Coul,Lig,Col,Contenu_jeu1),
377 changeContenu(Contenu_jeu1,Coulb,Ligp,Col,Nouv_Contenu_jeu).
378 /*case(Lig,Col,Nouv_Contenu_jeu,Coul),
379 case(Ligp,Col,Nouv_Contenu_jeu,Coulb).*/
382 /* diag haut droite */
383 lancerd1(Coul,Contenu_jeu,Nouv_Contenu_jeu):-
385 case(Lig,Col,Contenu_jeu,Coulb),
386 case(Ligp,Colp,Contenu_jeu,Coul),
387 Delta is Ligp-Lig -1,
388 Delta is Colp-Col -1,
389 aucun_adversaire_diag1(Coul,Lig,Col,Contenu_jeu,Delta),
391 changeContenu(Contenu_jeu,Coul,Lig,Col,Contenu_jeu1),
392 changeContenu(Contenu_jeu1,Coulb,Ligp,Colp,Nouv_Contenu_jeu).
394 /*case(Lig,Col,Nouv_Contenu_jeu,Coul),
395 case(Ligp,Colp,Nouv_Contenu_jeu,Coulb).*/
401 /* diag haut gauche */
402 lancerd2(Coul,Contenu_jeu,Nouv_Contenu_jeu):-
404 case(Lig,Col,Contenu_jeu,Coulb),
405 case(Ligp,Colp,Contenu_jeu,Coul),
406 Delta is -(Ligp-Lig -1),
407 Delta is Colp-Col -1,
408 aucun_adversaire_diag2(Coul,Lig,Col,Contenu_jeu,Delta),
410 changeContenu(Contenu_jeu,Coul,Lig,Col,Contenu_jeu1),
411 changeContenu(Contenu_jeu1,Coulb,Ligp,Colp,Nouv_Contenu_jeu).
413 /*case(Lig,Col,Nouv_Contenu_jeu,Coul),
414 case(Ligp,Colp,Nouv_Contenu_jeu,Coulb).*/
419 lancer(0,_,Contenu_jeu,Contenu_jeu).
421 lancer(1,Coul,Contenu_jeu,Nouv_Contenu_jeu):-
422 lancerv(Coul,Contenu_jeu,Nouv_Contenu_jeu);
423 lancerh(Coul,Contenu_jeu,Nouv_Contenu_jeu);
424 lancerd1(Coul,Contenu_jeu,Nouv_Contenu_jeu);
425 lancerd2(Coul,Contenu_jeu,Nouv_Contenu_jeu).
429 coup(Coul,Contenu_Jeu,Nouv_Contenu_jeu):-
430 lancer(L1,Coul,Contenu_Jeu,Contenu_jeu1),
431 depl(D1,Coul,Contenu_jeu1,Contenu_jeu2),
432 lancer(L2,Coul,Contenu_jeu2,Contenu_jeu3),
433 depl(D2,Coul,Contenu_jeu3,Contenu_jeu4),
434 lancer(L3,Coul,Contenu_jeu4,Nouv_Contenu_jeu),
447 /************ TODO à affiner **********/
450 valeur(Coul,Conf,1000):-
451 coup(Coul,Conf,Conf2),
452 victoire(Coul,Conf2).
454 valeur(Coul,Conf,T):-
455 maplist(nb_ele(Coul),Conf,L1),
458 maplist(poids_ligne,L1,L2,L3),
464 count(b,Conf,N,M,-10,T),
467 /* pour une ligne de poids X, de rang Y, son poids est N */
474 /*nbre d elements N de la couleur Coul dans la liste L */
476 sublist(ma_couleur(Coul),L,Lp),
487 count(Coul,Conf,N,ValNiveau,Add,Tp):-
489 ValNiveauP is ValNiveau+Add,
493 Tp is T+ValNiveau*Nb,
494 count(Coul,Conf,Np,ValNiveauP,Add,T).
501 nb_ele(Coul,[Coul2|F],N):-
502 not(ma_couleur(Coul,Coul2)),
505 nb_ele(Coul,[Coul2|F],Np):-
506 ma_couleur(Coul,Coul2),
518 calcul_valeur_list(_,[]).
520 calcul_valeur_list(Coul,[D|F]):-
521 test_victoire(Coul,D,V),
523 calcul_valeur_list(Coul,[F]).
527 successeurs(N,Coul,L) :-
528 findall(NP,coup(Coul,N,NP),Lp),
533 choisit la meilleur conf à partir de Conf parmi les susccesseurs
534 alpha est la valeur minimum estimée jusqu'à présent
535 beta est la valeur maximum estimée jusqu'à présent
537 evaluate_and_choose(Coul,[Succ|Succs],Conf,D,Alpha,Beta,Record,MeilleurSuccVal):-
538 joueur_suivant(Coul,Coulp),
539 alpha_beta(Coulp,D,Succ,Alpha,Beta,_,Valeur),
541 cutoff(Coul,Succ,Valeurp,D,Alpha,Beta,Succs,Conf,Record,MeilleurSuccVal).
543 evaluate_and_choose(_,[],_,_,Alpha,_,Record,(Record,Alpha)).
546 /* implantation alpha beta du minimax */
547 alpha_beta(Coul,0,Conf,_,_,_,Valeur) :-
548 valeur(Coul,Conf,Valeur).
550 alpha_beta(Coul,D,Conf,Alpha,Beta,Succ,Valeur) :-
552 successeurs(Conf,Coul,Succs),
556 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]),
557 evaluate_and_choose(Coul,Succs,Conf,D1,Alpha1,Beta1,nil,(Succ,Valeur)).
560 cutoff(_,Succ,Valeur,_,_,Beta,_,_,_,(Succ,Valeur)):-
562 cutoff(Coul,Succ,Valeur,D,Alpha,Beta,Succs,Conf,_Record,MeilleurSuccVal):-
563 Alpha < Value, Value < Beta,
564 evaluate_and_choose(Coul,Succs,Conf,D,Valeur,Beta,Succ,MeilleurSuccVal).
565 cutoff(Coul,_,Valeur,D,Alpha,Beta,Succs,Conf,Record,MeilleurSuccVal) :-
567 evaluate_and_choose(Coul,Succs,Conf,D,Alpha,Beta,Record,MeilleurSuccVal).
572 [A1,A2,A3,A4,A5,A6,A7],
573 [B1,B2,B3,B4,B5,B6,B7],
574 [C1,C2,C3,C4,C5,C6,C7],
575 [D1,D2,D3,D4,D5,D6,D7],
576 [E1,E2,E3,E4,E5,E6,E7],
577 [F1,F2,F3,F4,F5,F6,F7],
578 [G1,G2,G3,G4,G5,G6,G7]],
579 [[A7,A6,A5,A4,A3,A2,A1],
580 [B7,B6,B5,B4,B3,B2,B1],
581 [C7,C6,C5,C4,C3,C2,C1],
582 [D7,D6,D5,D4,D3,D2,D1],
583 [E7,E6,E5,E4,E3,E2,E1],
584 [F7,F6,F5,F4,F3,F2,F1],
585 [G7,G6,G5,G4,G3,G2,G1]]).
609 non_symetrique_de(X,Y):- not(symetrique(X,Y)).
612 filtre_sym([X|T],[X|R]):-
613 sublist(non_symetrique_de(X),T,Ns),
618 tour(Contenu_Jeu, Coul) :-
619 victoire(Coul,Contenu_Jeu).
621 tour(Contenu_Jeu, Coul) :-
622 coup(Coul,Contenu_Jeu,Nouv_Contenu_jeu),
623 victoire(Coul,Nouv_Contenu_jeu).
626 tour(Contenu_Jeu, Coul) :-
627 coup(Coul,Contenu_Jeu,Nouv_Contenu_jeu),
628 joueur_suivant(Coul,Coulp),
629 not(victoire(Coul,Nouv_Contenu_jeu)),
630 tour(Nouv_Contenu_jeu,Coulp).