%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% The "calcio" multiagent domain %%%% %%%% by DFP - 2010 %%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% PG, 18/11/2010 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% ********** %%% %%% ** X O ** %%% %%% ** ** %%% %%% %%% X @ %%% %%% Y axis %%% ** ** %%% %%% %%% ** X O ** %%% %%% 0..4 %%% ********** %%% %%%%%%%%%%%%%%%%%% %%% X axis 0..7 %%% %%% Teams team(black). team(white). num(1). num(2). num(3). door(white,0,2). door(black,7,2). color(black,1). color(white,0). %%% Agents (black -> X, white -> O) %%% If they have ball: Y and @. agent(player(T,X)) :- team(T),num(X). %%% Agent's ordering (to avoid symmetries) ord(player(white,A),player(black,B)) :- num(A), num(B). ord(player(T,A),player(T,B)) :- team(T),num(A), num(B), A < B. %%% Admissible directions and corresponding offsets delta(nw,-1,1). delta(n,0,1). delta(ne,1,1). delta( w,-1,0). delta(e,1,0). delta(sw,-1,-1). delta(s,0,-1). delta(se,1,-1). direction(D) :- delta(D,_,_). %%% Admissible kick strength power(X) :- interval(X,1,2). %%%%%% FLUENTS fluent(x(ball) , 0,7). fluent(y(ball) , 0,4). fluent(x(A), 1,6) :- agent(A). fluent(y(A), 0,4) :- agent(A). fluent(hasball(A),0,1) :- agent(A). fluent(win(T), 0,1) :- team(T). %%% Possible actions: %%% - move (like a chess king) %%% - kick (the ball goes like a queen, for F steps) %action([A],move(D)) :- agent(A),direction(D). %action([A],kick(D,F)) :- agent(A),direction(D),power(F). %%%%% Only white team plays action([player(white,A)],move(D)) :- agent(player(white,A)),direction(D). action([player(white,A)],kick(D,F)) :- agent(player(white,A)),direction(D),power(F). %%% Executability conditions %%% The player cannot exit, cannot enter in door executable([A],move(D),[1 leq x(A)+DX, x(A)+DX leq 6, 0 leq y(A)+DY, y(A)+DY leq 4]) :- action([A],move(D)), delta(D,DX,DY). %%% The ball cannot exit executable([A],kick(D,F),[hasball(A) gt 0, 1 leq x(A)+DX*F, x(A)+DX*F leq 6, 0 leq y(A)+DY*F, y(A)+DY*F leq 4]) :- action([A],kick(D,F)),delta(D,DX,DY). %%% But can enter the proper door executable([player(TEAM,N)],kick(D,F),[hasball(player(TEAM,N)) gt 0, pair(x(player(TEAM,N))+DX*F, y(player(TEAM,N))+DY*F) eq pair(X,Y)]) :- action([player(TEAM,N)],kick(D,F)),delta(D,DX,DY), door(TEAM,X,Y). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Effects of move: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% causes(pair(x(A),y(A)) eq pair(x(A)^(-1)+DX, y(A)^(-1)+DY), [actocc([A],move(D))]) :- action([A],move(D)), delta(D,DX,DY). causes(pair(x(ball),y(ball)) eq pair(x(A)^(-1)+DX, y(A)^(-1)+DY), [actocc([A],move(D)),hasball(A) eq 1]) :- action([A],move(D)), delta(D,DX,DY). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Effects of Kick: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Once agent A has kicked, he doesn't have the ball anymore causes(hasball(A) eq 0,[actocc([A],kick(D,F))]) :- action([A],kick(D,F)). %%% Handling of passage and ball capture %%% If an agent is in the reached position, he has the ball %%% unless another agent intercepts the ball one step before causes(pair(x(ball),y(ball)) eq pair(x(Sender)^(-1) + DX,y(Sender)^(-1) + DY), [actocc([Sender],kick(D,1))]) :- action([Sender],kick(D,1)), delta(D,DX,DY). %%% Note the forward reference. It simplifies a lot the encoding. causes(pair(x(ball),y(ball)) eq pair(x(Sender)^(-1) +DX,y(Sender)^(-1) +DY), [actocc([Sender],kick(D,2)), pair(x(Receiver)^1, y(Receiver)^1 ) eq pair(x(Sender) + DX, y(Sender) + DY)]) :- action([Sender],kick(D,2)), agent(Receiver), neq(Sender,Receiver), delta(D,DX,DY). %%%% In case it has not been intercepted the ball executes a step of 2: causes(pair(x(ball),y(ball)) eq pair(x(Sender)^(-1)+2*DX,y(Sender)^(-1)+2*DY), [actocc([Sender],kick(D,2)), pair(x(player(white,1)),y(player(white,1)))^1 neq pair(x(Sender)+DX,y(Sender)+DY), pair(x(player(white,2)),y(player(white,2)))^1 neq pair(x(Sender)+DX,y(Sender)+DY), pair(x(player(white,3)),y(player(white,3)))^1 neq pair(x(Sender)+DX,y(Sender)+DY), pair(x(player(black,1)),y(player(black,1)))^1 neq pair(x(Sender)+DX,y(Sender)+DY), pair(x(player(black,2)),y(player(black,2)))^1 neq pair(x(Sender)+DX,y(Sender)+DY), pair(x(player(black,3)),y(player(black,3)))^1 neq pair(x(Sender)+DX,y(Sender)+DY) ]) :- action([Sender],kick(D,2)), delta(D,DX,DY). %%% Ball reception caused([pair(x(ball),y(ball)) eq pair(x(Receiver),y(Receiver))], hasball(Receiver) eq 1) :- agent(Receiver). caused([pair(x(ball),y(ball)) neq pair(x(Receiver),y(Receiver))], hasball(Receiver) eq 0) :- agent(Receiver). %%% OPPURE: always( hasball(player(white,1)) + hasball(player(white,2)) + hasball(player(white,3)) + hasball(player(black,1)) + hasball(player(black,2)) + hasball(player(black,3)) leq 1 ). %%% Winning condition caused([pair(x(ball),y(ball)) eq pair(X,Y)],win(TEAM) eq 1) :- door(TEAM,X,Y). %%% Auxiliary static always(win(white) + win(black) leq 1). %%% Two of the same team never in the same cell %always( abs(x(player(T,N1))-x(player(T,N2))) + % abs(y(player(T,N1))-y(player(T,N2))) gt 0 ) :- % team(T), num(N1), num(N2), neq(N1,N2). %%% Never two (different) players in the same cell always( pair(x(A),y(A)) neq pair(x(B),y(B))) :- agent(A), agent(B), ord(A,B). %%% neq(A,B). %%% BLACK GOALKEEPER always( x(player(black,1)) lt x(player(black,2)) ). always( x(player(black,1)) lt x(player(black,3)) ). always( x(player(black,1)) + abs(y(player(black,1))-2) leq 2 ). %%% WHITE GOALKEEPER always( x(player(white,1)) gt x(player(white,2)) ). always( x(player(white,1)) gt x(player(white,3)) ). always( (6 - x(player(white,1))) + abs(y(player(white,1))-2) leq 2 ). %%% BARICENTERED DEFENSE always( y(player(black,1)) + y(player(black,2)) + y(player(black,3)) leq 6). always( y(player(black,1)) + y(player(black,2)) + y(player(black,3)) geq 4). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% STATE COST (for the white team) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% state_cost( 50*win(white) + (1-win(white))* (20*(hasball(player(white,1))+ hasball(player(white,2))+ hasball(player(white,3))) + 18 - (x(player(white,1)) + x(player(white,2)) + x(player(white,3)))) ). %goal_cost(goal gt 20). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Initial state %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% initially(pair(x(player(black,1)),y(player(black,1))) eq pair(1,2)). initially(pair(x(player(black,2)),y(player(black,2))) eq pair(3,4)). initially(pair(x(player(black,3)),y(player(black,3))) eq pair(3,0)). %%% initially(pair(x(player(white,1)),y(player(white,1))) eq pair(6,2)). initially(pair(x(player(white,2)),y(player(white,2))) eq pair(4,4)). initially(pair(x(player(white,3)),y(player(white,3))) eq pair(4,0)). %%% initially(pair(x(ball),y(ball)) eq pair(6,2)). initially(win(T) eq 0) :- team(T). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% GOAL (3 tipologie) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Gioco migliorativo per il bianco. %%% Abilitare opzione monotonic nel solver. %goal(1 eq 1). %%% Nero ruba palla, disabilitare opzione monotonic nel solver %goal(hasball(player(black,3)) eq 1). %%% Suggerimenti (ma ci arriva anche senza) per soluzione in 2 passi %holds(pair(x(ball),y(ball)) eq pair(4,2), 1). %holds(pair(x(player(black,3)),y(player(black,3))) eq pair(3,1), 1). %holds(pair(x(player(black,3)),y(player(black,3))) eq pair(4,2), 2). %%% Bianco segna passi: monotonic opzionale. goal(win(white) eq 1). %%%% Aiuto (meglio darglielo) per soluzione in 3 passi %holds(hasball(player(white,3)) eq 1,1). %holds(pair(x(player(white,3)),y(player(white,3))) eq pair(4,0), 1). %holds(pair(x(player(white,2)),y(player(white,2))) eq pair(3,3), 1). % Aiuto in piu' (non serve) %holds(pair(x(player(white,2)),y(player(white,2))) eq pair(2,2), 2). %holds(pair(x(player(black,1)),y(player(black,1))) eq pair(1,1), 2). %holds(hasball(player(white,2)) eq 1, 2). %%% %%% %%% %%% %%% %%% %%% %%% %%% PRINTING AD HOC %%% %%% %%% %%% %%% %%% %%% %%% soccer_result(_,[]). soccer_result(N,[S|Rest]) :- write('Time '),write(N),write(': '),nl, write_campo(S), N1 is N + 1, soccer_result(N1,Rest). write_campo(S) :- INITIAL= [ ['*','*','*','*','*','*','*','*'], ['*', _ , _ , _ , _ , _ , _ ,'*'], ['*', _ , _ , _ , _ , _ , _ ,'*'], [ _ , _ , _ , _ , _ , _ , _ , _ ], ['*', _ , _ , _ , _ , _ , _ ,'*'], ['*', _ , _ , _ , _ , _ , _ ,'*'], ['*','*','*','*','*','*','*','*'] ], collect_coord(white,Whites,S), collect_coord(black,Blacks,S), member(fluent(x(ball),BallX),S), member(fluent(y(ball),BallY),S), !, insertoken(white,Whites,INITIAL), insertoken(black,Blacks,INITIAL), insertoken(ball,[[BallX,BallY,0]], INITIAL), stampamatrice(INITIAL). collect_coord(TEAM,LIST,S) :- findall([X,Y,B], (num(N), member(fluent(x(player(TEAM,N)),X),S), member(fluent(y(player(TEAM,N)),Y),S), member(fluent(hasball(player(TEAM,N)),B),S)), LIST). insertoken(_,[],_). insertoken(COLOR,[[X,Y,F]|R],MAT) :- ( (var(X);var(Y)),!,write(player(COLOR,undefined)),nl; Y1 is 6-Y, nth1(Y1,MAT,L), X1 is X+1, nth1(X1,L,VAR), (var(VAR),!, ((COLOR=white,F=0) -> VAR='O'; (COLOR=white,F=1) -> VAR='@'; (COLOR=black,F=0) -> VAR='Y'; (COLOR=black,F=1) -> VAR='X'; (COLOR=ball) -> VAR='o'); true), ! ), insertoken(COLOR,R,MAT). %%%% AUX %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% stampamatrice([]). stampamatrice([A|R]) :- stampariga(A),nl, stampamatrice(R). stampariga([]). stampariga([A|R]) :- (var(A),!, write(' '); write(A)), stampariga(R). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%