Помогите с Прологом! Задача о шахматах (Есть код)

Компьютеры программирование шахматы

Вот код решения:
DOMAINS
позиция=integer
список_позиций=позиция*
позиции_фигуры=список_позиций*
имя_фигуры=symbol
список_имен_фигур=имя_фигуры*
имя_клетки=char
клетки_по_горизонтали=имя_клетки*
CONSTANTS
изначально_под_угрозой=26
фигуры=[ферзь,черныйСлон,белыйСлон,конь,конь,король]
фигуры_на_поле=['\2','\1','\252','\252','\252','\252','\252','\252']
/*Все фигуры, кроме ферзя заперты в квадрате - d4,d7,g7,g4; Наиболее большое покрытие*/
клеткиЧерногоСлона=[44,46,55,57,64,66,75,77]
клеткиБелогоСлона=[45,47,54,56,65,67,74,76]
клеткиКоня=[44,45,46,47,54,55,56,57,64,65,66,67,74,75,76,77]
клеткиКороля=[44,45,46,47,54,55,56,57,64,65,66,67,74,75,76,77]
/*Ферзь из соображений симметрии заперт в треуголнике - c3,c8,h8*/
клеткиФерзя=[33,34,35,36,37,38,44,45,46,47,48,55,56,57,58,66,67,68,77,78,88]
клеткиХодов=[клеткиФерзя,клеткиЧерногоСлона,клеткиБелогоСлона,клеткиКоня,клеткиКороля] % Клектки боя
такХодитФерзь=[-11,-10,-9,-1,1,9,10,11]
такХодитСлон=[-11,-9,9,11]
такХодитКонь=[-21,-19,-12,-8,8,12,19,21]
правилаДвиженияФигур=[такХодитФерзь,такХодитСлон,такХодитСлон,такХодитКонь,такХодитФерзь]
PREDICATES
nondeterm setFigs(список_имен_фигур,позиции_фигуры,позиции_фигуры,клетки_по_горизонтали,позиция,список_позиций) % Расставляем фигуры на поле 6х6
countNew(имя_фигуры,позиция,список_позиций,список_позиций,клетки_по_горизонтали,клетки_по_горизонтали,позиция,позиция) % Новая позиция фигур
countB(позиция,имя_фигуры,позиция,позиция,список_позиций,клетки_по_горизонтали,клетки_по_горизонтали,позиция,позиция)
check(позиция,имя_фигуры) % Проверка битых клеток
ifFiga(позиция,позиция,список_позиций,позиция)
setZero(позиция,клетки_по_горизонтали,клетки_по_горизонтали,позиция,позиция)
bits(позиция,имя_клетки)
del(имя_клетки,имя_клетки,позиция,позиция)
nondeterm member(список_позиций,позиция,список_позиций)
CLAUSES
setFigs([],_,_,фигуры_на_поле,изначально_под_угрозой,[]).
setFigs([Figa|Fh],[Boi|Bh],[Kletki|Klh],Pole,Bitye,[Fpoz|Poza]):-
not(Figa=конь), setFigs(Fh,Bh,Klh,Po,Bit,Poza), member(Kletki,Fpoz,_),
not(member(Poza,Fpoz,_)), countNew(Figa,Fpoz,Boi,Poza,Po,Pole,Bit,Bitye).
setFigs([конь,конь|Fh],[Boi|Bh],[Kletki|Klh],Pole,Bitye,[Fp2,Fp1|Poza]):-
setFigs(Fh,Bh,Klh,Po,Bit,Poza), member(Kletki,Fp1,Klet), not(member(Poza,Fp1,_)),
countNew(конь,Fp1,Boi,[],Po,Pole0,Bit,Bitye0), member(Klet,Fp2,_), not(member(Poza,Fp2,_)),
countNew(конь,Fp2,Boi,[],Pole0,Pole,Bitye0,Bitye).
countNew(Figa,Kletka,[B|Bh],Poza,Po,Pole,Bit,Bitye):-!,
countB(1,Figa,Kletka,B,Poza,Po,PoN,Bit,BitN),!,
countNew(Figa,Kletka,Bh,Poza,PoN,Pole,BitN,Bitye).
countNew(_,_,[],_,X,X,Y,Y).
countB(Sh,Figa,Kl,Boi,Poza,P,Pv,B,Bv):- check(Sh,Figa),
KlN=Kl+Boi, KlN<89, KlN>10, KlD=KlN mod 10, KlD<>0, KlD<>9,!,
setZero(KlN,P,Pn,B,Bn), ifFiga(Sh,KlN,Poza,ShN),!,
countB(ShN,Figa,KlN,Boi,Poza,Pn,Pv,Bn,Bv).
countB(_,_,_,_,_,X,X,Y,Y).
ifFiga(_,Kl,Poza,-1):- member(Poza,Kl,_),!.
ifFiga(Sh,_,_,ShN):- ShN=Sh+1.
check(-1,_):-!,fail.
check(2,король):-!,fail.
check(2,конь):-!,fail.
check(_,_).
setZero(Kl,[G|H1],[G|H2],B,Bn):- Kl>20,!, K=Kl-10,!, setZero(K,H1,H2,B,Bn).
setZero(Kl,[C|H],[Cn|H],B,Bn):- bits(Kl,Z), bitand(C,Z,Cn), del(C,Cn,B,Bn).
del(X,X,Y,Y):-!.
del(_,_,X,Y):- Y=X+1.
bits(11,'\254').
bits(12,'\253').
bits(13,'\251').
bits(14,'\247').
bits(15,'\239').
bits(16,'\223').
bits(17,'\191').
bits(18,'\127').
member([X|Y],X,Y).
member([_|X],Y,Z):- !,member(X,Y,Z).
GOAL setFigs(фигуры,правилаДвиженияФигур,клеткиХодов,_,Bac,Позиции), Bac=63.
Помогите понять почему фигуры на поле задаются такими константами? И что выполняют функции bits, countB, countNew?

Примечание:
Необходимо расставить фигуры с максимальной угрозой.

Примечание:
Ладьи стоят на месте! Все фигуры, кроме ферзя заперты в квадрате - d4,d7,g7,g4; Наиболее большое покрытие. Ферзь из соображений симметрии заперт в треуголнике - c3,c8,h8.

Примечание:
Малость изменил код! Может так понятнее будет! Ладьи на а2 и б1. Плиз Хелп!
PREDICATES
nondeterm рассталяемФигуры(список_имен_фигур,позиции_фигуры,позиции_фигуры,клетки_по_горизонтали,позиция,список_позиций)
двигаемФигуру(имя_фигуры,позиция,список_позиций,список_позиций,клетки_по_горизонтали,клетки_по_горизонтали,позиция,позиция)
количествоБитых(позиция,имя_фигуры,позиция,позиция,список_позиций,клетки_по_горизонтали,клетки_по_горизонтали,позиция,позиция)
проверка(позиция,имя_фигуры)
выборПозиции(позиция,позиция,список_позиций,позиция)
установкаНачала(позиция,клетки_по_горизонтали,клетки_по_горизонтали,позиция,позиция)
bits(позиция,имя_клетки)
del(имя_клетки,имя_клетки,позиция,позиция)
nondeterm member(список_позиций,позиция,список_позиций)
CLAUSES
рассталяемФигуры([Фигура|СписокФигур],[ПравилоБоя|СписокПравил],[ВозможныеХоды|СписокВозможныхХодов],РасстановкаНаПоле,КолвоБитыхКлеток,[ПозицияФигуры|СписокПозиций]):-
not(Фигура=конь), рассталяемФигуры(СписокФигур,СписокПравил,СписокВозможныхХодов,НаПоле,БитыеКлетки,СписокПозиций), member(ВозможныеХоды,ПозицияФигуры,_),
not(member(СписокПозиций,ПозицияФигуры,_)), двигаемФигуру(Фигура,ПозицияФигуры,ПравилоБоя,СписокПозиций,НаПоле,РасстановкаНаПоле,БитыеКлетки,КолвоБитыхКлеток).
рассталяемФигуры([конь,конь|СписокФигур],[ПравилоБоя|СписокПравил],[ВозможныеХоды|СписокВозможныхХодов],РасстановкаНаПоле,КолвоБитыхКлеток,[ПозицияКоня2,ПозицияКоня1|СписокПозиций]):-
рассталяемФигуры(СписокФигур,СписокПравил,СписокВозможныхХодов,НаПоле,БитыеКлетки,СписокПозиций), member(ВозможныеХоды,ПозицияКоня1,Клетки), not(member(СписокПозиций,ПозицияКоня1,_)),
двигаемФигуру(конь,ПозицияКоня1,ПравилоБоя,[],НаПоле,РасстановкаНаПоле0,БитыеКлетки,КолвоБитыхКлеток0), member(Клетки,ПозицияКоня2,_), not(member(СписокПозиций,ПозицияКоня2,_)),
двигаемФигуру(конь,ПозицияКоня2,ПравилоБоя,[],РасстановкаНаПоле0,РасстановкаНаПоле,КолвоБитыхКлеток0,КолвоБитыхКлеток).
рассталяемФигуры([],_,_,фигуры_на_поле,изначально_под_угрозой,[]).
двигаемФигуру(Фигура,ГдеСтоит,[Правило|СписокПравил],СписокПозиций,Поле,РасстановкаНаПоле,БитыеКлетки,КолвоБитыхКлеток):-!,
количествоБитых(1,Фигура,ГдеСтоит,Правило,СписокПозиций,Поле,ПолеN,БитыеКлетки,BitN),!,
двигаемФигуру(Фигура,ГдеСтоит,СписокПравил,СписокПозиций,ПолеN,РасстановкаНаПоле,BitN,КолвоБитыхКлеток).
двигаемФигуру(_,_,[],_,X,X,Y,Y).
количествоБитых(Sh,Фигура,Kl,ПравилоБоя,СписокПозиций,P,Pv,B,Bv):- проверка(Sh,Фигура),
KlN=Kl+ПравилоБоя, KlN<89, KlN>10, KlD=KlN mod 10, KlD<>0, KlD<>9,!,
установкаНачала(KlN,P,Pn,B,Bn), выборПозиции(Sh,KlN,СписокПозиций,ShN),!,
количествоБитых(ShN,Фигура,KlN,ПравилоБоя,СписокПозиций,Pn,Pv,Bn,Bv).
количествоБитых(_,_,_,_,_,X,X,Y,Y).
выборПозиции(_,Kl,СписокПозиций,-1):- member(СписокПозиций,Kl,_),!.
выборПозиции(Sh,_,_,ShN):- ShN=Sh+1.
проверка(-1,_):-!,fail.
проверка(2,король):-!,fail.
проверка(2,конь):-!,fail.
проверка(_,_).
установкаНачала(Kl,[G|H1],[G|H2],B,Bn):- Kl>20,!, K=Kl-10,!, установкаНачала(K,H1,H2,B,Bn).
установкаНачала(Kl,[C|H],[Cn|H],B,Bn):- bits(Kl,Z), bitand(C,Z,Cn), del(C,Cn,B,Bn).
del(X,X,Y,Y):-!.
del(_,_,X,Y):- Y=X+1.
bits(11,'\254').
bits(12,'\253').
bits(13,'\251').
bits(14,'\247').
bits(15,'\239').
bits(16,'\223').
bits(17,'\191').
bits(18,'\127').
member([X|Y],X,Y).
member([_|X],Y,Z):- !, member(X,Y,Z).
GOAL рассталяемФигуры(фигуры,правилаДвиженияФигур,клеткиХодов,_,Побито,Расстановка), Побито=63.
Ответы:
Вы у Пролога-то понимаете в чём соль? На всякий случай - это не процедурный язык, а скорее язык фактов и правил. bits, countB, countNew это не функции а предикаты, или факты-правила. Фраза bits(18,'\127'). означает  "18 бьёт (bits) '\127' " то есть утверждается такой факт. Соответственно, предикат (а не функция) countB используется для установления правил. countB(_,_,_,_,_,X,X,Y,Y). означает: "утверждение countB верно для любых пяти первых его аргументов, при условии что 6 и 7, а также 8 и 9 совпадают (унифицируются)"
Судя по комментариям в коде, bits - это правило кто кого бьёт, countB устанавливает правило для подсчёта количества битых, countNew - правило перехода к следующей позиции
идея бредовая или брэдовая? :)


14 лет назад

RPI.su - самая большая русскоязычная база вопросов и ответов. Наш проект был реализован как продолжение популярного сервиса otvety.google.ru, который был закрыт и удален 30 апреля 2015 года. Мы решили воскресить полезный сервис Ответы Гугл, чтобы любой человек смог публично узнать ответ на свой вопрос у интернет сообщества.

Все вопросы, добавленные на сайт ответов Google, мы скопировали и сохранили здесь. Имена старых пользователей также отображены в том виде, в котором они существовали ранее. Только нужно заново пройти регистрацию, чтобы иметь возможность задавать вопросы, или отвечать другим.

Чтобы связаться с нами по любому вопросу О САЙТЕ (реклама, сотрудничество, отзыв о сервисе), пишите на почту [email protected]. Только все общие вопросы размещайте на сайте, на них ответ по почте не предоставляется.