Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
208
Task/Tic-tac-toe/Prolog/tic-tac-toe-1.pro
Normal file
208
Task/Tic-tac-toe/Prolog/tic-tac-toe-1.pro
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
:- use_module('min-max.pl').
|
||||
|
||||
:-dynamic box/2.
|
||||
:- dynamic tic_tac_toe_window/1.
|
||||
|
||||
% Computer begins.
|
||||
tic-tac-toe(computer) :-
|
||||
V is random(9),
|
||||
TTT = [_,_,_,_,_,_ ,_,_,_],
|
||||
nth0(V, TTT, o),
|
||||
display_tic_tac_toe(TTT).
|
||||
|
||||
% Player begins
|
||||
tic-tac-toe(me) :-
|
||||
TTT = [_,_,_,_,_,_ ,_,_,_],
|
||||
display_tic_tac_toe(TTT).
|
||||
|
||||
|
||||
display_tic_tac_toe(TTT) :-
|
||||
retractall(box(_,_)),
|
||||
retractall(tic_tac_toe_window(_)),
|
||||
new(D, window('Tic-tac-Toe')),
|
||||
send(D, size, size(170,170)),
|
||||
X = 10, Y = 10,
|
||||
display(D, X, Y, 0, TTT),
|
||||
assert(tic_tac_toe_window(D)),
|
||||
send(D, open).
|
||||
|
||||
display(_, _, _, _, []).
|
||||
|
||||
display(D, X, Y, N, [A,B,C|R]) :-
|
||||
display_line(D, X, Y, N, [A,B,C]),
|
||||
Y1 is Y+50,
|
||||
N3 is N+3,
|
||||
display(D, X, Y1, N3, R).
|
||||
|
||||
|
||||
display_line(_, _, _, _, []).
|
||||
display_line(D, X, Y, N, [C|R]) :-
|
||||
( nonvar(C)-> C1 = C; C1 = ' '),
|
||||
new(B, tic_tac_toe_box(C1)),
|
||||
assertz(box(N, B)),
|
||||
send(D, display, B, point(X, Y)),
|
||||
X1 is X + 50,
|
||||
N1 is N+1,
|
||||
display_line(D, X1, Y, N1, R).
|
||||
|
||||
|
||||
|
||||
% class tic_tac_toe_box
|
||||
% display an 'x' when the player clicks
|
||||
% display an 'o' when the computer plays
|
||||
:- pce_begin_class(tic_tac_toe_box, box, "Graphical window with text").
|
||||
|
||||
variable(mess, any, both, "text to display").
|
||||
|
||||
initialise(P, Lbl) :->
|
||||
send(P, send_super, initialise),
|
||||
send(P, slot, mess, Lbl),
|
||||
WS = 50, HS = 50,
|
||||
send(P, size, size(WS,HS)),
|
||||
send(P, recogniser,
|
||||
handler_group(new(click_gesture(left,
|
||||
'',
|
||||
single,
|
||||
message(@receiver, my_click))))).
|
||||
|
||||
% the box is clicked
|
||||
my_click(B) :->
|
||||
send(B, set_val, x),
|
||||
send(@prolog, play).
|
||||
|
||||
% only works when the box is "free"
|
||||
set_val(B, Val) :->
|
||||
get(B, slot, mess, ' '),
|
||||
send(B, slot, mess, Val),
|
||||
send(B, redraw),
|
||||
send(B, flush).
|
||||
|
||||
|
||||
% redefined method to display custom graphical objects.
|
||||
'_redraw_area'(P, A:area) :->
|
||||
send(P, send_super, '_redraw_area', A),
|
||||
%we display the text
|
||||
get(P, slot, mess, Lbl),
|
||||
new(Str1, string(Lbl)),
|
||||
get_object(P, area, area(X,Y,W,H)),
|
||||
send(P, draw_box, X, Y, W, H),
|
||||
send(P, draw_text, Str1,
|
||||
font(times, normal, 30),
|
||||
X, Y, W, H, center, center).
|
||||
|
||||
:- pce_end_class.
|
||||
|
||||
play :-
|
||||
numlist(0, 8, L),
|
||||
maplist(init, L, TTT),
|
||||
finished(x, TTT, Val),
|
||||
( Val = 2 -> send(@display, inform,'You win !'),
|
||||
tic_tac_toe_window(D),
|
||||
send(D, destroy)
|
||||
; ( Val = 1 -> send(@display, inform,'Draw !'),
|
||||
tic_tac_toe_window(D),
|
||||
send(D, destroy)
|
||||
; next_move(TTT, TT1),
|
||||
maplist(display, L, TT1),
|
||||
finished(o, TT1, V),
|
||||
( V = 2 -> send(@display, inform,'I win !'),
|
||||
tic_tac_toe_window(D),
|
||||
send(D, destroy)
|
||||
; ( V = 1 -> send(@display, inform,'Draw !'),
|
||||
tic_tac_toe_window(D),
|
||||
send(D, destroy)
|
||||
; true)))).
|
||||
|
||||
|
||||
% use minmax to compute the next move
|
||||
next_move(TTT, TT1) :-
|
||||
minimax(o, 0, 1024, TTT, _V1- TT1).
|
||||
|
||||
|
||||
% we display the new board
|
||||
display(I, V) :-
|
||||
nonvar(V),
|
||||
box(I, V1),
|
||||
send(V1, set_val, V).
|
||||
|
||||
display(_I, _V).
|
||||
|
||||
% we create the board for minmax
|
||||
init(I, V) :-
|
||||
box(I, V1),
|
||||
get(V1, slot, mess, V),
|
||||
V \= ' '.
|
||||
|
||||
init(_I, _V).
|
||||
|
||||
% winning position for the player P ?
|
||||
winned(P, [A1, A2, A3, A4, A5, A6, A7, A8, A9]) :-
|
||||
(is_winning_line(P, [A1, A2, A3]);
|
||||
is_winning_line(P, [A4, A5, A6]);
|
||||
is_winning_line(P, [A7, A8, A9]);
|
||||
is_winning_line(P, [A1, A4, A7]);
|
||||
is_winning_line(P, [A2 ,A5, A8]);
|
||||
is_winning_line(P, [A3, A6, A9]);
|
||||
is_winning_line(P, [A1, A5, A9]);
|
||||
is_winning_line(P, [A3, A5, A7])).
|
||||
|
||||
|
||||
is_winning_line(P, [A, B, C]) :-
|
||||
nonvar(A), A = P,
|
||||
nonvar(B), B = P,
|
||||
nonvar(C), C = P.
|
||||
|
||||
% Winning position for the player
|
||||
eval(Player, Deep, TTT, V) :-
|
||||
winned(Player, TTT),
|
||||
( Player = o -> V is 1000 - 50 * Deep; V is -1000+ 50 * Deep).
|
||||
|
||||
% Loosing position for the player
|
||||
eval(Player, Deep, TTT, V) :-
|
||||
select(Player, [o,x], [Player1]),
|
||||
winned(Player1, TTT),
|
||||
( Player = x -> V is 1000 - 50 * Deep; V is -1000+ 50 * Deep).
|
||||
|
||||
% Draw position
|
||||
eval(_Player, _Deep, TTT, 0) :-
|
||||
include(var, TTT, []).
|
||||
|
||||
|
||||
% we fetch the free positions of the board
|
||||
possible_move(TTT, LMove) :-
|
||||
new(C, chain),
|
||||
forall(between(0,8, I),
|
||||
( nth0(I, TTT, X),
|
||||
( var(X) -> send(C, append, I); true))),
|
||||
chain_list(C, LMove).
|
||||
|
||||
% we create the new position when the player P clicks
|
||||
% the box "N"
|
||||
assign_move(P, TTT, N, TT1) :-
|
||||
copy_term(TTT, TT1),
|
||||
nth0(N, TT1, P).
|
||||
|
||||
% We fetch all the possible boards obtained from board TTT
|
||||
% for the player P
|
||||
get_next(Player, Deep, TTT, Player1, Deep1, L):-
|
||||
possible_move(TTT, LMove),
|
||||
select(Player, [o,x], [Player1]),
|
||||
Deep1 is Deep + 1,
|
||||
maplist(assign_move(Player, TTT), LMove, L).
|
||||
|
||||
|
||||
% The game is over ?
|
||||
% Player P wins
|
||||
finished(P, TTT, 2) :-
|
||||
winned(P, TTT).
|
||||
|
||||
% Draw
|
||||
finished(_P, TTT, 1) :-
|
||||
include(var, TTT, []).
|
||||
|
||||
% the game is not over
|
||||
finished(_P, _TTT, 0) .
|
||||
|
||||
% minmax must knows when the computer plays
|
||||
% (o for ordinateur in French)
|
||||
computer(o).
|
||||
26
Task/Tic-tac-toe/Prolog/tic-tac-toe-2.pro
Normal file
26
Task/Tic-tac-toe/Prolog/tic-tac-toe-2.pro
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
:- module('min-max.pl', [minimax/5]).
|
||||
|
||||
% minimax(Player, Deep, MaxDeep, B, V-B)
|
||||
% @arg1 : current player at this level
|
||||
% @arg2 : current level of recursion
|
||||
% @arg3 : max level of recursion (in this version of the game no use : set to 1024 !)
|
||||
% @arg4 : current board
|
||||
% @arg5 : B is the evaluation of the board, the result is V-B to know the new board
|
||||
|
||||
% Here we get an evaluation
|
||||
minimax(Player, Deep, MaxDeep, B, V-B) :-
|
||||
( eval(Player, Deep, B, V) -> true
|
||||
; % in this version of the game this second division always fails
|
||||
( Deep > MaxDeep -> V is random(1000) - 1000)).
|
||||
|
||||
% here we must compute all the possible moves to know the evaluation of the board
|
||||
minimax(Player, Deep, MaxDeep, B, V) :-
|
||||
get_next(Player, Deep, B, Player1, Deep1, L),
|
||||
maplist(minimax(Player1, Deep1, MaxDeep), L, LV),
|
||||
maplist(lie, L, LV, TLV),
|
||||
sort(TLV, SLVTmp),
|
||||
( computer(Player) -> reverse(SLVTmp, SLV); SLV = SLVTmp),
|
||||
SLV = [V | _R].
|
||||
|
||||
|
||||
lie(TTT, V-_, V-TTT).
|
||||
Loading…
Add table
Add a link
Reference in a new issue