Kamis, 23 Februari 2012

manual book game catur

saya akan memposting artikel saya sendiri tentang bagaimana membuat sebuah game catur  pada strawberry prolog, dan cara memainkannya. semoga bermanfaat.

artikel ini saya buat untuk memenuhi tugas praktikum dikampus saya.


1.1  Landasan Teori Kecerdasan Buatan
            1.2.1 Kecerdasan Buatan
Kecerdasan buatan ( artificial inteligence ) merupakan salah satu bagian ilmu komputer yang membuat agar mesin ( komputer) dapat melakukan pekerjaan seperti yang sebaik dilakukan manusia (Sri Kusumadewi, 2003).

Pengertian kecerdasan buatan dapat di pandang dari berbagai sudut pandang, antara lain :
1. Sudut pandang kecerdasan.
    Kecerdasan buatan akan membuat mesin menjadi cerdas
    dalam arti mampu berbuat seperti apa yang dilakukan manusia.
2. Sudut pandang penelitian.
    Kecerdasan buatan adalah suatu studi bagaimana membuat
    agar komputer dapat melakukan sesuatu sebaik yang dikerjakan
    manusia.
3. Sudut pandang bisnis.
    Kecerdasan buatan adalah kumpulan peralatan yang sangat
    powerful dan metodologis dalam mnyelesaikan masalah-
    masalah bisnis.
4. Sudut pandang pemrograman.
    Kecerdasan meliputi studi tentang pemrograman simbolik,  
    penyelesaian masalahdan pencarian.

Lingkup Utama dari kecerdasan buatan (Sri Kusumadewi, 2003) adalah sebagai berikut :
1. Sistem Pakar ( Expert System ).
                Disini komputer digunakan untuk menyimpan pengetahuan para 
                pakar.
2. Pengelolaan Bahasa Alami ( Natural Language Processing ).
                Dengan pengolahan bahasa alami ini diharapkan user dapat
                berkomunikasi dengan komputer dengan menggunakan bahasa
                sehari-hari.
3. Pengenalan Ucapan ( Speech Recognition ). Melalui
    pengenalan ucapan diharapkan manusia dapat berkomunikasi
    dengan komputer  dengan menggunakan suara.
4. Robotika & Sistem Sensor ( Robotics & Sensory System).
5. Computer Vision
mencoba untuk dapat menginterprestasikan gambar atau obyek tampak melalui komputer.
6. Intelligent Computer-aided Instruction.Komputer dapat 
    Digunakan sebagai tutor dalam melatih dan mengajar.
7. Game Playing.
                Beberapa karakteristik yang ada pada sistem yang
               menggunakan Artificial inteligence adalah pemrograman yang
                cenderung bersifat simbolik ketimbang algoritmik, bisa
    mengakomodasi input yang tidak lengkap. Dan Game Playing ini
    juga merupakan jenis AI yang penulis pakai dalam proyek ini.

Ada beberapa konsep yang harus dipahami dalam kecerdasan buatan, diantaranya (Kusrini, 2006) :
1. Turing Test – Metode pengujian kecerdasan buatan.
                Merupakan sebuah metode pengujian kecerdasan buatan yang
                dibuat oleh Alan Turing.
2. Pemrosesan Simbolik.
                Sifat penting dari AI adalah bahwa AI merupakan bagian ilmu
                komputer yang melakukan proses secara simbolik dan non-
    algoritmik dalam penyelesaian masalah.
3. Heuristic
                Merupakan suatu strategi untuk melakukan proses pencarian
    (search) ruang problem secara selektif, yang memandu proses
    pencarian yang dilakukan sepanjang jalur yang memiliki
    kemungkinan sukses paling besar.
4. Penarikan Kesimpulan (Inferencing)
                AI mencoba membuat mesin memiliki kemampuan berfikir atau
                mempertimbangkan (reasoning). Kemampuan berfikir termasuk
                didalamnya proses penarikan kesimpulan berdasarkan fakta-
    fakta dan aturan dengan menggunakan metode heuristik atau
    metode pencarian lainnya.
