[[0,2,1,0,1,2,0,0,0],[1,1,2,2,1,0,0,1,2],[0,1,2,0,1,2,2,1,1],[1,0,1,2,0,0,1,1,1],[0,1,1,0,2,2,1,2,0],[2,1,2,1,1,2,0,0,1],[0,2,1,2,1,0,0,2,0],[2,1,0,2,2,1,1,0,0],[1,0,0,1,0,1,2,2,2]]
...est équivalente à la grille suivante:
playableGrid(N) :- getGridsState(State), allowedGrids(Allowed,State), member(N, Allowed).
playableCell(N, M) :- playableGrid(N), gameField(D), nth1(N, D, G), nth1(M, G, 0).
nextPlayer(X) :- lastMove(_,_,-1), X is 1.
nextPlayer(X) :- lastMove(_,_,P), P > 0, X is 3-P.
playMove(N,M,J) :- gameField(D), /* ... */
retract(gameField(D)), assert(gameField(NewD)),
lastMove(A,B,C), retract(lastMove(A,B,C)),
asserta(lastMove(N,M,J)).
Chaque IA implémente un prédicat nextMove donnant le coup à jouer.
input.pl
:- ['ai.pl'].
:- asserta(gameField([[1, 0, 2, 0, 1, 2, 0, 0, 2], [1, 2, 1, 2, 2, 2, 2, 0, 0], [2, 1, 1, 2, 0, 0, 2, 0, 0], [1, 1, 1, 2, 0, 0, 0, 2, 0], [1, 1, 0, 2, 2, 0, 1, 0, 2], [1, 1, 2, 1, 1, 2, 2, 1, 0], [1, 1, 1, 0, 1, 0, 0, 2, 2], [1, 1, 1, 2, 2, 0, 0, -1, 1], [1, 1, 1, 0, 0, 2, 0, 2, 0]])).
:- asserta(lastMove(5, 5, 2)).
[[1,0,2,0,1,2,0,0,2],[1,2,1,2,2,2,2,0,0],[2,1,1,2,0,0,2,0,0],[1,1,1,2,0,0,0,2,0],[1,1,1,2,2,0,1,0,2],[1,1,2,1,1,2,2,1,0],[1,1,1,0,1,0,0,2,2],[1,1,1,2,2,0,0,-1,1],[1,1,1,0,0,2,0,2,0]] [] [2,2,2,1,1,1,1,1,1] [5,3,1] spoilWinWeight(N, M, J, 32) :- NJ is 3 - J, isWinningMove(N, M, NJ).
spoilWinWeight(_, _, _, 0).
avoidWinWeight(M, J, 64) :- NJ is 3 - J, not(isWinningMove(M, _, NJ)).
avoidWinWeight(_, _, 0). Son principe :
Etudier les victoires des parties jouées.
L'objectif :
Ne pas jouer de coups faisant gagner l'adversaire.
La solution :
Cataloguer les coups faisant perdre les parties, et ne pas les rejouer si on est dans une situation identique.

Chaque IA a une stratégie de jeu différente:


