Senin, 31 Mei 2010

Games CATUR menggunakan bahasa PROLOG

Siapa sih yang gak kenal permainan catur? Permainan yang didalamnya terdapat beberapa pasukan antara lain : pion (prajurit), kuda, raja, ratu dll. Setiap pasukan (bagian) memiliki cara berjalan yang berbeda-beda. Sebelum saya menjelaskan mengenai permainan catur lebih jauh...

Permainan ini di buat menggunakan bahasa pemrograman prolog..

Prolog merupakan singkatan dari “Programing In Logic”. Prolog juga merupakan salah satu bahasa pemrograman yang bersifat Open source. jadi, apabila anda ingin mencoba permainan catur ini , anda dapat harus terlebih dahulu mengunduh Prolog.

Prolog pertama kali dikembangkan oleh Alain Colmetrouer dan P.Roussel di Universitas Marseilles Prancis tahun 1972. Selama tahun 70-an, prolog menjadi ppuler di Eropa untuk aplikasi AI. Sedangkandi Amerika Serikat, para peneliti juga mengmbangkan bahas lain untuk aplikasi yang sama yaitu LISP. LISP mempunyai kelebihan dibandingkan prolog, tetapi LISP lebih sulit dipelajari..
Dengan adanya Compiler Prolog, kecepatan eksekusi program dapat ditingkatkan, namun Prolog masih dipandang sebagai bahasa yang terbahas (hanya digunakan di kalangan perguruan tinggi dan riset).

a. Aplikasi Prolog
Prolog digunakan khususnya dibidang kecerdasan buatan (Artificial Intelegent) meliputi bidang :
• Sistem Pakar
• Pengolahan bahas alami (Natural Language Processing)
• Robotik
• Logika dan ketidakpastian
• Pengenalan pola dan gambarame
• Simulasi pengolahan simbol


Berikut ini adalah coding permainan catur menggunakan bahasa PROLOG :

level(1, 2, 1, 5).
level(2, 3, 3, 15).
level(3, 4, 6, 30).
level(4, 5, 30, 150).

?-
G_AuCh=0,
G_Level=2,
G_Deep=0,
G_Move=0,
G_Forward=0,
G_I=0,
G_Play_with_Blacks=0,
G_Play_with_Computer=1,
array(val,100,0),
array(maximum,100,0),
array(i,1000,0),
array(j,1000,0),
array(x,1000,0),
array(y,1000,0),
array(val2,1000,0),
array(index,1000,0),
G_chessboard is bitmap_image("chess_pic\\chessboard.bmp",_),
G_squareW is bitmap_image("chess_pic\\squareW.bmp",_),
G_squareB is bitmap_image("chess_pic\\squareB.bmp",_),
G_PawnW1 is bitmap_image("chess_pic\\PawnW1.bmp",_),
G_PawnW2 is bitmap_image("chess_pic\\PawnW2.bmp",_),
G_PawnB1 is bitmap_image("chess_pic\\PawnB1.bmp",_),
G_PawnB2 is bitmap_image("chess_pic\\PawnB2.bmp",_),
G_KingW1 is bitmap_image("chess_pic\\KingW1.bmp",_),
G_KingW2 is bitmap_image("chess_pic\\KingW2.bmp",_),
G_KingB1 is bitmap_image("chess_pic\\KingB1.bmp",_),
G_KingB2 is bitmap_image("chess_pic\\KingB2.bmp",_),
G_QueenW1 is bitmap_image("chess_pic\\QueenW1.bmp",_),
G_QueenW2 is bitmap_image("chess_pic\\QueenW2.bmp",_),
G_QueenB1 is bitmap_image("chess_pic\\QueenB1.bmp",_),
G_QueenB2 is bitmap_image("chess_pic\\QueenB2.bmp",_),
G_BishopW1 is bitmap_image("chess_pic\\BishopW1.bmp",_),
G_BishopW2 is bitmap_image("chess_pic\\BishopW2.bmp",_),
G_BishopB1 is bitmap_image("chess_pic\\BishopB1.bmp",_),
G_BishopB2 is bitmap_image("chess_pic\\BishopB2.bmp",_),
G_KnightW1 is bitmap_image("chess_pic\\KnightW1.bmp",_),
G_KnightW2 is bitmap_image("chess_pic\\KnightW2.bmp",_),
G_KnightB1 is bitmap_image("chess_pic\\KnightB1.bmp",_),
G_KnightB2 is bitmap_image("chess_pic\\KnightB2.bmp",_),
G_RookW1 is bitmap_image("chess_pic\\RookW1.bmp",_),
G_RookW2 is bitmap_image("chess_pic\\RookW2.bmp",_),
G_RookB1 is bitmap_image("chess_pic\\RookB1.bmp",_),
G_RookB2 is bitmap_image("chess_pic\\RookB2.bmp",_),
window(G_Win,_,chess_func(_),"Chess",10,150,512,550).

levelm(init):-
menu(normal,_,_,l2(_),"&Beginner"),
menu(checked,_,_,l3(_),"&Normal"),
menu(normal,_,_,l4(_),"&Advanced"),
menu(normal,_,_,l5(_),"&Expert"),
menu(separator, _,_,fail(_),_),
menu(normal,_,_,automatic_change(_),"Automatic change of the Deep").

l2(press):-change_level(1).
l3(press):-change_level(2).
l4(press):-change_level(3).
l5(press):-change_level(4).

automatic_change(press):-
G_AuCh:=1-G_AuCh,
(G_AuCh=0->
modify_menu(G_Menu1,6,normal,_)
else
modify_menu(G_Menu1,6,checked,_)
).

change_level(M):-
G_Deep:=0,
modify_menu(G_Menu1,G_Level,normal,_),
G_Level:=M, modify_menu(G_Menu1,M,checked,_).

changem(init):-
menu(normal,_,_,play_with_blacks(_),"&Play with Blacks"),
menu(checked,_,_,play_with_computer(_),"&Play with the computer").

play_with_blacks(press):-
(G_Play_with_Computer=0->
message("", "You can change the side only when you play with the computer!", s)
else
change_side,
pos(G_Move, C1, WantsStalemate, Pos),
G_WantsStalemate:=0-WantsStalemate,
opposite(C1, C2),
computer(C1,C2,Pos)
).

change_side:-
G_Play_with_Blacks:=1-G_Play_with_Blacks,
(G_Play_with_Blacks=0->
modify_menu(G_Menu2,1,normal,_)
else
modify_menu(G_Menu2,1,checked,_)
).

play_with_computer(press):-
G_Play_with_Computer:=1-G_Play_with_Computer,
(G_Play_with_Computer=0->
modify_menu(G_Menu2,2,normal,_)
else
modify_menu(G_Menu2,2,checked,_)
).

back(press):-
G_Move:=G_Move - 1,
(G_Move=0->
modify_menu(G_Win,3,grayed,_),
draw_menu_bar(_)
),
(G_Forward=0->
modify_menu(G_Win,4,normal,_),
draw_menu_bar(_)
),
G_Forward:=G_Forward + 1,
set_some_text,
update_window(_).

forward(press):-
(G_Move=0->
modify_menu(G_Win,3,normal,_),
draw_menu_bar(_)
),
G_Move:=G_Move + 1,
G_Forward:=G_Forward - 1,
(G_Forward=0->
modify_menu(G_Win,4,grayed,_),
draw_menu_bar(_)
),
set_some_text,
update_window(_).

set_some_text:-
pos(G_Move, C, _, _),
(G_Play_with_Blacks=\=true_value(C=b)->
change_side
),
(C=b->
set_text("Play with Blacks", _)
else (C=w->
set_text("Play with Whites", _)
else
set_text("Game Over", _)
)).

set_pos(C, Pos) :-
(G_Move=0->
modify_menu(G_Win,3,normal,_),
draw_menu_bar(_)
),
(G_Forward>0->
modify_menu(G_Win,4,grayed,_),
draw_menu_bar(_)
),
G_Move:=G_Move+1,
G_Forward:=0,
write(pos(G_Move, C, G_WantsStalemate, Pos)),nl,
retractall(pos(G_Move,_,_,_)),
assert(pos(G_Move,C,G_WantsStalemate,Pos)).

chess_func(init):-
menu(pop_up, G_Menu1,_,levelm(_),"&Level"),
menu(pop_up, G_Menu2,_,changem(_),"&Change"),
menu( right, _, _, back(_), "&Back"),
menu( right, _, _, forward(_), "&Forward"),
modify_menu(G_Win,3,grayed,_),
modify_menu(G_Win,4,grayed,_).

chess_func(paint):-
draw_bitmap(0,0,G_chessboard,_,_),
fail.

chess_func(paint):-
pos(G_Move, _, _, Pos),
mem(Row, Pos,J),
mem(Fig, Row,I),
draw_fig(Fig,I,J),
fail.

