Skip to content

Instantly share code, notes, and snippets.

@stephenroller
Created July 19, 2012 13:06
Show Gist options
  • Save stephenroller/3143782 to your computer and use it in GitHub Desktop.
Save stephenroller/3143782 to your computer and use it in GitHub Desktop.
Prolog Tic-Tac-Toe
%
% TIC-TAC-TOE
%
% a | b | c
% --+---+---
% d | e | f
% --+---+---
% g | h | i
%
:- dynamic(move/2).
human(x).
computer(o).
win_(a, b, c).
win_(d, e, f).
win_(g, h, i).
win_(a, d, g).
win_(b, e, h).
win_(c, f, i).
win_(a, e, i).
win_(c, e, g).
win(A, B, C) :-
A \= B, A \= C, B \= C,
(
win_(A, B, C), !;
win_(A, C, B), !;
win_(B, A, C), !;
win_(B, C, A), !;
win_(C, A, B), !;
win_(C, B, A), !
).
filled :-
move(a, _), move(b, _), move(c, _),
move(d, _), move(e, _), move(f, _),
move(g, _), move(h, _), move(i, _).
winner(Winner) :-
move(X, Winner),
move(Y, Winner),
move(Z, Winner),
win(X, Y, Z).
loser(Loser) :-
winner(Winner),
switch_turns(Winner, Loser).
switch_turns(Old, New) :-
member(Old, [o,x]),
member(New, [o,x]),
Old \= New.
tie :-
winner(_),!,fail;
filled.
game_over :-
filled; winner(_).
free(Square) :-
member(Square, [a,b,c,d,e,f,g,h,i]),
\+ move(Square, _).
enter(Square, Turn) :-
human(Turn),
repeat,
write('Your move: '),
read(Input),
(
Input = 'exit',
halt
;
member(Input, [a,b,c,d,e,f,g,h,i]),
free(Square),
Square = Input
;
move(Input, _),
write('This move is already taken'), nl,
fail
;
\+ member(Input, [a,b,c,d,e,f,g,h,i]),
write('Please enter in a square'),nl,
fail
).
enter(Square, Turn) :- % Prefer a winning move
computer(Turn),
free(Square),
move(X, Turn),
move(Y, Turn),
win(Square, X, Y),
!.
enter(Square, Turn) :- % Block a winning move if needed
computer(Turn),
switch_turns(Turn, Op),
move(X, Op),
move(Y, Op),
win(Square, X, Y),
free(Square),
!.
enter(Square, Turn) :- % But take a two-in-row if I can
computer(Turn),
move(X, Turn),
free(Square),
free(Y),
win(Square, X, Y),
!.
enter(Square, Turn) :- % prefer the middle
computer(Turn),
free(e),
Square = e,
!.
enter(Square, Turn) :- % Just make any move if it doesn't matter.
computer(Turn),
free(Square),
free(X),
free(Y),
win(Square, X, Y),
!.
text(Square, Text) :-
move(Square, Text),!;
Text = ' '.
draw :-
text(a, A),text(b, B),text(c, C),
text(d, D),text(e, E),text(f, F),
text(g, G),text(h, H),text(i, I),
write(' '),write(A),write(' | '),write(B),write(' | '),write(C),nl,
write('---+---+---'),nl,
write(' '),write(D),write(' | '),write(E),write(' | '),write(F),nl,
write('---+---+---'),nl,
write(' '),write(G),write(' | '),write(H),write(' | '),write(I),nl,
nl.
play :-
retractall(move(_, _)), % clear the game so we can play again
play(x).
play(_) :- % if the game is over, say so and restart.
(
tie, draw, write('Cat\'s game'), nl
;
winner(Winner), draw, write(Winner), write(' won the game.'), nl
),
!.
play(Turn) :-
(human(Turn), draw; computer(Turn)),
enter(Square, Turn),
!,
assertz(move(Square, Turn)),
switch_turns(Turn, New),
play(New).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment