:- dynamic
board/1
.
board(no).
player(x).
player(o).
turn(B,x) :- count(B,x,C), count(B,o,C).
turn(B,o) :- count(B,x,Cx), Co is Cx - 1, count(B,o,Co).
win(B,P) :- player(P), row(B,R), tuple_count(R,P,3).
subscript((Item,X,Y),0,Item,(X,Y)).
subscript((Y,Item,X),1,Item,(X,Y)).
subscript((X,Y,Item),2,Item,(X,Y)).
count((R1,R2,R3),P,C) :-
tuple_count(R1, P, C1)
, tuple_count(R2, P, C2)
, tuple_count(R3, P, C3)
, C is C1 + C2 + C3
, !
.
print_winner(B) :- win(B, P), write(P), write(' wins!'),!.
print_winner(_).
print_row((X,Y,Z)) :- write(X), write('|'), write(Y), write('|'), write(Z), nl.
print_board((X,Y,Z)) :-
print_row(X)
, write('-+-+-')
, nl
, print_row(Y)
, write('-+-+-')
, nl
, print_row(Z)
, print_winner((X,Y,Z))
.
tuple_count((P,P,P), P, 3).
tuple_count((P,P,_), P, 2).
tuple_count((P,_,P), P, 2).
tuple_count((_,P,P), P, 2).
tuple_count((P,_,_), P, 1).
tuple_count((_,P,_), P, 1).
tuple_count((_,_,P), P, 1).
tuple_count(_,_,0).
row((Fst,_,_),Fst).
row((_,Snd,_),Snd).
row((_,_,Thd),Thd).
row(((X,_,_),(Y,_,_),(Z,_,_)),(X,Y,Z)).
row(((_,X,_),(_,Y,_),(_,Z,_)),(X,Y,Z)).
row(((_,_,X),(_,_,Y),(_,_,Z)),(X,Y,Z)).
row(((X,_,_),(_,Y,_),(_,_,Z)),(X,Y,Z)).
row(((_,_,X),(_,Y,_),(Z,_,_)),(X,Y,Z)).
can_move(B,(X,Y)) :- \+ win(B,_), subscript(B,Y,R,_), subscript(R,X,' ',_).
do_move(B1,(X,Y),B2) :-
turn(B1,P)
, subscript(B1,Y,R1,Rows)
, subscript(R1,X,' ',Items)
, subscript(R2,X,P,Items)
, subscript(B2,Y,R2,Rows)
.
move(B1,(X,Y),'',B2) :- can_move(B1, (X,Y)), do_move(B1,(X,Y),B2),!.
move(B,_,'cannot move there',B).
start_game :-
B = ((' ', ' ', ' '),(' ', ' ', ' '),(' ', ' ', ' '))
, retract(board(_))
, asserta(board(B))
, print_board(B)
.
move(X,Y) :-
board(B1)
, move(B1,(X,Y),M,B2)
, write(M)
, nl
, retract(board(_))
, asserta(board(B2))
, print_board(B2)
.
Comments
0 B
|👍
/👎
0 B
|👍
/👎