% This general game player needs these predicates to be defined: % - player(Player) % - game_over(State,Player,Winner) % - legal_move(BeforeState,Player,Move,AfterState) % label(S,P,W): state S with player P to move is labeled winner W. label(S,P,W) :- game_over(S,P,W). label(S,P,P) :- win_move(S,P,_). label(S,P,neither) :- \+ win_move(S,P,_), tie_move(S,P,_). label(S,P,Q) :- opp(P,Q), \+ tie_move(S,P,_), \+ game_over(S,P,_). % win_move(S,P,M): P can win by making move M. win_move(S,P,M) :- \+ game_over(S,P,_), opp(P,Q), legal_move(S,P,M,New), label(New,Q,P). % tie_move(S,P,M): P can avoid losing by making move M. tie_move(S,P,M) :- \+ game_over(S,P,_), opp(P,Q), legal_move(S,P,M,New), \+ label(New,Q,Q). opp(P,Q) :- player(P), player(Q), \+ P=Q. player(x). player(o). % This is the tic-tac-toe game. initial_state([-,-,-,-,-,-,-,-,-],x). % x moves first. game_over(S,_,Q) :- three_in_row(S,Q). % A winner game_over(S,_,neither) :- \+ legal_move(S,_,_,_). % A tie three_in_row([P,P,P,_,_,_,_,_,_],P) :- player(P). three_in_row([_,_,_,P,P,P,_,_,_],P) :- player(P). three_in_row([_,_,_,_,_,_,P,P,P],P) :- player(P). three_in_row([P,_,_,P,_,_,P,_,_],P) :- player(P). three_in_row([_,P,_,_,P,_,_,P,_],P) :- player(P). three_in_row([_,_,P,_,_,P,_,_,P],P) :- player(P). three_in_row([P,_,_,_,P,_,_,_,P],P) :- player(P). three_in_row([_,_,P,_,P,_,P,_,_],P) :- player(P). legal_move([-,B,C,D,E,F,G,H,I],P,1,[P,B,C,D,E,F,G,H,I]). legal_move([A,-,C,D,E,F,G,H,I],P,2,[A,P,C,D,E,F,G,H,I]). legal_move([A,B,-,D,E,F,G,H,I],P,3,[A,B,P,D,E,F,G,H,I]). legal_move([A,B,C,-,E,F,G,H,I],P,4,[A,B,C,P,E,F,G,H,I]). legal_move([A,B,C,D,-,F,G,H,I],P,5,[A,B,C,D,P,F,G,H,I]). legal_move([A,B,C,D,E,-,G,H,I],P,6,[A,B,C,D,E,P,G,H,I]). legal_move([A,B,C,D,E,F,-,H,I],P,7,[A,B,C,D,E,F,P,H,I]). legal_move([A,B,C,D,E,F,G,-,I],P,8,[A,B,C,D,E,F,G,P,I]). legal_move([A,B,C,D,E,F,G,H,-],P,9,[A,B,C,D,E,F,G,H,P]). % play_user(U): play entire game, getting moves for U from terminal. play_user(U) :- initial_state(S,P), write('The first player is '), write(P), write(' and the initial state is '), write_state(S), play_from(S,P,U). % play_from(S,P,U): player P plays from state S with user U. play_from(S,P,_) :- % Is the game over? game_over(S,P,W), write('-------- The winner is '), write(W). play_from(S,P,U) :- % Continue with next move. opp(P,Q), get_move(S,P,M,U), legal_move(S,P,M,New), write('Player '), write(P), write(' chooses move '), write(M), write(' and the new state is '), write_state(New), play_from(New,Q,U). write_state(S) :- nl, write(' '), write(S), nl. % Get the next move either from the user or from gameplayer.pl. get_move(S,P,M,U) :- \+ P=U, win_move(S,P,M). % Try to win. get_move(S,P,M,U) :- \+ P=U, tie_move(S,P,M). % Try to tie. get_move(S,P,M,U) :- \+ P=U, legal_move(S,P,M,_). % Do anything. get_move(_,P,M,P) :- write('Enter user move (then a period): '), read(M).