chess_func(mouse_click(X,Y)):-
I :=X//50,
J :=Y//50,
I>0, I=<8,
J>0, J=<8,
pos(G_Move, C1, WantsStalemate, Pos),
opposite(C1, C2),
mem(Row,Pos,J),
mem(Fig,Row,I),
(G_I=0 ->
Fig=[_|C1],
G_Fig:=Fig,
clean_field(I, J),
G_I:=I,
G_J:=J
else (can_move(G_Fig,G_I,G_J,I,J,Pos,Fig2), not(Fig2=[_|C1])->
move0(G_I,G_J,Pos,I,J,Pos2),
(check(C1, C2, Pos2)->
message("Bad move", "You are in check after this move", !),
draw_fig(G_Fig,G_I,G_J),
G_I:=0,
fail
),
(J/\6=:=0->
(G_Fig=[p|C1]->
draw_fig([q|C1],I,J)
else (G_Fig=[k|C1], abs(G_I-I)=:=2 ->
(I=3, Xm=4, Xf=1; I=7, Xm=6, Xf=8),
clean_field(Xf, J),
draw_fig([r|C1],Xm,J),
draw_fig([k|C1],I,J)
else
draw_fig(G_Fig,I,J)
))
else
draw_fig(G_Fig,I,J)
),
val(Fig2,Val),
G_WantsStalemate:=WantsStalemate+Val,
(check(C2, C1, Pos2), not(not_mate(C2, C1, Pos2))->
set_pos(n,Pos2),
set_text("Mate. You won!", _),
message("Congratulations", "You won!", !),
fail
),
(G_Play_with_Computer=1->
computer(C2,C1,Pos2)
else
change_side,
G_WantsStalemate:=0-G_WantsStalemate,
set_pos(C2, Pos2),
set_text(xy(G_I, G_J)+":"+xy(I, J)+ (G_Play_with_Blacks=1-> " (Play with Blacks)" else ""), _),
G_I:=0
)
else
draw_fig(G_Fig,G_I,G_J),
G_I:=0
)).

computer(C2,C1,Pos2):-
G_I:=0,
set_text("...", _),
G_I1:=0,
(G_Deep=0->level(G_Level,Deep,_,_), G_Deep:=Deep),
write("Deep="+G_Deep),nl,
chronometer(_),
chronometer_steps(_),
maximum(G_Deep):= -20000,
Moves:=0,
(play(C2,C1,Pos2,G_Deep,Moves); true),
chronometer(Time),
chronometer_steps(Steps),
beep,
write(maximum(G_Deep)+" for "+Time/1000+" seconds ("+Steps+" steps)"),nl,
(G_AuCh=1->
level(G_Level,_,Minimum,Maximun),
(Time<1000*Minimum->
G_Deep:=G_Deep+1,
write("Deep+1="+G_Deep),nl
else (Time>1000*Maximun, G_Deep>2->
G_Deep:=G_Deep- 1,
write("Deep-1="+G_Deep),nl
))
),
(G_I1=0->
set_pos(n, Pos2),
set_text("Stalemate", _),
message("Stalemate", "I am in stalemate. This gane is draw.", !),
fail
),
mem(Row1,Pos2,G_J1),
mem(Fig,Row1,G_I1),
can_move(Fig,G_I1,G_J1,G_I2,G_J2,Pos2,Fig2),
val(Fig2,Val),
G_WantsStalemate:=G_WantsStalemate-Val,
move0(G_I1,G_J1,Pos2,G_I2,G_J2,Pos3),
clean_field(G_I1, G_J1),
mem(Row2,Pos3,G_J2),
mem(BFig,Row2,G_I2),
(BFig=[k|C2], abs(G_I1-G_I2)=:=2 ->
(G_I2=3, XXm=4, XXf=1; G_I2=7, XXm=6, XXf=8),
clean_field(XXf, G_J2),
draw_fig([r|C2],XXm,G_J2),
draw_fig([k|C2],G_I2,G_J2)
else
draw_fig(BFig,G_I2,G_J2)
),
(check(C1, C2, Pos3)->
(not_mate(C1, C2, Pos3)->
set_text("Check", _)
else
set_pos(n, Pos3),
set_text("You are Mate!", _),
message("Mate. Game over", "Sorry but you lost this set.", s),
fail
)
else
set_text(xy(G_I1, G_J1)+":"+xy(G_I2, G_J2)+ (G_Play_with_Blacks=1-> " (Play with Blacks)" else ""), _)
),
(not(mem(Row3,Pos3,J1), mem([F1|C1],Row3,I1), can_move([F1|C1],I1,J1,_,_,Pos3,Fig3), not(Fig3=[_|C1]))->
set_pos(n, Pos3),
set_text("Stalemate", _),
message("Stalemate", "You are in stalemate. This game is draw.", !),
fail
),
(not(mem(Row4,Pos3,_), mem([F2|_],Row4,_), F2\=k)->
set_pos(n, Pos3),
set_text("Tie", _),
message("Tie", "This game is draw.", !),
fail
),
set_pos(C1, Pos3).

