Prolog Tic-Tac-Toe 井字棋 (框架)

先曬一曬程式。改日解說。

place(.).
player(o).
player(x).
opponent(A, B) :-
	player(A), player(B), A \= B.
pattern([S/N,_,_], S, p1/N).
pattern([_,S/N,_], S, p2/N).
pattern([_,_,S/N], S, p3/N).
pattern([S/_,S/_,S/_], S, p4).
pattern(_, _, p5).
pattern([S/N,T/_,T/_], S, T, p6/N).
pattern([T/_,S/N,T/_], S, T, p7/N).
pattern([T/_,T/_,S/N], S, T, p8/N).
lattice([S/1,S/2,S/3,S/4,S/5,S/6,S/7,S/8,S/9]) :- place(S).
parts([A,B,C,D,E,F,G,H,I], R1, R2, R3, L1, L2, L3, D1, D2) :-
	R1 = [A,B,C], R2 = [D,E,F], R3 = [G,H,I],
	L1 = [A,D,G], L2 = [B,E,H], L3 = [C,F,I],
	D1 = [A,E,I], D2 = [C,E,G].
move([], _, _, []).
move([_/N|T], S, N, [S/N|T]).
move([H/N|T], S, N1, [H/N|T1]) :- N =\= N1, !, move(T, S, N1, T1).
any_pattern([Line|_], Player, Pattern) :-
	pattern(Line, Player, Pattern).
any_pattern([_|Tail], Player, Pattern) :-
	any_pattern(Tail, Player, Pattern).
any_pattern([Line|_], Sym1, Sym2, Pattern) :-
	pattern(Line, Sym1, Sym2, Pattern).
any_pattern([_|Tail], Sym1, Sym2, Pattern) :-
	any_pattern(Tail, Sym1, Sym2, Pattern).
win(Lattice, Player) :-
	parts(Lattice, R1, R2, R3, L1, L2, L3, D1, D2),
	any_pattern([R1,R2,R3,L1,L2,L3,D1,D2], Player, p4).
strategy(Lattice, Player, N, Lattice1) :-
	parts(Lattice, R1, R2, R3, L1, L2, L3, D1, D2),
	place(Place),
	any_pattern([R1,R2,R3,L1,L2,L3,D1,D2], Place, Player, Pattern/N), !,
	(Pattern = p6; Pattern = p7; Pattern = p8),
	move(Lattice, Player, N, Lattice1).
strategy(Lattice, Player, N, Lattice1) :-
	parts(Lattice, R1, R2, R3, L1, L2, L3, D1, D2),
	opponent(Player, Enemy),
	place(Place),
	any_pattern([R1,R2,R3,L1,L2,L3,D1,D2], Place, Enemy, Pattern/N), !,
	(Pattern = p6; Pattern = p7; Pattern = p8),
	move(Lattice, Player, N, Lattice1).
my_turn(N) :- write('My turn: '), write(N), write('.'), nl, nl.
input(X) :- write('Your turn: '), read(X).
input_digit_without_0(X) :- 
	input(X),
	member(X, [1,2,3,4,5,6,7,8,9]), !.
input_digit_without_0(X) :-
	write('Input must be [1-9].'), nl,
	input_digit_without_0(X).
show_off(Lattice) :-
	parts(Lattice, R1, R2, R3, _, _, _, _, _),
	show_off_line(R1),
	show_off_line(R2),
	show_off_line(R3).
show_off_line([]) :- write(']'), nl.
show_off_line([H/_|T]) :- write('['), write(H), show_off_line(T).
turn1(Lattice, Player, Lattice1) :-
	input_digit_without_0(N),
	move(Lattice, Player, N, Lattice1),
	show_off(Lattice1),
	(win(Lattice1, Player) -> write('You win!'), nl, fail;
	    true).
turn2(Lattice, Player, Lattice1) :-
	strategy(Lattice, Player, N, Lattice1), !,
	my_turn(N),
	show_off(Lattice1),
	(win(Lattice1, Player) -> write('My pride!'), nl, fail;
	    true).
turn2(_, _, _) :-
	my_turn('Surrender').
game :-
	lattice(Lattice),
	player(O), opponent(O, X),
	show_off(Lattice),
	turn1(Lattice, O, Lattice1),
	turn2(Lattice1, X, Lattice2), !.
廣告

About 黃耀賢 (Yau-Hsien Huang)

熱愛 Erlang ,並且有相關工作經驗。喜歡程式語言。喜歡邏輯。目前用 Python 工作。
本篇發表於 Prolog。將永久鏈結加入書籤。