Skip to content

Instantly share code, notes, and snippets.

@Steffo99
Last active July 18, 2021 14:26
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save Steffo99/e6a8271f193303f40ddac4df2a366383 to your computer and use it in GitHub Desktop.
A tic-tac-toe enumerator in Prolog
/**
* Usage:
*
* play(A, "X", "O"). % Gets boards where X wins and O loses
* play(A, "O", "X"). % Gets boards where O wins and X loses
* play([[_,_,_], [_,"X",_], [_,_,_]], "X", "O") % Finds winning boards for X with that starting condition
* play([[_,_,_], [_,"X",_], [_,_,_]], "O", "X") % Finds winning boards for O with that starting condition
* ...
*/
winning_line([A, B, C], PLAYER) :-
A = B,
A = C,
A = PLAYER.
winning_row([[A, B, C], [D, E, F], [G, H, I]], PLAYER) :-
winning_line([A, B, C], PLAYER);
winning_line([D, E, F], PLAYER);
winning_line([G, H, I], PLAYER).
winning_col([[A, B, C], [D, E, F], [G, H, I]], PLAYER) :-
winning_line([A, D, G], PLAYER);
winning_line([B, E, H], PLAYER);
winning_line([C, F, I], PLAYER).
winning_dia([[A, _, C], [_, E, _], [G, _, I]], PLAYER) :-
winning_line([A, E, I], PLAYER);
winning_line([C, E, G], PLAYER).
winning_board(BOARD, PLAYER) :-
winning_row(BOARD, PLAYER);
winning_col(BOARD, PLAYER);
winning_dia(BOARD, PLAYER).
count_cell(CELL, X, O) :-
CELL = "X",
X = 1, O = 0;
CELL = "O",
X = 0, O = 1;
CELL = " ",
X = 0, O = 0.
count_line([A, B, C], X, O) :-
count_cell(A, X1, O1),
count_cell(B, X2, O2),
count_cell(C, X3, O3),
X is X1 + X2 + X3,
O is O1 + O2 + O3.
count_board([A, B, C], X, O) :-
count_line(A, X1, O1),
count_line(B, X2, O2),
count_line(C, X3, O3),
X is X1 + X2 + X3,
O is O1 + O2 + O3.
valid_board(BOARD) :-
count_board(BOARD, X, O),
O = X;
count_board(BOARD, X, O),
O = X + 1.
play(BOARD, WIN, LOSE) :-
valid_board(BOARD),
winning_board(BOARD, WIN),
\+ winning_board(BOARD, LOSE).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment