% nacteni:
/* ['7.1_11.pl']. */

% minimax( Pos, BestSucc, Val ):
% Pos is a position , Val is its minimax value ;
% best move from Pos leads to position BestSucc
minimax(Pos, BestSucc, Val) :-
    moves(Pos, PosList), ! ,   % Legal moves in Pos produce PosList
    best(PosList, BestSucc, Val)
    ;
    staticval( Pos, Val ).     % Pos has no successors : evaluate statically
    
best([Pos], Pos, Val) :-
    minimax(Pos,_, Val), ! .
best([Pos1 | PosList], BestPos, BestVal) :-
    minimax(Pos1,_, Val1),
    best(PosList, Pos2, Val2),
    betterof(Pos1, Val1, Pos2, Val2, BestPos, BestVal).
betterof(Pos0, Val0, _Pos1, Val1, Pos0, Val0) :-    % Pos0 better than Pos1
    min_to_move(Pos0),				    % MIN to move in Pos0
    Val0 > Val1, !				    % MAX prefers the greater value
    ;
    max_to_move(Pos0),                              % MAX to move in Pos0
    Val0 < Val1, ! .				    % MIN prefers the lesser value
betterof(_Pos0, _Val0, Pos1, Val1, Pos1, Val1).	    % Otherwise Pos1 better than Pos0