5. Pencocokan Pola (Pattern matching)
                AI bekerja dengan mencocokkan pola yang berusaha untuk 
                menjelaskan objek, kejadian atau proses, dalam hubungan logik
    atau komputasional.

Jika dibandingkan dengan kecerdasan alami (kecerdasan yang dimiliki manusia), kecerdasan buatan memiliki beberapa keuntungan secara komersial, antara lain :
1. Lebih Permanen.
2. Memberikan kemudahan dalam duplikasi dan penyebaran.
3. Relatif lebih murah dari kecerdasan alamiah.
4. Konsisten dan teliti.
5. Dapat didokumentasikan.
6. Dapat mengerjakan beberapa task lebih cepat dan
   lebih baik dibandingkan manusia.



BAGIAN II

1. Bahasa dan Program Editor
            Permainan Horse chess ini menggunakan bahasa pemrograman Prolog, dengan program editor yang saya gunakan adalah Strawberry Prolog.
           
2. Initial State
Initial State yang digunakan sebagai acuan untuk membuat program Horse chess adalah pada buah catur yang berisi mayoritas kuda.
Di sini saya menggunakan papan catur biasa tetapi tiap-tiap perwiranya diganti dengan kuda kecuali ratu. Pion atau bidak terletak dibaris depan selayaknya catur pada umumnya, dan kuda dibaris belakang menemani 1 raja dan 1 ratu.
Game ini akan mengasah otak pemainnya. Pemain dipaksa untuk menerapkan strategi yang tepat untuk memenangkan game ini. Permainan ini hanya dapat dimainkan oleh satu pemain, sedangkan Komputer bertindak sebagai lawan.

3. Aturan (Rule)
            Setiap permainan pasti memiliki aturan, begitu juga dengan permainan ini.  Ada beberapa aturan yang terdapat dalam permainan ini, diantaranya adalah :
  1. pemain (user) dapat menentukan akan bermain dengan warna putih atau hitam, dan seperti catur pada umumnya, putih jalan terlebih dahulu.
  2. Pemain hanya dapat melangkah satu kali kemudian komputer yang mendapat giliran melangkah, begitu seterusnya.
  3. Disini hanya ada 4 tipe buah catur, yaitu : pion, kuda, ratu dan raja.
  4. Langkah pion yaitu jalan 1 langkah kedepan dengan kondisi petak didepan harus  kosong (tidak ada yang menghalangi). Jika ingin memakan lawan, pion melangkah diagonal kedepan sebanyak 1 petak.
  5. Ketika pion berhasil berjalan sampai  garis belakang daerah lawan, maka pion secara otomatis berganti dengan ratu.
  6. Langkah kuda yaitu membentuk huruf L.
  7. Langkah ratu yaitu vertical, horizontal dan diagonal.
  8. Langkah raja sama dengan ratu tetapi hanya boleh melangkah 1 petak saja.
  9. komputer diberi pembelajaran untuk menghalagi jalan user mencapai tujuan (goal).
  10. komputer juga diberi pembelajaran untuk memenangkan permaianan ini
  11. Untuk memenangkan permainan ini, pemain harus membuat raja lawan tidak dapat mengelak untuk dimakan (skak mat).

3. Tujuan ( Goal )
Tujuan (goal) untuk menyelesaikan permainan ini adalah membuat
Lawan menyerah dengan membuat raja tidak dapat mengelak untuk dimakan.














Dari gambar diatas raja hitam tertangkap oleh ratu yang melakukan skak mat, dan putih memenangkan permainan.




4. Kecerdasan Buatan ( AI )
            Kecerdasan buatan atau sering disebut sebagai AI pada permaianan ini terletak pada computer, yang bertindak sebagai lawan. Computer akan berusaha mengalakan pemain (user) dan dapat menyusun strategi sendiri agar menjadi pemenang.

5.      Batas Usia
Semua orang dapat menjadi pemain (user) dan memainkan permainan
ini. Karena permainan ini mengasah keterampilan otak dalam menyusun strategi, maka tidak ada batasan umur yang diberikan.

