Задание:
На prologe написать программу реализующую дебюд шахматной игры,о собого интелекта делать ненадо просто научить фигур ходить ходов 10, партию играет игрок и пк-который должен сам ходить.
DOMAINS
figure=f(char, string, integer,integer)%cvet, figura, stroka,stolbec
figures=figure*
PREDICATES
nondeterm show(figures)
nondeterm show_index(figures,integer,integer)
nondeterm member(figure, figures)
nondeterm delete(figure,figures,figures)
nondeterm add(figure,figures,figures)
nondeterm step_man(char,figures)
nondeterm step_computer(char,figures)
nondeterm step(char,figures)
nondeterm start_game(char)
nondeterm start_position(figures)
nondeterm switch(char,char)
nondeterm not_empty(figures,integer,integer,integer,integer)
nondeterm in(integer,integer,integer)
nondeterm hod(string,figures,integer,integer,integer,integer)
nondeterm designation(string,string)
nondeterm can_eat(char,figures,integer,integer)
nondeterm going_figure(figures,figure,integer,integer,figures)
nondeterm for(integer,integer,integer)
nondeterm main
nondeterm append(figures,figures,figures)
nondeterm sdvig_vlevo(figures,integer,figures)
nondeterm horoshii_hod(char,figures)
CLAUSES
%Standartnii predicat, proveryayusii yavlyaetsya li element(1 parametr) chlenov spiska(2 parametr)
%Esli pishets [H|Tail], to H - "golova" spiska, te pervii element, a Tail - "hvost" spiska, te csya ostavshayasya chast
%_ oznachaet bezimyanaya peremennaya, te ee znachenie nam ne vazno
member(H,[H|_]).%esli element yavlyaetsya golovoi spiska, to on prinadlezgit spisku
member(H,[_|Tail]):-member(H,Tail).%esli element prinadlezght hvostu spiska, to on b prinadlezgit vsemu spisku
%Standartnii predicat sliyaniya dvuh spiskov i pomeshenie rezultata v 3 spisok
append([],B,B).%esli 1 spisok pust, to rezultato sliyaniya budet 2 spisok
append([H|Tail],B,[H|NewTail]):-append(Tail,B,NewTail).%golovoi novogo spiska budet golova 1 spiska, a hvostom
%budet rezultat sliyaniya hvosta 1 spiska i 2 spiska
%standartnii predicat udaleniya elementa iz spiska
delete(_,[],[]).%kakoi bi element ni udalyali iz pustogo spiska, otvetom budet pustoi spisok
delete(H,[H|Tail],Tail):-!.%esli udalyaemii element - goova spiska, to otvetom budet hvost spiska. ! znachit otsechenie, te dalneishii
%pravila etogo redicata v dannom slucha rassmatrivatsya ne budut. Pro eto luche v inete pochitat
delete(Y,[H|Tail],[H|NewTail]):-delete(Y,Tail,NewTail).%esli iskomii elelment ne yavlayetsya golovoi spiska,
%to udalyaem ego iz hvosta, delaya takim obrazom novii hvost
add(Figure,Figures,[Figure|Figures]). %dabavlyaet figuru v spisok figur, stavya ee na meso golovi
%pereclyuchaet znachenie cveta
switch('w','b').
switch('b','w').
%proveryaet chtobi chislo A lezgalo mezgdu cheslami B i C
in(A,B,C):-A>B,A
in(A,B,C):-AC.
%zakolcovanno sdvigaet spisok na I elementov vlevo. Eto ponadobitsya dlya togo, chtobi komp vibiral figuru sluchainim obrazom
sdvig_vlevo(L,0,L):-!.%esli nado sdvinut na 0 elementov, to ne nado nichego menyat
sdvig_vlevo([H|Tail],I,Ans):-append(Tail,[H],Temp),I1=I-1,sdvig_vlevo(Temp,I1,Ans).%inache golovu spiska peremeshaem v ego konec
%i sdvigaem etot spisok vlevo, no uzge na odno znachenie menshe
%cikl, pervii parametr probegaet znacheniya ot A do B
for(A,A,_).%espli pervii parametr raven A, to podhodit
for(X,A,B):-A1=A+1,A1<=B,for(X,A1,B).%uvelichivaem parametr A na 1 i vizivaem cikl ot novogo parametra
%vspomogatelnii predicat, chtobi pravila peredvizgeniya figur ne nado bulo povtoryat dlya chernih i belih
%te vse chernii elementi krome peshi budut rassmatrivatsya kak ih belie analogi
designation("l","L").%ladiya
designation("k","K").%kon
designation("s","S").%slon
designation("f","F").%ferz
designation("kr","Kr").%korol
designation(X,X).%vse belie i chernaya pesha ne menyayut oboznachenie
%nachalnaya poziciya
start_position([f('w',"L",1,1),f('w',"K",1,2),f('w',"S",1,3),f('w',"F",1,4),
f('w',"Kr",1,5),f('w',"S",1,6),f('w',"K",1,7),f('w',"L",1,8),
f('w',"P",2,1),f('w',"P",2,2),f('w',"P",2,3),f('w',"P",2,4),
f('w',"P",2,5),f('w',"P",2,6),f('w',"P",2,7),f('w',"P",2,8),
f('b',"l",8,1),f('b',"k",8,2),f('b',"s",8,3),f('b',"kr",8,4),
f('b',"f",8,5),f('b',"s",8,6),f('b',"k",8,7),f('b',"l",8,8),
f('b',"p",7,1),f('b',"p",7,2),f('b',"p",7,3),f('b',"p",7,4),
f('b',"p",7,5),f('b',"p",7,6),f('b',"p",7,7),f('b',"p",7,8)]).
%predicat vivoda tekushei pozicii na ekran
show(Figures):-show_index(Figures,8,0).%vizivaet predicat vuvoda s indeksami(stroka,solbec)
show_index(_,0,0):-!,nl,write(" 1 2 3 4 5 6 7 8"),nl,nl,nl.%kogda doidem do 0(mnimoi) stroki, to vivedem nomera i zavershim predicat
show_index(Figures,I,0):-!,write(I," "),show_index(Figures,I,1).%kogada stolbec raven 0, te tolko nachali vuvodit etu stroku, to vuvedem ee indeks
show_index(Figures,I,9):-!,nl,I1=I-1,show_index(Figures,I1,0).%esli stolbec raven 9, to stroka proidenna i perehodim k sleduyushei
show_index(Figures,I,J):-member(f(_,Figure,I,J),Figures),!,write(" ",Figure), J1=J+1, show_index(Figures,I,J1).%esli v spiski figur est figura
%s indeksami I i J, to vivodim ee i perehodim k sleduyushemu stolbcu etoi stroki
show_index(Figures,I,J):-write(" -"), J1=J+1, show_index(Figures,I,J1).%esli netu takogo elementa, to vivodim procherk
%Vspomogatelnii predicat, neoobhodimii dlya opisaniya vozmognih hodov figur, poskolku dlya slona,ladii i ferzya neobhdimo,
%chtobi na ih dlinnom puti ne bulo figur. Proverka na nahozgdenie figuri v nachale i konce puti proveryatsya v drugom meste
not_empty(Figures,Y,X,Y,NewX):-member(f(_,_,Y,MiddleX),Figures),in(MiddleX,X,NewX).%esli mi dvizgemsya po gorizontali i v etom
%stolbce est figura s koordinatoi stroki, lezgasheii v intevale strok nachala i konca dvizheniya, to znachit put ne bil pustim
not_empty(Figures,Y,X,NewY,X):-member(f(_,_,MiddleY,X),Figures),in(MiddleY,Y,NewY).%to zge sanoe s vertikalyu
not_empty(Figures,Y,X,NewY,NewX):-member(f(_,_,MiddleY,MiddleX),Figures),%i s takoi / diagonlyu
in(MiddleY,Y,NewY),in(MiddleX,X,NewX),MiddleY-Y=MiddleX-X.
not_empty(Figures,Y,X,NewY,NewX):-member(f(_,_,MiddleY,MiddleX),Figures),%i s takoi \ diagonalyu
in(MiddleY,Y,NewY),in(MiddleX,X,NewX),MiddleY-Y=X-MiddleX.
%pravil hodov figur
hod("L",Figures,Y,X,Y,NewX):-not(not_empty(Figures,Y,X,Y,NewX)).%ladya mozget dvigatsya po pustoi gorizontali
hod("L",Figures,Y,X,NewY,X):-not(not_empty(Figures,Y,X,NewY,X)).%ladya mozget dvigatysa po pustoi vertikali
%hodi konem
hod("K",_,Y,X,NewY,NewX):-NewY=Y+1,NewX=X+2.
hod("K",_,Y,X,NewY,NewX):-NewY=Y+1,NewX=X-2.
hod("K",_,Y,X,NewY,NewX):-NewY=Y-1,NewX=X+2.
hod("K",_,Y,X,NewY,NewX):-NewY=Y-1,NewX=X-2.
hod("K",_,Y,X,NewY,NewX):-NewY=Y+2,NewX=X+1.
hod("K",_,Y,X,NewY,NewX):-NewY=Y+2,NewX=X-1.
hod("K",_,Y,X,NewY,NewX):-NewY=Y-2,NewX=X+1.
hod("K",_,Y,X,NewY,NewX):-NewY=Y-2,NewX=X-1.
hod("S",Figures,Y,X,NewY,NewX):-NewY-Y=NewX-X,not(not_empty(Figures,Y,X,NewY,NewX)).%slon mozget dvigatsya po pustoi /
hod("S",Figures,Y,X,NewY,NewX):-NewY-Y=X-NewX,not(not_empty(Figures,Y,X,NewY,NewX)).%slon mozget dvagatsya po pustoi \
hod("F",Figures,Y,X,NewY,NewX):-hod("S",Figures,Y,X,NewY,NewX).%ferz mozget dvagatsya kak slon
hod("F",Figures,Y,X,NewY,NewX):-hod("L",Figures,Y,X,NewY,NewX).%ferz mozget dvigatsya kak ladya
hod("P",Figures,2,X,4,X):-not(member(f(_,_,3,X),Figures)),not(member(f(_,_,4,X),Figures)).%belaya peshka pervim hodom mozget
%prignut na dve kletki vpered, esli ee nikto ne meshaeet
hod("P",Figures,Y,X,NewY,NewX):-NewY=Y+1,NewX=X+1,member(f('b',_,NewY,NewX),Figures).%belaya pesha est po diagonali esli
%tam figura protivnika
hod("P",Figures,Y,X,NewY,NewX):-NewY=Y+1,NewX=X-1,member(f('b',_,NewY,NewX),Figures).%est po drugoi diagonali
hod("P",Figures,Y,X,NewY,X):-NewY=Y+1,not(member(f(_,_,NewY,X),Figures)).%prosto vpered
%dlya chernoi peshki
hod("p",Figures,7,X,5,X):-not(member(f(_,_,6,X),Figures)),not(member(f(_,_,5,X),Figures)).
hod("p",Figures,Y,X,NewY,NewX):-NewY=Y-1,NewX=X+1,member(f('w',_,NewY,NewX),Figures).
hod("p",Figures,Y,X,NewY,NewX):-NewY=Y-1,NewX=X-1,member(f('w',_,NewY,NewX),Figures).
hod("p",Figures,Y,X,NewY,X):-NewY=Y-1,not(member(f(_,_,NewY,X),Figures)).
hod("Kr",_,Y,X,NewY,NewX):-DY=NewY-Y,DY>=-1,DY<=1,DX=NewX-X,DX>=-1,DX<=1,5*DY+DX<>0.%dlya korolya. Poslednie neravenstvo garantiruet,
%chto korol ne ostanetsya na tom zge meste
%proveryaet mozget li kakaya-libo iz figur zadannogo cveta pobit pole s koordinatamo Y X
can_eat(Color,Figures,Y,X):-
member(f(Color,Figure,TempY,TempX),Figures),designation(Figure,F),hod(F,Figures,TempY,TempX,Y,X).
%danni predicat proveryaet mozget li zadannaya figura poit na pole NewY NewX, i esli eto vozmozgo to vozvrashaet rezultat
going_figure(Figures,f(Color,Figure,Y,X),NewY,NewX,NewFigures):-
designation(Figure,F),hod(F,Figures,Y,X,NewY,NewX),%proveryaet vozmozgnost hoda
delete(f(_,_,Y,X),Figures,Figures1),%udalyet figuru s nachalnoi pozicii
delete(f(_,_,NewY,NewX),Figures1,Figures2),%ochishaet konecnuyu poziciyu
add(f(Color,Figure,NewY,NewX),Figures2,NewFigures).%dobavlyet figuru na konechnuyu poziciyu
%danni predicat sdelan dlya proverki ne postavlen li mat. On istinen esli mozgno sdelat
%kakoi-libo hod, posle kotorogo korol bul bi ne pod shahom
horoshii_hod('w',Figures):-
member(Figure,Figures),Figure=f('w',_,_,_),%esli est kakaya-libo belaya figura
for(NewY,1,8),for(NewX,1,8),going_figure(Figures,Figure,NewY,NewX,NewFigures),%kotoraya mozhe poiti na nekie koordinati NewY NewX
member(f('w',"Kr",KY,KX),NewFigures),not(can_eat('b',NewFigures,KY,KX)).%i posle etogo hoda kletka s korolem ne pod boeb, ti eto horoshii hod
horoshii_hod('b',Figures):-member(Figure,Figures),Figure=f('b',_,_,_),%to zge samoe, no dlya chernogo cveta
for(NewY,1,8),for(NewX,1,8),going_figure(Figures,Figure,NewY,NewX,NewFigures),
member(f('b',"kr",KY,KX),NewFigures),not(can_eat('w',NewFigures,KY,KX)).
%predicat hoda polzovatelya
step_man(Color,Figures):-not(horoshii_hod(Color,Figures)),!,write("Vam mat!"),nl.%esli nevozmogno cdelat ni odnogo hoda tak,
%chtobi korol bil ne pod boem, to eto mat
step_man('w',Figures):-member(f('w',"Kr",Y,X),Figures),can_eat('b',Figures,Y,X),write("Vam shah!"),nl,step('w',Figures).%esli polzovatel igraet
%belimi, a belogo korolya mogut sest za odin hod, to vuvoditsya sobshenie ob shahe
step_man('b',Figures):-member(f('b',"kr",Y,X),Figures),can_eat('w',Figures,Y,X),write("Vam shah!"),nl,step('b',Figures).%to zge samoe, no dlya chernih
step_man(_,Figures):-show(Figures),write("Esli ne hotite prodolzgat, vvedite 's' "),readchar(C),nl,C='s'.%pokazivaetsya poziciya i vidatsya zapros ob vihode
step_man(Color,Figures):-step(Color,Figures).%esli ne bil udovletvoren zapros ob vihide, to vizivaetsya predicat hoda
%predicat hoda
step(ManColor,Figures):-write("Vvedite koordinatu Y figuri: "),readint(Y),%snachala zaprosi koordinat
write("Vvedite koordinatu X figuri: "),readint(X),
write("Vvedite koordinatu Y novogo mesta: "),readint(NewY),
write("Vvedite koordinatu X novogo mesta: "),readint(NewX),
member(f(ManColor,Figure,Y,X),Figures),not(member(f(ManColor,_,NewY,NewX),Figures)),%esli v nachalnoi tochke est figura, a v konechoi net figuri polzovatelya
designation(Figure,F),hod(F,Figures,Y,X,NewY,NewX),!,%esli eta figura mogla sdelat takoi hod
delete(f(_,_,NewY,NewX),Figures,TempFigures),%to raschishaem novoe mesto
add(f(ManColor,Figure,NewY,NewX),TempFigures,Temp2Figures),%dobavlyaem ee na novoe mesto
delete(f(_,_,Y,X),Temp2Figures,NewFigures),switch(ManColor,CompColor),%udalyaem ee so starogo mesta
random(10,S),sdvig_vlevo(NewFigures,S,SdvigFigures),%poluchivshuyusya novuyu rasstanovku svigaem vlevo na cluchainooe chislo
%esli bi etogo ne bulo, to comp bi hodil odnimi i temi zge figurami, pochemu - opisano dalshe
step_computer(CompColor,SdvigFigures).%peredaem hod compu
step(ManColor,Figures):-write("Vi vveli nepravilnii znacheniya!"),nl,step(ManColor,Figures).%znachit ne vipolnilos predidushee pravilo,
%te nedopustimue parametri ili nevozmozgnostsdelat takoi hod
%predicat hoda compa
step_computer(Color,Figures):-not(horoshii_hod(Color,Figures)),!,write("Vi pobedili!"),nl.%esli u kompa mat, to vivoditsya soobshenie o pobede
step_computer(Color,Figures):-
member(Figure,Figures),Figure=f(Color,_,_,_),switch(Color,OppColor),member(f(OppColor,_,NewY,NewX),Figures),
going_figure(Figures,Figure,NewY,NewX,NewFigures),%esli est takaya figura, chto mozhet za odin hod vzyat figuru protivnika, to imenno etot hod i sovershaetsya
show(Figures),step_man(OppColor,NewFigures). %pokazuvaetsya polozenie na doske do hoda i peredaetsya hod polzovatelyu
step_computer(Color,Figures):-%esli nelzya nikogo sest, to
member(Figure,Figures),Figure=f(Color,_,_,_),for(NewY,1,8),for(NewX,1,8),not(member(f(_,_,NewY,NewX),Figures)),%nahoditsya figura
going_figure(Figures,Figure,NewY,NewX,NewFigures),%kotoraya mogla bi shodit tak
can_eat(Color,NewFigures,NewY,NewX),%chto posle hoda ona nahoditsya na zashishennom pole, to delaetsy etot hod
show(Figures),switch(Color,OppColor),step_man(OppColor,NewFigures).
step_computer(Color,Figures):-%esli i tak ne poluchaetsya
member(Figure,Figures),Figure=f(Color,_,_,_),for(NewY,1,8),for(NewX,1,8),not(member(f(_,_,NewY,NewX),Figures)),
going_figure(Figures,Figure,NewY,NewX,NewFigures),
switch(Color,OppColor),not(can_eat(OppColor,NewFigures,NewY,NewX)), %to nahoditsya figura i ee hod, posle kotorogo ee nelzya srazu sest
show(Figures),step_man(OppColor,NewFigures).
step_computer(Color,Figures):-%a esli i eto nelzya, to togda lyuboi iz vozmozgih hodov
member(Figure,Figures),Figure=f(Color,_,_,_),for(NewY,1,8),for(NewX,1,8),not(member(f(_,_,NewY,NewX),Figures)),
going_figure(Figures,Figure,NewY,NewX,NewFigures),show(Figures),switch(Color,OppColor),step_man(OppColor,NewFigures).
%poskolku u nas hodyashaya figura vibiraetsya predicatom member, to beretsya pervaya figura iz
%spiska kotoraya mozget sdelat hod, i esli bi ne bilo sdviga cpiska vlevo na cluchainoe chislo,
%comp bi hodil malim kolochestvom figur
%predicat nahala igri. Peredayet od tomu kto igraet belimi
start_game('w'):-start_position(Figures),step_man('w',Figures).
start_game('b'):-start_position(Figures),step_computer('w',Figures).
%predicat igri. Zaprashivaet cvet i nachinaet igru
main:-write("Vvedite kakimi shahkami Vi hotite igrat (w-belie, b-chernii): "), readchar(ColorMan),nl, start_game(ColorMan).
GOAL
main.
|