play(C1,C2,Pos,Deep,Moves):-
Deep1 is Deep - 1,
(Deep1=0->
(val(Deep):=35;
mem(Row,Pos,J),
mem([Fig|C1],Row,I),
can_move([Fig|C1],I,J,X,Y,Pos,[Fig2|C2]),
take_val(Fig,Fig2,Val2,C1,C2,X,Y,Pos),
val(Deep):=Val2)
else
Moves2:=Moves,
all_moves(C1,Pos,Deep,I,J,X,Y,Val2,Moves,Moves2),
move(I,J,Pos,X,Y,Pos2,Val2),
val(Deep):=Val2,
(Val2>5000->
(Deep=:=G_Deep- 1, check(C2, C1, Pos)->
maximum(Deep1):= -5000
else
maximum(Deep1):=0
)
else
maximum(Deep1):= -20000,
(play(C2,C1,Pos2,Deep1,Moves2); true),
(maximum(Deep1) =:= -20000->
(check(C2, C1, Pos2)->
maximum(Deep1):= -10000-Deep
else
maximum(Deep1):= (1 - 2* ((G_Deep-Deep1) mod 2))*G_WantsStalemate
)
)
)
),
%(Deep=G_Deep-> write(xy(I,J)+":"+xy(X,Y)+" is "+ (val(Deep)-maximum(Deep1))), nl),
(maximum(Deep) % =< in order to see all best
maximum(Deep):=val(Deep)-maximum(Deep1),
(Deep=G_Deep->
write(xy(I,J)+":"+xy(X,Y)+" is "+ (val(Deep)-maximum(Deep1))), nl,
G_I1:=I, G_J1:=J,
G_I2:=X, G_J2:=Y,
fail
else (maximum(Deep+1) % =< in order to see all best

fail
%else
%write(Deep) % alpha-beta cutting
))
else
fail
),
!,
fail.

