Information Technology Reference
In-Depth Information
Figure 10.7.
Playing an entire game
playuser.pl
% 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).
Apart from printing various pieces of information, the way this program works is
that starting in the initial state, it uses
play_from
to obtain a next move, check that it
is legal, move to the next state, and repeat until the game is over.
The
get_move
predicate is used to obtain the next move. In the case where the
player is not the user (clauses 1, 2, and 3), this is done by first trying to find a winning
move, then failing this, a nonlosing move, and then failing this, returning any legal
move (and hoping for a mistake from the opponent).
The last clause for
get_move
handles the case when the next move needs to come
from the user. A message is printed requesting a move, and a special Prolog predicate
called
read
is used to obtain the move. (The details of
read
are not important here.
Basically, it is the opposite of
write
: instead of producing output at the terminal, it
consumes input provided at the terminal.)
An example of using
play_user
with tic-tac-toe appears in figure 10.8. In this case,
the computer plays both
X
and
O
. Not too surprisingly, although both players play
perfectly, the game ends in a tie. Since
play_user
always returns the
first
move it
finds, it will always play the same way. (To get some variation, one would need to
randomly
choose among the equally good moves.)