%"Èíòåëëåêòóàëüíûå" êðåñòèêè-íîëèêè íà Java Internet Prolog
%êîìïüþòåð óìååò èãðàòü è çà êðåñòèêè, è çà 0
% (Ñ) À.À. Òþãàøåâ 2014

%Êëåòêè ïîëÿ çàäàþòñÿ êîîðäèíàòàìè, íàïèìåð, [3,1] - ïðàâûé âåðõíèé óãîë 
%ñíà÷àëà íîìåð âåðòèêàëè!
%   1     2     3
%1     |      |      
%---------------------
%2     |      |     
%---------------------
%3     |      |

%âñïîìîãàòåëüíûé ïðåäèêàò - îïðåäåëÿåò ïóñòîòó ïîëÿ
free(X):-p(-,X).

%âñïîìîãàòåëüíûé ïðåäèêàò - îïðåäåëÿåò, ÷åì èãðàåò ñîïåðíèê
partner(0,x).
partner(x,0).

%âñïîìîãàòåëüíûé ïðåäèêàò - äîïîëíåíèå äî çàïîëíåíèÿ ïîëíîãî ñïèñêà êîîðäèíàò [1,2,3] íà ãåíåðàòîðå âñåõ ïåðåñòàíîâîê ýëåìåíòîâ òðîåê
%ò.å. äëÿ [1,X,2]  äàåò X=3, äëÿ [1,2,X] - X=3, äëÿ [X,2,3] - 1, è òàê äàëåå 
dop(X):-permutation([1,2,3],X).

%÷òî òàêîå "íà îäíîé ëèíèè"
same_line(S):-glav_diagonal(L),permutation(S,L). 
same_line(S):-pob_diagonal(L),permutation(S,L). 
same_line(S):-vertikal(L),permutation(S,L).
same_line(S):-horizontal(L),permutation(S,L).

%ãëàâíàÿ è ïîáî÷íàÿ äèàãîíàëè, ãîðèçîíòàëü, âåðòèêàëü
glav_diagonal([[1,1],[2,2],[3,3]]).
pob_diagonal([[3,1],[2,2],[1,3]]).
horizontal([[P,Y],[K,Y],[L,Y]]):-dop([P,K,L]),dop([Y,_,_]).
vertikal([[X,P],[X,K],[X,L]]):-dop([P,K,L]),dop([X,_,_]).

%========================================================== ÎÑÍÎÂÍÀß ËÎÃÈÊÀ ÈÃÐÛ - ïðåäèêàò hod (×åì,Êóäà) íàïðèìåð Hod(x,[3,1]).
%ïîðÿäîê ïðåäèêàòîâ hodl(D,P) èìååò çíà÷åíèå, èñïîëüçóåòñÿ îòñå÷åíèå ! ïîñëå âûáîðà õîäà äëÿ îòáðàñûâàíèÿ íèæåñòîÿùèõ

%------------------ Ïåðâûì äåëîì ïûòàåìñÿ âûèãðàòü, çàòåì íå ïðîèãðàòü  
hod(D,P):-free(P),try_win(D,P),!.
%----- íå ïðîèãðàé
hod(D,P):-free(P),not_lose(D,P),!.

%----- Åñëè óæå åñòü äâà îäèíàêîâûõ íà îäíîé ëèíèè -> äåëàåì õîä, ëèáî çàâåðøàþùèé çàïîëíåíèå ëèíèè, ëèáî ìåøàþùèé, åñëè ñòîÿò çíàêè ïðîòèâíèêà
try_win(D,P):-same_line([X,Y,P]),p(D,X),p(D,Y),not(free(X)),!.
not_lose(O,P):-same_line([X,Y,P]),p(D,X),p(D,Y),partner(O,D),!.

%--------------------------------- Ñëåäóþùèé ïî ïðèîðèòåòíîñòè õîä - ïîñòàâèòü âèëêó --------------------------------------------------------
hod(D,P):-free(P),try_attack(D,P),!.
%---------------------------- âèëêà îáðàçóåòñÿ åñëè ñòàíåò ïîñëå õîäà äâà îäèíàêîâûõ çíàêà íà îäíîé ëèíèè, íå áëîêèðîâàíà àòàêà, è åùå ïî îäíîé ëèíèè - òî æå ñàìîå
try_attack(D,X):-same_line([X,P,M]),same_line([X,K,L]),p(D,P),p(D,K),free(M),free(L),P\=K,M\=L,!.

%Åñëè íè÷åãî âûøå íå ïîäîøëî 
%------------- âñïîìîãàòåëüíàÿ ëîãèêà äëÿ õîäîâ íà÷àëà èãðû
ugol([3,3]). ugol([1,1]). ugol([1,3]).

%ñàìûé ñèëüíûé ïåðâûé õîä - â [3,1] 
hod(_,[3,1]):-free([3,1]),!. %è êðåñòèêàìè, è íîëèêàìè è äîñòóïíîñòü ïîëÿ [3,1]  ìîæíî îòäåëüíî íå ïðîâåðÿòü ;-)
hod(0,[2,2]):-free([2,2]),!.
hod(x,U):-free(U),glav_diagonal([P,L,U]),p(0,L),p(x,P),!.
hod(x,U):-free(U),pob_diagonal([P,L,U]),p(0,L),p(x,P),!.
hod(x,[2,2] ):-free([2,2] ),p(0,O),not(ugol(O)),!.
hod(x,X):-free(X),p(0,O),ugol(O),ugol(X),!.
hod(0,[2,1] ):-free([2,1] ),p(0,[2,2] ),!.
hod(0,O):-free(O),ugol(O),p(x,[2,2] ),!.

%èíà÷å - â ïåðâóþ ïîïàâøóþñÿ ñëó÷àéíóþ êëåòêó 
hod(D,P):-free(P),!.