all_moves(C1,Pos,Deep,_,_,_,_,_,Moves,Moves2):-
mem(Row,Pos,J),
mem([Fig|C1],Row,I),
Sum1:=0,
can_hit([Fig|C1],I,J,Pos,shadow,no,Sum1),
can_move([Fig|C1],I,J,X,Y,Pos,Fig2),
not(Fig2=[_|C1]),
(Fig2=[p|_]->
Val is (C1=w-> 60+20*Y else 240- 20*Y)
else
val(Fig2,Val)
),
Val2 is Val-Sum1+Deep* (1+sign(Val//18- 1)), % 18 is val(p)
find_the_right_place(Val2,Moves,Moves2,Place),
i(Moves2):=I, j(Moves2):=J,
x(Moves2):=X, y(Moves2):=Y,
val2(Moves2):=Val2,
index(Place):=Moves2,
Moves2:=Moves2+1,
fail.
all_moves(_,_,_,I,J,X,Y,Val2,Moves,Moves2):-
for(N, Moves, Moves2- 1),
I is i(index(N)), J is j(index(N)),
X is x(index(N)), Y is y(index(N)),
Val2 is val2(index(N)).

find_the_right_place(Val2,M,M,M):- !.
find_the_right_place(Val2,Moves,Moves2,Place):-
MovesP is Moves2- 1,
(val2(index(MovesP))
index(Moves2):=index(MovesP),
find_the_right_place(Val2,Moves,MovesP,Place)
else
Moves2=Place
).

can_hit([Fig|C1],I,J,Pos,_,Try,Sum):- % the figure hits
can_move([Fig|C1],I,J,_,_,Pos,F),
(F=[Fig2|C]->
(C=C1->
Sum:=Sum+8
else
val([Fig2|_],Val2),
val([Fig|_],Val1),
(Val1
(Fig2=k->
(Try=no; not_mate(C, C1, Pos)->
Sum:=Sum+50
else
Sum:=Val2
)
else
Sum:=Sum+33
)
else
Sum:=Sum+12
)
)
else
Sum:=Sum+4
),
fail.
can_hit([Fig|C1],I,J,Pos,Shadow,_,Sum):- % other figures hit it
can_move([F|C_1],I,J,I0,J0,Pos,[F|C_2]),
not(F=p, C_1=C_2),
not(F=k, C_1=C_2),
(C_2=C1->
Sum:=Sum+ 4 % 8-4
else
val([F|_],Val2),
val([Fig|_],Val1),
(Val1>Val2->
(Fig=k->
Sum:=Sum- 46 % 50-4
else
Sum:=Sum- 29 % 33-4
)
else
Sum:=Sum- 8 % 12-4
)
),
throw_shadow(Shadow,[F|C_2],I0,J0,I,J,Pos,SumT),
(C_2=C1->
Sum:=Sum-SumT
else
Sum:=Sum+SumT
),
fail.
can_hit(_,_,_,_,_,_,_).

throw_shadow(shadow,[F|C_2],I1,J1,I2,J2,Pos,Sum):-
Sum:=0,
(F=r; F=q),
(I1=I2->
(J1
move_down(I2,J2,_,_,Pos,Fig)
else
move_up(I2,J2,_,_,Pos,Fig)
)
else (J1=J2->
(I1
move_right(I2,J2,_,_,Pos,Fig)
else
move_left(I2,J2,_,_,Pos,Fig)
)
else
fail
)),
hit([F|C_2],Fig,Sum).
throw_shadow(shadow,[F|C_2],I1,J1,I2,J2,Pos,Sum):-
(F=b; F=q),
(I1+J1=:=I2+J2->
(I1
move_right_up(I2,J2,_,_,Pos,Fig)
else
move_left_down(I2,J2,_,_,Pos,Fig)
)
else (I1-J1=:=I2-J2->
(I1
move_right_down(I2,J2,_,_,Pos,Fig)
else
move_left_up(I2,J2,_,_,Pos,Fig)
)
else
fail
)),
hit([F|C_2],Fig,Sum).
throw_shadow(shadow,[_|_],_,_,_,_,_,_).

hit([Fig|C1],F,Sum):-
(F=[Fig2|C]->
(C=C1->
Sum:=Sum+8
else
val([Fig2|_],Val2),
val([Fig|_],Val1),
(Val1
(Fig2=k->
Sum:=Sum+50
else
Sum:=Sum+33
)
else
Sum:=Sum+12
)
)
else
Sum:=Sum+4
),
fail.

move(I1,J1,Pos1,I2,J2,Pos2,Sum):-
mem(Row, Pos1, J1),
mem([F1|C1], Row, I1),
replace(f, Row, Row2,I1),
replace(Row2, Pos1, Pos1a, J1),
mem(Row3, Pos1a, J2),
(J2/\6=:=0->
(F1=p->
replace([q|C1], Row3, Row4, I2)
else (F1=k, abs(I1-I2)=:=2 ->
(I2=3, Xm=4, Xf=1; I2=7, Xm=6, Xf=8),
Sum:=Sum+50,
replace(f, Row3, Row3a, Xf),
replace([r|C1], Row3a, Row3b, Xm),
replace([F1|C1], Row3b, Row4, I2)
else
replace([F1|C1], Row3, Row4, I2)
))
else
replace([F1|C1], Row3, Row4, I2)
),
replace(Row4, Pos1a, Pos2,J2),
(mem([F2|C2], Row3, I2)->
Sum1:=0,
can_hit([F2|C2],I2,J2,Pos2,no,no,Sum1),
Sum:=Sum-Sum1,
can_hit([F1|C1],I2,J2,Pos2,no,try,Sum)
else
can_hit([F1|C1],I2,J2,Pos2,shadow,try,Sum)
).

move0(I1,J1,Pos1,I2,J2,Pos2):-
mem(Row, Pos1, J1),
mem([F1|C1], Row, I1),
replace(f, Row, Row2,I1),
replace(Row2, Pos1, Pos1a, J1),
mem(Row3, Pos1a, J2),
(J2/\6=:=0->
(F1=p->
replace([q|C1], Row3, Row4, I2)
else (F1=k, abs(I1-I2)=:=2 ->
(I2=3, Xm=4, Xf=1; I2=7, Xm=6, Xf=8),
replace(f, Row3, Row3a, Xf),
replace([r|C1], Row3a, Row3b, Xm),
replace([F1|C1], Row3b, Row4, I2)
else
replace([F1|C1], Row3, Row4, I2)
))
else
replace([F1|C1], Row3, Row4, I2)
),
replace(Row4, Pos1a, Pos2,J2).

val(f,0).
val(p,18). % Pawn move
val(d,35). % Pawn double move = 2*val(p)-1
val([p|_],100).
val([h|_],300).
val([b|_],300).
val([r|_],500).
val([q|_],1000).
val([n|_],600). % new queen
val([t|_],700). % new queen and take
val([k|_],10000).

take_val(p,p,60|_). take_val(p,h,250|_). take_val(p,b,250|_). take_val(p,r,450|_). take_val(p,q,950|_). take_val(p,k,10000|_).
take_val(k,p,100|_). take_val(k,h,300|_). take_val(k,b,300|_). take_val(k,r,500|_). take_val(k,q,1000|_). take_val(k,k,10000|_).
take_val(h|T):-
evaluate(300|T).
take_val(b|T):-
evaluate(300|T).
take_val(r|T):-
evaluate(500|T).
take_val(q|T):-
evaluate(1000|T).

evaluate(Val1,Fig,Val,C1,C2,X,Y,Pos):-
val([Fig|_],Val2),
(Val2>Val1->
Val is Val2 - Val1//2
else (can_move([F|C1],X,Y,_,_,Pos,[F|C2])->
Val=50
else
val([Fig|_],Val)
)).

%pos(0,w,0,[[rb,hb,bb,qb,kb,bb,hb,rb],[f,pb,f,f,f,f,pb,f],[f,f,f,pb,f,pb,f,f],[pb,f,pb,qw,f,f,f,pb],[f,f,f,f,pw,f,f,f],[f,pw,hw,f,f,hw,f,f],[pw,f,pw,f,f,pw,pw,pw],[rw,f,bw,f,kw,bw,f,rw]]).

pos(0, w, 0,
[[rb,hb,bb,qb,kb,bb,hb,rb],
[pb,pb,pb,pb,pb,pb,pb,pb],
[f,f,f,f,f,f,f,f],
[f,f,f,f,f,f,f,f],
[f,f,f,f,f,f,f,f],
[f,f,f,f,f,f,f,f],
[pw,pw,pw,pw,pw,pw,pw,pw],
[rw,hw,bw,qw,kw,bw,hw,rw]]).

clean_field(I, J):-
( (I+J) mod 2 =:= 0->
draw_bitmap(50*I,50*J,G_squareW,_,_)
else
draw_bitmap(50*I,50*J,G_squareB,_,_)
).

draw_fig(Fig,I,J):-
N is 1+ (I+J) mod 2,
fig(Fig, N, Bitmap),
draw_bitmap(I*50,J*50,Bitmap,_,_).

fig(pb, 1, G_PawnB1).
fig(pw, 1, G_PawnW1).
fig(kb, 1, G_KingB1).
fig(kw, 1, G_KingW1).
fig(qb, 1, G_QueenB1).
fig(qw, 1, G_QueenW1).
fig(bb, 1, G_BishopB1).
fig(bw, 1, G_BishopW1).
fig(hb, 1, G_KnightB1).
fig(hw, 1, G_KnightW1).
fig(rb, 1, G_RookB1).
fig(rw, 1, G_RookW1).
fig(pb, 2, G_PawnB2).
fig(pw, 2, G_PawnW2).
fig(kb, 2, G_KingB2).
fig(kw, 2, G_KingW2).
fig(qb, 2, G_QueenB2).
fig(qw, 2, G_QueenW2).
fig(bb, 2, G_BishopB2).
fig(bw, 2, G_BishopW2).
fig(hb, 2, G_KnightB2).
fig(hw, 2, G_KnightW2).
fig(rb, 2, G_RookB2).
fig(rw, 2, G_RookW2).

R is xy(X, Y):- R:=string_from_ASCII(X+first_ASCII("A")- 1)+ (9-Y).

mem(E,[E,_,_,_,_,_,_,_],1).
mem(E,[_,E,_,_,_,_,_,_],2).
mem(E,[_,_,E,_,_,_,_,_],3).
mem(E,[_,_,_,E,_,_,_,_],4).
mem(E,[_,_,_,_,E,_,_,_],5).
mem(E,[_,_,_,_,_,E,_,_],6).
mem(E,[_,_,_,_,_,_,E,_],7).
mem(E,[_,_,_,_,_,_,_,E],8).

replace(X,[_,A,B,C,D,E,F,G],[X,A,B,C,D,E,F,G],1).
replace(X,[A,_,B,C,D,E,F,G],[A,X,B,C,D,E,F,G],2).
replace(X,[A,B,_,C,D,E,F,G],[A,B,X,C,D,E,F,G],3).
replace(X,[A,B,C,_,D,E,F,G],[A,B,C,X,D,E,F,G],4).
replace(X,[A,B,C,D,_,E,F,G],[A,B,C,D,X,E,F,G],5).
replace(X,[A,B,C,D,E,_,F,G],[A,B,C,D,E,X,F,G],6).
replace(X,[A,B,C,D,E,F,_,G],[A,B,C,D,E,F,X,G],7).
replace(X,[A,B,C,D,E,F,G,_],[A,B,C,D,E,F,G,X],8).

check(C1, C2, Pos):-
mem(Row,Pos,J),
mem([k|C1],Row,I),
can_move([Fig|C1],I,J,_,_,Pos,[Fig|C2]).

not_mate(C1, C2, Pos):-
mem(Row,Pos,J),
mem([Fig|C1],Row,I),
can_move([Fig|C1],I,J,X,Y,Pos,Fig2),
not(Fig2=[_|C1]),
move0(I,J,Pos,X,Y,Pos2),
not(check(C1, C2, Pos2)).

opposite(w, b).
opposite(b, w).

can_move([h|_], X1,Y1,X2,Y2,Pos,Fig):-
(X2 is X1+1; X2 is X1 - 1),
(Y2 is Y1+2; Y2 is Y1 - 2),
mem(Row,Pos,Y2),
mem(Fig,Row,X2).

can_move([h|_], X1,Y1,X2,Y2,Pos,Fig):-
(X2 is X1+2; X2 is X1 - 2),
(Y2 is Y1+1; Y2 is Y1 - 1),
mem(Row,Pos,Y2),
mem(Fig,Row,X2).

can_move([k|Color], X1,Y1,X2,Y2,Pos,Fig):-
(X2 is X1+1; X2 is X1 - 1; X2=X1),
(Y2 is Y1+1; Y2 is Y1 - 1;Y2=Y1),
not(X1=X2,Y1=Y2),
mem(Row,Pos,Y2),
mem(Fig,Row,X2),
opposite(Color, C2),
(Fig=[k| C2]; not(can_move([F|Color],X2,Y2,_,_,Pos,[F|C2]))).

can_move([k|Color], 5,Y,X2,Y,Pos,f):-
(Y = 1, Color=b, C2=w; Y= 8, Color=w, C2=b),
mem(Row,Pos,Y),
(X2 = 3, mem(f,Row,2), Xn=4, Xr=1; X2 = 7, Xn=6, Xr=8),
mem(f,Row,X2),
mem(f,Row,Xn),
mem([r|Color],Row,Xr),
not(can_move([Fig|Color],X2,Y,_,_,Pos,[Fig|C2])),
not(can_move([Fig|Color],Xn,Y,_,_,Pos,[Fig|C2])),
not(can_move([Fig|Color], 5,Y,_,_,Pos,[Fig|C2])).

can_move(pw, X,Y1,X,Y2,Pos,Fig):-
Yn is Y1 - 1,
mem(Row,Pos,Yn),
mem(f,Row,X),
(Y2=Yn, (Y1=2->Fig=nb else Fig=p)
;
Y1=7, mem(Row2,Pos,5), mem(f,Row2,X), Y2=5, Fig=d
).

can_move(pb, X,Y1,X,Y2,Pos,Fig):-
Yn is Y1 + 1,
mem(Row,Pos,Yn),
mem(f,Row,X),
(Y2=Yn, (Y1=7->Fig=nw else Fig=p)
;
Y1=2, mem(Row2,Pos,4), mem(f,Row2,X), Y2=4, Fig=d
).

can_move(pw, X1,Y1,X2,Y2,Pos,[F1|C]):-
Y2 is Y1 - 1,
mem(Row,Pos,Y2),
(X2 is X1+1;X2 is X1 - 1),
mem([F2|C],Row,X2),
(Y2=1, F2\=k->F1=t else F1=F2).

can_move(pb, X1,Y1,X2,Y2,Pos,[F1|C]):-
Y2 is Y1 + 1,
mem(Row,Pos,Y2),
(X2 is X1+1;X2 is X1 - 1),
mem([F2|C],Row,X2),
(Y2=8, F2\=k->F1=t else F1=F2).

can_move([r|_], X1,Y1,X2,Y2,Pos,Fig):-
move_up(X1,Y1,X2,Y2,Pos,Fig);
move_down(X1,Y1,X2,Y2,Pos,Fig);
move_left(X1,Y1,X2,Y2,Pos,Fig);
move_right(X1,Y1,X2,Y2,Pos,Fig).

can_move([b|_], X1,Y1,X2,Y2,Pos,Fig):-
move_left_up(X1,Y1,X2,Y2,Pos,Fig);
move_right_down(X1,Y1,X2,Y2,Pos,Fig);
move_left_down(X1,Y1,X2,Y2,Pos,Fig);
move_right_up(X1,Y1,X2,Y2,Pos,Fig).

can_move([q|_], X1,Y1,X2,Y2,Pos,Fig):-
move_up(X1,Y1,X2,Y2,Pos,Fig);
move_down(X1,Y1,X2,Y2,Pos,Fig);
move_left(X1,Y1,X2,Y2,Pos,Fig);
move_right(X1,Y1,X2,Y2,Pos,Fig);
move_left_up(X1,Y1,X2,Y2,Pos,Fig);
move_right_down(X1,Y1,X2,Y2,Pos,Fig);
move_left_down(X1,Y1,X2,Y2,Pos,Fig);
move_right_up(X1,Y1,X2,Y2,Pos,Fig).

move_up(X,Y1,X,Y2,Pos,Fig2):-
Y is Y1 - 1,
mem(Row,Pos,Y),
mem(Fig,Row,X),
(Fig=f ->
(Y2 =Y, Fig2=Fig; move_up(X,Y,X,Y2,Pos,Fig2))
else
Y2=Y, Fig2=Fig
).

move_down(X,Y1,X,Y2,Pos,Fig2):-
Y is Y1 + 1,
mem(Row,Pos,Y),
mem(Fig,Row,X),
(Fig=f ->
(Y2 =Y, Fig2=Fig; move_down(X,Y,X,Y2,Pos,Fig2))
else
Y2=Y, Fig2=Fig
).

move_left(X1,Y,X2,Y,Pos,Fig2):-
X is X1 - 1,
mem(Row,Pos,Y),
mem(Fig,Row,X),
(Fig=f ->
(X2=X, Fig2=Fig; move_left(X,Y,X2,Y,Pos,Fig2))
else
X2=X, Fig2=Fig
).

move_right(X1,Y,X2,Y,Pos,Fig2):-
X is X1 + 1,
mem(Row,Pos,Y),
mem(Fig,Row,X),
(Fig=f ->
(X2=X, Fig2=Fig; move_right(X,Y,X2,Y,Pos,Fig2))
else
X2=X, Fig2=Fig
).

move_left_up(X1,Y1,X2,Y2,Pos,Fig2):-
X is X1 - 1, Y is Y1 - 1,
mem(Row,Pos,Y),
mem(Fig,Row,X),
(Fig=f ->
(X2=X, Y2=Y, Fig2=Fig; move_left_up(X,Y,X2,Y2,Pos,Fig2))
else
X2=X, Y2=Y, Fig2=Fig
).

move_left_down(X1,Y1,X2,Y2,Pos,Fig2):-
X is X1 - 1, Y is Y1 + 1,
mem(Row,Pos,Y),
mem(Fig,Row,X),
(Fig=f ->
(X2=X, Y2=Y, Fig2=Fig; move_left_down(X,Y,X2,Y2,Pos,Fig2))
else
X2=X, Y2=Y, Fig2=Fig
).

move_right_up(X1,Y1,X2,Y2,Pos,Fig2):-
X is X1 + 1, Y is Y1 - 1,
mem(Row,Pos,Y),
mem(Fig,Row,X),
(Fig=f ->
(X2=X, Y2=Y, Fig2=Fig; move_right_up(X,Y,X2,Y2,Pos,Fig2))
else
X2=X, Y2=Y, Fig2=Fig
).

move_right_down(X1,Y1,X2,Y2,Pos,Fig2):-
X is X1 + 1, Y is Y1 + 1,
mem(Row,Pos,Y),
mem(Fig,Row,X),
(Fig=f ->
(X2=X, Y2=Y, Fig2=Fig; move_right_down(X,Y,X2,Y2,Pos,Fig2))
else
X2=X, Y2=Y, Fig2=Fig
).


File games catur ini akan berformat .spj karena memang itulah format yang dihasilkan pada bahasa Prolog...



....SELAMAT MENCOBA....