6.      Strawberry Prolog
            Strawberry Prolog merupakan sebuah bahasa pemrograman logika yang memiliki Object Oriented Language. Pada prolog ini tidak terdapat prosedur, hanya terdapat kumpulan data yang akan diolah. Untuk menggunakan strawberry prolog tidak dilakukan instalasi. Programmer dapat meng-unduhnya secara gratis di website resminya. Namun karena penggunaannya yang gratis, pada strawberry prolog ini, games horse chess tidak dapat membentuk sebuah file execute (exe). Jadi program dapat dijalankan dengan membuka file strawberry prolog (spj) di dalam strawberry prolog itu sendiri.












7.      Analisa Pembuatan Program

            Pembuatan permainan ini sebenarnya cukup rumit tetapi akan mudah untuk dipelajari, langkah pertama tentu saya membuat desain gambar sebuah papan catur 8 x 8 kotak yang berselang-seling dengan warna coklat muda dan coklat tua. Kemudian saya membuat desain untuk pion putih dan hitam. Lalu membuat desain untuk kuda putih dan hitam, membuat ratu untuk putih dan hitam dan yang terakhir adalah raja putih dan hitam yang berbentuk seperti Pegasus (kuda bersayap).
            Setelah semua gambar visual yang dibutuhkan selesai dibuat, kita hanya tinggal “memanggil” gambar tersebut kedalam prolog pada beberapa perintah. Perlu diingat banhwa file gambar tersebut harus didalam folder yang sama dengan listing program.spj yang akan kita buat.
            Kemudian saya memberikan hak langkah untuk masing-masing buah catur dengan beberapa kondisi dan aturan didalamnya.lalu saya membuat beberapa level kecerdasan AI yaitu beginner, normal, advanced dan expert yang tentunya memiliki tingkat kesulitan untuk dikalahkan yang berbeda-beda.
            Kemudian saya memberikan aturan khusus untuk raja, yaitu ketika raja berhasil dimakan, maka permainan berakhir. Untuk lebih jelasnya saya telah menyiapkan listing program pada lembar selanjutnya.










BAGIAN III

1.      Kesimpulan
            Permainan horse chess yang saya buat ini adalah sebuah permainan hiburan yang juga dapat mengasah otak. Karena pemain harus menyusun strategi agar dapat mengalahkan AI yang saya buat pada lawan (computer)

2.      Saran
            Untuk setiap pemain (user) yang memainkan permainan ini, diharapkan lebih teliti serta dapat menggunakan strategi yang tepat dan cerdas agar dapat mengalahkan AI pada komputer

3.      Output program :

jika komputer menang :
           










Jika pemain (user) menang :











4.               Listing Program :


% If you want to understand this program look at
% its rough variant "chess rough.pro".
% It is easier to understand because
% "Chess.spj" contains too many details.

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_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",_),
 window(G_Win,_,chess_func(_),"Horse 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)<val(Deep)-maximum(Deep1)->  % =< 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)<val(Deep+1)-maximum(Deep)->  % =< 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))<Val2->
    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<Val2->
        (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<J2->
      move_down(I2,J2,_,_,Pos,Fig)
    else
      move_up(I2,J2,_,_,Pos,Fig)
    )
  else (J1=J2->
    (I1<I2->
      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<I2->
      move_right_up(I2,J2,_,_,Pos,Fig)
    else
      move_left_down(I2,J2,_,_,Pos,Fig)
    )
  else (I1-J1=:=I2-J2->
    (I1<I2->
      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<Val2->
        (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([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,q,950|_).  take_val(p,k,10000|_).
take_val(k,p,100|_). take_val(k,h,300|_). take_val(k,q,1000|_). take_val(k,k,10000|_).
take_val(h|T):-
  evaluate(300|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,
    [[hb,hb,hb,qb,kb,hb,hb,hb],
     [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],
     [hw,hw,hw,qw,kw,hw,hw,hw]]).

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(hb, 1, G_KnightB1).
fig(hw, 1, G_KnightW1).
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(hb, 2, G_KnightB2).
fig(hw, 2, G_KnightW2).

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
  ).


NB :silahkan copy-paste coding programnya, gambar2 caturnya harus 1 folder dengan listingnya,agar dapat "dipanggil"

Open Panel

Blogroll