Компьютерный форум
Правила
Вернуться   Компьютерный форум > Форум программистов > Языки программирования > Prolog
Перезагрузить страницу слоны на шахматной доске
Ответ
 
Опции темы Опции просмотра
  (#1 (permalink)) Старый
dkarm dkarm вне форума
Новичок
 
Сообщений: 5
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 11.11.2007
По умолчанию 23.12.2007, 13:37

Помогите пожалуйсьа разобраться! Есть программа которая расставляет максимальное количество слонов на шахматной доске. но максимальное колисчество у нее получается 12 слнов. а вариант с 14ю (например когда восемь на первой горизонтале и шесть на восьмой) не выдает никак. Подскажите можно ли побыстрорму эту прогу исправить чтобы реально максимальное число слонов на доске не бьющих друг друга искала. Очень срочно нужно, уповаю...

Код:
Global domains
ФФФ = слон
Угол = наискось
Дальность = линия; рядом
Бъёт = бъёт(Дальность,Угол)
Строка = string
Строки = Строка*
Поле = поле(Строка,Строка)

Global predicates
поставить_фигуры(ФФФ)

predicates
nondeterm правило(ФФФ,Бъёт)
разметка1(Строки)
разметка2(Строки)

clauses
% правила боя фигур

правило(слон,бъёт(линия,наискось)).

% размеры доски по вертикали и по горизонтали
разметка1(["1","2","3","4","5","6","7","8"]).
разметка2(["a","b","c","d","e","f","g","h"]).

database - расстановки
% факт -  места где стоят фигуры
стоит(ФФФ,Поле)

domains
Напр = /*влево; вправо; вверх; вниз;*/ вниз_влево; вниз_вправо;
    вверх_влево; вверх_вправо

%
% служебные процедуры перебора клеток
% для "понимания" правил компьютером
% заметьте, здесь "понимание" идет такое же как и человеком
% и нет ни одной математической операции.
% все построено на фактах
%
predicates
nondeterm перебор_списка_как_фактов(Строки,Строка).
элемент_слева(Строки,Строка Элемент, Строка ЭлементСлева)
элемент_справа(Строки,Строка Элемент, Строка ЭлементСправа)
поле_слева(Поле, Поле Находим)
поле_справа(Поле, Поле Находим)
поле_сверху(Поле, Поле Находим)
поле_снизу(Поле, Поле Находим)
поле_рядом(Угол,Поле,Поле Рядом)
nondeterm поле_рядом(Угол,Напр,Поле,Поле Рядом)
поле_линия(Угол,Поле,Поле Линия)


clauses
% перебирает элементы списка как факты базы ПРОЛОГа
% это позволяет включить механизм отката
перебор_списка_как_фактов([Строка|_],Строка).
перебор_списка_как_фактов([_|Строки],Строка):-
    перебор_списка_как_фактов(Строки,Строка).

% найдет элемент слева от данного в списке
элемент_слева([ЭлементСлева,Элемент|_],Элемент,ЭлементСлева):-
    !.
элемент_слева([_|Список],Элемент,ЭлементСлева):-
    элемент_слева(Список,Элемент,ЭлементСлева),
    !.
% найдет элемент справа от данного в списке
элемент_справа([Элемент,ЭлементСправа|_],Элемент,ЭлементСправа):-
    !.
элемент_справа([_|Список],Элемент,ЭлементСправа):-
    элемент_справа(Список,Элемент,ЭлементСправа),
    !.
% берет поле рядом
поле_слева(поле(Число,Буква),поле(ЧислоСлева,Буква)):-
    разметка1(Числа),
    элемент_слева(Числа,Число,ЧислоСлева),
    !.
поле_справа(поле(Число,Буква),поле(ЧислоСправа,Буква)):-
    разметка1(Числа),
    элемент_справа(Числа,Число,ЧислоСправа),
    !.
поле_сверху(поле(Число,Буква),поле(Число,БукваСверху)):-
    разметка2(Буквы),
    элемент_слева(Буквы,Буква,БукваСверху),
    !.
поле_снизу(поле(Число,Буква),поле(Число,БукваСнизу)):-
    разметка2(Буквы),
    элемент_справа(Буквы,Буква,БукваСнизу),
    !.

% перебирает все поля рядом в соответствии с углом боя
% то же, но поля рядом с углом боя ”наискось”
поле_рядом(наискось,Поле,Поле1):-
    поле_слева(Поле,Поле0),
    поле_снизу(Поле0,Поле1),!.
поле_рядом(наискось,Поле,Поле1):-
    поле_справа(Поле,Поле0),
    поле_снизу(Поле0,Поле1),!.
поле_рядом(наискось,Поле,Поле1):-
    поле_слева(Поле,Поле0),
    поле_сверху(Поле0,Поле1),!.
поле_рядом(наискось,Поле,Поле1):-
    поле_справа(Поле,Поле0),
    поле_сверху(Поле0,Поле1),!.


% перебор всех полей по линии боя ”наискось”
поле_рядом(наискось,вниз_влево,Поле,Поле1):-
    поле_слева(Поле,Поле0),
    поле_снизу(Поле0,Поле1).
поле_рядом(наискось,вниз_влево,Поле,Поле1):-
    поле_слева(Поле,Поле0),
    поле_снизу(Поле0,Поле2),
    поле_рядом(наискось,вниз_влево,Поле2,Поле1).

поле_рядом(наискось,вниз_вправо,Поле,Поле1):-
    поле_справа(Поле,Поле0),
    поле_снизу(Поле0,Поле1).
поле_рядом(наискось,вниз_вправо,Поле,Поле1):-
    поле_справа(Поле,Поле0),
    поле_снизу(Поле0,Поле2),
    поле_рядом(наискось,вниз_вправо,Поле2,Поле1).

поле_рядом(наискось,вверх_влево,Поле,Поле1):-
    поле_слева(Поле,Поле0),
    поле_сверху(Поле0,Поле1).
поле_рядом(наискось,вверх_влево,Поле,Поле1):-
    поле_слева(Поле,Поле0),
    поле_сверху(Поле0,Поле2),
    поле_рядом(наискось,вверх_влево,Поле2,Поле1).

поле_рядом(наискось,вверх_вправо,Поле,Поле1):-
    поле_справа(Поле,Поле0),
    поле_сверху(Поле0,Поле1).
поле_рядом(наискось,вверх_вправо,Поле,Поле1):-
    поле_справа(Поле,Поле0),
    поле_сверху(Поле0,Поле2),
    поле_рядом(наискось,вверх_вправо,Поле2,Поле1).

% если поля находятся на линии боя

поле_линия(наискось,Поле,Поле1):-
    поле_рядом(наискось,вверх_влево,Поле,Поле1),!.
поле_линия(наискось,Поле,Поле1):-
    поле_рядом(наискось,вниз_вправо,Поле,Поле1),!.
поле_линия(наискось,Поле,Поле1):-
    поле_рядом(наискось,вниз_влево,Поле,Поле1),!.
поле_линия(наискось,Поле,Поле1):-
    поле_рядом(наискось,вверх_вправо,Поле,Поле1),!.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% сам механизм выбора полей 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
predicates
фигура_под_боем2(Поле Из,Бъёт,Поле)
фигура_под_боем1(Поле Из,Бъёт,Поле)
фигура_под_боем(ФФФ,Поле)
фигуры_не_под_боем(ФФФ,Поле)
nondeterm выбрать_поле_на_доске(Поле)
поставить_фигуры1(ФФФ,integer)
поставить_фигуру(ФФФ)

clauses
% берёт клетку на доске, в которую еще не ставили
% фигуру
выбрать_поле_на_доске(поле(Число,Буква)):-
    разметка1(Числа),
    разметка2(Буквы),
    перебор_списка_как_фактов(Числа,Число),
    перебор_списка_как_фактов(Буквы,Буква).

% определяет – стоят ли две фигуры под боем
%
% если это место уже занято
фигура_под_боем2(Поле,_,Поле):-!.
фигура_под_боем2(ПолеИз,бъёт(рядом,Напр),Поле):-
% если фигура стоит рядом и по направлению боя
    поле_рядом(Напр,ПолеИз,Поле),
    !.
фигура_под_боем2(ПолеИз,бъёт(линия,Напр),Поле):-
% если фигура стоит на линии боя
    поле_линия(Напр,ПолеИз,Поле),
    !.
% фигура под боем которую ставим
фигура_под_боем1(ПолеИз,Бъёт,Поле):-
    фигура_под_боем2(ПолеИз,Бъёт,Поле),
    !.
% фигура под боем, которя уже стоит
фигура_под_боем1(ПолеИз,Бъёт,Поле):-
    фигура_под_боем2(Поле,Бъёт,ПолеИз),
    !.
    
% фигура под боем
фигура_под_боем(Фигура,Поле):-
% перебор правил для фигуры
    правило(Фигура,Бъёт),
% перебор других фигур на доске
    стоит(_,ПолеИз),
% если Фигура с Правилом боя бьёт из своих координат данную клетку
% или наоборот
    фигура_под_боем1(ПолеИз,Бъёт,Поле),
% то фигура под боем
    !.    
% удостовериться что фигура не под боем
фигуры_не_под_боем(Фигура,Поле):-
    not(фигура_под_боем(Фигура,Поле)),
    !.

% ставит одну фигуру на доску
поставить_фигуру(Фигура):-
% берет любое поле
    выбрать_поле_на_доске(Поле),
% если фигура на этом поле не будет побита
% и не побьёт другую фигуру
    фигуры_не_под_боем(Фигура,Поле),
% то поставим её на доску
    assertz(стоит(Фигура,Поле)),
    
    !.
% расставляет фигуры на доске
поставить_фигуры1(Фигура,Count):-
    поставить_фигуру(Фигура),
    Num=Count+1,
    Num<=11,!,
    поставить_фигуры1(Фигура,Num),
    !.
поставить_фигуры1(Фигура,Count):-
% вывести вариант с расстановкой
    Count>=11,!,
    nl,write("вариант для ", Фигура),
    стоит(Фигура,Поле),
    write(" ",Поле),
    fail.
    
поставить_фигуры(Фигура):-
% начальная подготовка
% перебор всех поле
    выбрать_поле_на_доске(Поле), 
% очистить знания
    retractall(_,расстановки),
% поставить первую фигуру
    assertz(стоит(Фигура,Поле)),
    поставить_фигуры1(Фигура,0),
    !.

/* вызов предиката рсстановки */
Goal поставить_фигуры(слон).
Ответить с цитированием
  (#2 (permalink)) Старый
dkarm dkarm вне форума
Новичок
 
Сообщений: 5
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 11.11.2007
По умолчанию 23.12.2007, 13:37

Помогите пожалуйсьа разобраться! Есть программа которая расставляет максимальное количество слонов на шахматной доске. но максимальное колисчество у нее получается 12 слнов. а вариант с 14ю (например когда восемь на первой горизонтале и шесть на восьмой) не выдает никак. Подскажите можно ли побыстрорму эту прогу исправить чтобы реально максимальное число слонов на доске не бьющих друг друга искала. Очень срочно нужно, уповаю...

Код:
Global domains
ФФФ = слон
Угол = наискось
Дальность = линия; рядом
Бъёт = бъёт(Дальность,Угол)
Строка = string
Строки = Строка*
Поле = поле(Строка,Строка)

Global predicates
поставить_фигуры(ФФФ)

predicates
nondeterm правило(ФФФ,Бъёт)
разметка1(Строки)
разметка2(Строки)

clauses
% правила боя фигур

правило(слон,бъёт(линия,наискось)).

% размеры доски по вертикали и по горизонтали
разметка1(["1","2","3","4","5","6","7","8"]).
разметка2(["a","b","c","d","e","f","g","h"]).

database - расстановки
% факт -  места где стоят фигуры
стоит(ФФФ,Поле)

domains
Напр = /*влево; вправо; вверх; вниз;*/ вниз_влево; вниз_вправо;
    вверх_влево; вверх_вправо

%
% служебные процедуры перебора клеток
% для "понимания" правил компьютером
% заметьте, здесь "понимание" идет такое же как и человеком
% и нет ни одной математической операции.
% все построено на фактах
%
predicates
nondeterm перебор_списка_как_фактов(Строки,Строка).
элемент_слева(Строки,Строка Элемент, Строка ЭлементСлева)
элемент_справа(Строки,Строка Элемент, Строка ЭлементСправа)
поле_слева(Поле, Поле Находим)
поле_справа(Поле, Поле Находим)
поле_сверху(Поле, Поле Находим)
поле_снизу(Поле, Поле Находим)
поле_рядом(Угол,Поле,Поле Рядом)
nondeterm поле_рядом(Угол,Напр,Поле,Поле Рядом)
поле_линия(Угол,Поле,Поле Линия)


clauses
% перебирает элементы списка как факты базы ПРОЛОГа
% это позволяет включить механизм отката
перебор_списка_как_фактов([Строка|_],Строка).
перебор_списка_как_фактов([_|Строки],Строка):-
    перебор_списка_как_фактов(Строки,Строка).

% найдет элемент слева от данного в списке
элемент_слева([ЭлементСлева,Элемент|_],Элемент,ЭлементСлева):-
    !.
элемент_слева([_|Список],Элемент,ЭлементСлева):-
    элемент_слева(Список,Элемент,ЭлементСлева),
    !.
% найдет элемент справа от данного в списке
элемент_справа([Элемент,ЭлементСправа|_],Элемент,ЭлементСправа):-
    !.
элемент_справа([_|Список],Элемент,ЭлементСправа):-
    элемент_справа(Список,Элемент,ЭлементСправа),
    !.
% берет поле рядом
поле_слева(поле(Число,Буква),поле(ЧислоСлева,Буква)):-
    разметка1(Числа),
    элемент_слева(Числа,Число,ЧислоСлева),
    !.
поле_справа(поле(Число,Буква),поле(ЧислоСправа,Буква)):-
    разметка1(Числа),
    элемент_справа(Числа,Число,ЧислоСправа),
    !.
поле_сверху(поле(Число,Буква),поле(Число,БукваСверху)):-
    разметка2(Буквы),
    элемент_слева(Буквы,Буква,БукваСверху),
    !.
поле_снизу(поле(Число,Буква),поле(Число,БукваСнизу)):-
    разметка2(Буквы),
    элемент_справа(Буквы,Буква,БукваСнизу),
    !.

% перебирает все поля рядом в соответствии с углом боя
% то же, но поля рядом с углом боя ”наискось”
поле_рядом(наискось,Поле,Поле1):-
    поле_слева(Поле,Поле0),
    поле_снизу(Поле0,Поле1),!.
поле_рядом(наискось,Поле,Поле1):-
    поле_справа(Поле,Поле0),
    поле_снизу(Поле0,Поле1),!.
поле_рядом(наискось,Поле,Поле1):-
    поле_слева(Поле,Поле0),
    поле_сверху(Поле0,Поле1),!.
поле_рядом(наискось,Поле,Поле1):-
    поле_справа(Поле,Поле0),
    поле_сверху(Поле0,Поле1),!.


% перебор всех полей по линии боя ”наискось”
поле_рядом(наискось,вниз_влево,Поле,Поле1):-
    поле_слева(Поле,Поле0),
    поле_снизу(Поле0,Поле1).
поле_рядом(наискось,вниз_влево,Поле,Поле1):-
    поле_слева(Поле,Поле0),
    поле_снизу(Поле0,Поле2),
    поле_рядом(наискось,вниз_влево,Поле2,Поле1).

поле_рядом(наискось,вниз_вправо,Поле,Поле1):-
    поле_справа(Поле,Поле0),
    поле_снизу(Поле0,Поле1).
поле_рядом(наискось,вниз_вправо,Поле,Поле1):-
    поле_справа(Поле,Поле0),
    поле_снизу(Поле0,Поле2),
    поле_рядом(наискось,вниз_вправо,Поле2,Поле1).

поле_рядом(наискось,вверх_влево,Поле,Поле1):-
    поле_слева(Поле,Поле0),
    поле_сверху(Поле0,Поле1).
поле_рядом(наискось,вверх_влево,Поле,Поле1):-
    поле_слева(Поле,Поле0),
    поле_сверху(Поле0,Поле2),
    поле_рядом(наискось,вверх_влево,Поле2,Поле1).

поле_рядом(наискось,вверх_вправо,Поле,Поле1):-
    поле_справа(Поле,Поле0),
    поле_сверху(Поле0,Поле1).
поле_рядом(наискось,вверх_вправо,Поле,Поле1):-
    поле_справа(Поле,Поле0),
    поле_сверху(Поле0,Поле2),
    поле_рядом(наискось,вверх_вправо,Поле2,Поле1).

% если поля находятся на линии боя

поле_линия(наискось,Поле,Поле1):-
    поле_рядом(наискось,вверх_влево,Поле,Поле1),!.
поле_линия(наискось,Поле,Поле1):-
    поле_рядом(наискось,вниз_вправо,Поле,Поле1),!.
поле_линия(наискось,Поле,Поле1):-
    поле_рядом(наискось,вниз_влево,Поле,Поле1),!.
поле_линия(наискось,Поле,Поле1):-
    поле_рядом(наискось,вверх_вправо,Поле,Поле1),!.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% сам механизм выбора полей 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
predicates
фигура_под_боем2(Поле Из,Бъёт,Поле)
фигура_под_боем1(Поле Из,Бъёт,Поле)
фигура_под_боем(ФФФ,Поле)
фигуры_не_под_боем(ФФФ,Поле)
nondeterm выбрать_поле_на_доске(Поле)
поставить_фигуры1(ФФФ,integer)
поставить_фигуру(ФФФ)

clauses
% берёт клетку на доске, в которую еще не ставили
% фигуру
выбрать_поле_на_доске(поле(Число,Буква)):-
    разметка1(Числа),
    разметка2(Буквы),
    перебор_списка_как_фактов(Числа,Число),
    перебор_списка_как_фактов(Буквы,Буква).

% определяет – стоят ли две фигуры под боем
%
% если это место уже занято
фигура_под_боем2(Поле,_,Поле):-!.
фигура_под_боем2(ПолеИз,бъёт(рядом,Напр),Поле):-
% если фигура стоит рядом и по направлению боя
    поле_рядом(Напр,ПолеИз,Поле),
    !.
фигура_под_боем2(ПолеИз,бъёт(линия,Напр),Поле):-
% если фигура стоит на линии боя
    поле_линия(Напр,ПолеИз,Поле),
    !.
% фигура под боем которую ставим
фигура_под_боем1(ПолеИз,Бъёт,Поле):-
    фигура_под_боем2(ПолеИз,Бъёт,Поле),
    !.
% фигура под боем, которя уже стоит
фигура_под_боем1(ПолеИз,Бъёт,Поле):-
    фигура_под_боем2(Поле,Бъёт,ПолеИз),
    !.
    
% фигура под боем
фигура_под_боем(Фигура,Поле):-
% перебор правил для фигуры
    правило(Фигура,Бъёт),
% перебор других фигур на доске
    стоит(_,ПолеИз),
% если Фигура с Правилом боя бьёт из своих координат данную клетку
% или наоборот
    фигура_под_боем1(ПолеИз,Бъёт,Поле),
% то фигура под боем
    !.    
% удостовериться что фигура не под боем
фигуры_не_под_боем(Фигура,Поле):-
    not(фигура_под_боем(Фигура,Поле)),
    !.

% ставит одну фигуру на доску
поставить_фигуру(Фигура):-
% берет любое поле
    выбрать_поле_на_доске(Поле),
% если фигура на этом поле не будет побита
% и не побьёт другую фигуру
    фигуры_не_под_боем(Фигура,Поле),
% то поставим её на доску
    assertz(стоит(Фигура,Поле)),
    
    !.
% расставляет фигуры на доске
поставить_фигуры1(Фигура,Count):-
    поставить_фигуру(Фигура),
    Num=Count+1,
    Num<=11,!,
    поставить_фигуры1(Фигура,Num),
    !.
поставить_фигуры1(Фигура,Count):-
% вывести вариант с расстановкой
    Count>=11,!,
    nl,write("вариант для ", Фигура),
    стоит(Фигура,Поле),
    write(" ",Поле),
    fail.
    
поставить_фигуры(Фигура):-
% начальная подготовка
% перебор всех поле
    выбрать_поле_на_доске(Поле), 
% очистить знания
    retractall(_,расстановки),
% поставить первую фигуру
    assertz(стоит(Фигура,Поле)),
    поставить_фигуры1(Фигура,0),
    !.

/* вызов предиката рсстановки */
Goal поставить_фигуры(слон).
Ответить с цитированием
  (#3 (permalink)) Старый
dkarm dkarm вне форума
Новичок
 
Сообщений: 5
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 11.11.2007
По умолчанию 23.12.2007, 13:37

Помогите пожалуйсьа разобраться! Есть программа которая расставляет максимальное количество слонов на шахматной доске. но максимальное колисчество у нее получается 12 слнов. а вариант с 14ю (например когда восемь на первой горизонтале и шесть на восьмой) не выдает никак. Подскажите можно ли побыстрорму эту прогу исправить чтобы реально максимальное число слонов на доске не бьющих друг друга искала. Очень срочно нужно, уповаю...

Код:
Global domains
ФФФ = слон
Угол = наискось
Дальность = линия; рядом
Бъёт = бъёт(Дальность,Угол)
Строка = string
Строки = Строка*
Поле = поле(Строка,Строка)

Global predicates
поставить_фигуры(ФФФ)

predicates
nondeterm правило(ФФФ,Бъёт)
разметка1(Строки)
разметка2(Строки)

clauses
% правила боя фигур

правило(слон,бъёт(линия,наискось)).

% размеры доски по вертикали и по горизонтали
разметка1(["1","2","3","4","5","6","7","8"]).
разметка2(["a","b","c","d","e","f","g","h"]).

database - расстановки
% факт -  места где стоят фигуры
стоит(ФФФ,Поле)

domains
Напр = /*влево; вправо; вверх; вниз;*/ вниз_влево; вниз_вправо;
    вверх_влево; вверх_вправо

%
% служебные процедуры перебора клеток
% для "понимания" правил компьютером
% заметьте, здесь "понимание" идет такое же как и человеком
% и нет ни одной математической операции.
% все построено на фактах
%
predicates
nondeterm перебор_списка_как_фактов(Строки,Строка).
элемент_слева(Строки,Строка Элемент, Строка ЭлементСлева)
элемент_справа(Строки,Строка Элемент, Строка ЭлементСправа)
поле_слева(Поле, Поле Находим)
поле_справа(Поле, Поле Находим)
поле_сверху(Поле, Поле Находим)
поле_снизу(Поле, Поле Находим)
поле_рядом(Угол,Поле,Поле Рядом)
nondeterm поле_рядом(Угол,Напр,Поле,Поле Рядом)
поле_линия(Угол,Поле,Поле Линия)


clauses
% перебирает элементы списка как факты базы ПРОЛОГа
% это позволяет включить механизм отката
перебор_списка_как_фактов([Строка|_],Строка).
перебор_списка_как_фактов([_|Строки],Строка):-
    перебор_списка_как_фактов(Строки,Строка).

% найдет элемент слева от данного в списке
элемент_слева([ЭлементСлева,Элемент|_],Элемент,ЭлементСлева):-
    !.
элемент_слева([_|Список],Элемент,ЭлементСлева):-
    элемент_слева(Список,Элемент,ЭлементСлева),
    !.
% найдет элемент справа от данного в списке
элемент_справа([Элемент,ЭлементСправа|_],Элемент,ЭлементСправа):-
    !.
элемент_справа([_|Список],Элемент,ЭлементСправа):-
    элемент_справа(Список,Элемент,ЭлементСправа),
    !.
% берет поле рядом
поле_слева(поле(Число,Буква),поле(ЧислоСлева,Буква)):-
    разметка1(Числа),
    элемент_слева(Числа,Число,ЧислоСлева),
    !.
поле_справа(поле(Число,Буква),поле(ЧислоСправа,Буква)):-
    разметка1(Числа),
    элемент_справа(Числа,Число,ЧислоСправа),
    !.
поле_сверху(поле(Число,Буква),поле(Число,БукваСверху)):-
    разметка2(Буквы),
    элемент_слева(Буквы,Буква,БукваСверху),
    !.
поле_снизу(поле(Число,Буква),поле(Число,БукваСнизу)):-
    разметка2(Буквы),
    элемент_справа(Буквы,Буква,БукваСнизу),
    !.

% перебирает все поля рядом в соответствии с углом боя
% то же, но поля рядом с углом боя ”наискось”
поле_рядом(наискось,Поле,Поле1):-
    поле_слева(Поле,Поле0),
    поле_снизу(Поле0,Поле1),!.
поле_рядом(наискось,Поле,Поле1):-
    поле_справа(Поле,Поле0),
    поле_снизу(Поле0,Поле1),!.
поле_рядом(наискось,Поле,Поле1):-
    поле_слева(Поле,Поле0),
    поле_сверху(Поле0,Поле1),!.
поле_рядом(наискось,Поле,Поле1):-
    поле_справа(Поле,Поле0),
    поле_сверху(Поле0,Поле1),!.


% перебор всех полей по линии боя ”наискось”
поле_рядом(наискось,вниз_влево,Поле,Поле1):-
    поле_слева(Поле,Поле0),
    поле_снизу(Поле0,Поле1).
поле_рядом(наискось,вниз_влево,Поле,Поле1):-
    поле_слева(Поле,Поле0),
    поле_снизу(Поле0,Поле2),
    поле_рядом(наискось,вниз_влево,Поле2,Поле1).

поле_рядом(наискось,вниз_вправо,Поле,Поле1):-
    поле_справа(Поле,Поле0),
    поле_снизу(Поле0,Поле1).
поле_рядом(наискось,вниз_вправо,Поле,Поле1):-
    поле_справа(Поле,Поле0),
    поле_снизу(Поле0,Поле2),
    поле_рядом(наискось,вниз_вправо,Поле2,Поле1).

поле_рядом(наискось,вверх_влево,Поле,Поле1):-
    поле_слева(Поле,Поле0),
    поле_сверху(Поле0,Поле1).
поле_рядом(наискось,вверх_влево,Поле,Поле1):-
    поле_слева(Поле,Поле0),
    поле_сверху(Поле0,Поле2),
    поле_рядом(наискось,вверх_влево,Поле2,Поле1).

поле_рядом(наискось,вверх_вправо,Поле,Поле1):-
    поле_справа(Поле,Поле0),
    поле_сверху(Поле0,Поле1).
поле_рядом(наискось,вверх_вправо,Поле,Поле1):-
    поле_справа(Поле,Поле0),
    поле_сверху(Поле0,Поле2),
    поле_рядом(наискось,вверх_вправо,Поле2,Поле1).

% если поля находятся на линии боя

поле_линия(наискось,Поле,Поле1):-
    поле_рядом(наискось,вверх_влево,Поле,Поле1),!.
поле_линия(наискось,Поле,Поле1):-
    поле_рядом(наискось,вниз_вправо,Поле,Поле1),!.
поле_линия(наискось,Поле,Поле1):-
    поле_рядом(наискось,вниз_влево,Поле,Поле1),!.
поле_линия(наискось,Поле,Поле1):-
    поле_рядом(наискось,вверх_вправо,Поле,Поле1),!.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% сам механизм выбора полей 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
predicates
фигура_под_боем2(Поле Из,Бъёт,Поле)
фигура_под_боем1(Поле Из,Бъёт,Поле)
фигура_под_боем(ФФФ,Поле)
фигуры_не_под_боем(ФФФ,Поле)
nondeterm выбрать_поле_на_доске(Поле)
поставить_фигуры1(ФФФ,integer)
поставить_фигуру(ФФФ)

clauses
% берёт клетку на доске, в которую еще не ставили
% фигуру
выбрать_поле_на_доске(поле(Число,Буква)):-
    разметка1(Числа),
    разметка2(Буквы),
    перебор_списка_как_фактов(Числа,Число),
    перебор_списка_как_фактов(Буквы,Буква).

% определяет – стоят ли две фигуры под боем
%
% если это место уже занято
фигура_под_боем2(Поле,_,Поле):-!.
фигура_под_боем2(ПолеИз,бъёт(рядом,Напр),Поле):-
% если фигура стоит рядом и по направлению боя
    поле_рядом(Напр,ПолеИз,Поле),
    !.
фигура_под_боем2(ПолеИз,бъёт(линия,Напр),Поле):-
% если фигура стоит на линии боя
    поле_линия(Напр,ПолеИз,Поле),
    !.
% фигура под боем которую ставим
фигура_под_боем1(ПолеИз,Бъёт,Поле):-
    фигура_под_боем2(ПолеИз,Бъёт,Поле),
    !.
% фигура под боем, которя уже стоит
фигура_под_боем1(ПолеИз,Бъёт,Поле):-
    фигура_под_боем2(Поле,Бъёт,ПолеИз),
    !.
    
% фигура под боем
фигура_под_боем(Фигура,Поле):-
% перебор правил для фигуры
    правило(Фигура,Бъёт),
% перебор других фигур на доске
    стоит(_,ПолеИз),
% если Фигура с Правилом боя бьёт из своих координат данную клетку
% или наоборот
    фигура_под_боем1(ПолеИз,Бъёт,Поле),
% то фигура под боем
    !.    
% удостовериться что фигура не под боем
фигуры_не_под_боем(Фигура,Поле):-
    not(фигура_под_боем(Фигура,Поле)),
    !.

% ставит одну фигуру на доску
поставить_фигуру(Фигура):-
% берет любое поле
    выбрать_поле_на_доске(Поле),
% если фигура на этом поле не будет побита
% и не побьёт другую фигуру
    фигуры_не_под_боем(Фигура,Поле),
% то поставим её на доску
    assertz(стоит(Фигура,Поле)),
    
    !.
% расставляет фигуры на доске
поставить_фигуры1(Фигура,Count):-
    поставить_фигуру(Фигура),
    Num=Count+1,
    Num<=11,!,
    поставить_фигуры1(Фигура,Num),
    !.
поставить_фигуры1(Фигура,Count):-
% вывести вариант с расстановкой
    Count>=11,!,
    nl,write("вариант для ", Фигура),
    стоит(Фигура,Поле),
    write(" ",Поле),
    fail.
    
поставить_фигуры(Фигура):-
% начальная подготовка
% перебор всех поле
    выбрать_поле_на_доске(Поле), 
% очистить знания
    retractall(_,расстановки),
% поставить первую фигуру
    assertz(стоит(Фигура,Поле)),
    поставить_фигуры1(Фигура,0),
    !.

/* вызов предиката рсстановки */
Goal поставить_фигуры(слон).
Ответить с цитированием
  (#4 (permalink)) Старый
Alison Alison вне форума
Member
 
Сообщений: 4,781
Сказал(а) спасибо: 0
Поблагодарили 119 раз(а) в 116 сообщениях
Регистрация: 17.11.2004
По умолчанию 24.12.2007, 23:32

Я не знаю, можно ли по-быстрому исправить эту программу.
А вот как расставить слонов, я уже писала:
http://www.hardforum.ru/t75864
Вот пример, как найти одну расстановку слонов, первую попавшуюся. Но все расстановки на доске 8x8 так не найти, надо делать более тонко.
Код:
domains
bishop    = q(integer, integer)
bishops   = bishop*
freelist = integer*
board    = board(bishops, freelist, freelist)
predicates
nondeterm placeN(integer,integer,board,board)
nondeterm place_a_bishop(integer,board,board)
determ nbishops(integer SizeOfBoard,integer NumberOfQ)
determ makelist(integer, freelist)
nondeterm findandremove(integer, freelist, freelist)
clauses
nbishops(N,Q):-
    Diagonal=N*2-1,
    makelist(Diagonal,LL),
    placeN(N,Q,board([],LL,LL),Final),
    Final=board(Bishops,_,_),
    !,
    write(Bishops),nl.

placeN(_,0,board(D,D1,D2),board(D,D1,D2)):- !.
placeN(N,Q,Board1,Result):- Q>0,
    place_a_bishop(N,Board1,Board2),
    Q1=Q-1,
    placeN(N,Q1,Board2,Result).

place_a_bishop(N,board(Bishops,Diag1,Diag2),
         board([q(R,C)|Bishops],NewD1,NewD2)):-
    findandremove(D1,Diag1,NewD1),
    findandremove(D2,Diag2,NewD2),
    C1=D1+D2-N+1,
    C1 mod 2 = 0,
    C=C1 div 2, C>0, C<=N,
    R=D2-C+1, R>0, R<=N.

findandremove(X,[X|Rest],Rest).
findandremove(X,[Y|Rest],[Y|Tail]):- findandremove(X,Rest,Tail).

makelist(0,[]):- !.
makelist(N,[N|Rest]):- N1=N-1, makelist(N1,Rest).
goal
nbishops(8,14).
Находится вот такая расстановка:
Код:
[q(7,1),q(6,1),q(5,1),q(4,1),q(3,1),q(2,1),q(8,8),q(7,8),q(6,8),q(5,8),q(4,8),q(3,8),q(2,8),q(1,8)]
Ответить с цитированием
Ads
  (#5 (permalink)) Старый
Alison Alison вне форума
Member
 
Сообщений: 4,781
Сказал(а) спасибо: 0
Поблагодарили 119 раз(а) в 116 сообщениях
Регистрация: 17.11.2004
По умолчанию 24.12.2007, 23:32

Я не знаю, можно ли по-быстрому исправить эту программу.
А вот как расставить слонов, я уже писала:
http://www.hardforum.ru/t75864
Вот пример, как найти одну расстановку слонов, первую попавшуюся. Но все расстановки на доске 8x8 так не найти, надо делать более тонко.
Код:
domains
bishop    = q(integer, integer)
bishops   = bishop*
freelist = integer*
board    = board(bishops, freelist, freelist)
predicates
nondeterm placeN(integer,integer,board,board)
nondeterm place_a_bishop(integer,board,board)
determ nbishops(integer SizeOfBoard,integer NumberOfQ)
determ makelist(integer, freelist)
nondeterm findandremove(integer, freelist, freelist)
clauses
nbishops(N,Q):-
    Diagonal=N*2-1,
    makelist(Diagonal,LL),
    placeN(N,Q,board([],LL,LL),Final),
    Final=board(Bishops,_,_),
    !,
    write(Bishops),nl.

placeN(_,0,board(D,D1,D2),board(D,D1,D2)):- !.
placeN(N,Q,Board1,Result):- Q>0,
    place_a_bishop(N,Board1,Board2),
    Q1=Q-1,
    placeN(N,Q1,Board2,Result).

place_a_bishop(N,board(Bishops,Diag1,Diag2),
         board([q(R,C)|Bishops],NewD1,NewD2)):-
    findandremove(D1,Diag1,NewD1),
    findandremove(D2,Diag2,NewD2),
    C1=D1+D2-N+1,
    C1 mod 2 = 0,
    C=C1 div 2, C>0, C<=N,
    R=D2-C+1, R>0, R<=N.

findandremove(X,[X|Rest],Rest).
findandremove(X,[Y|Rest],[Y|Tail]):- findandremove(X,Rest,Tail).

makelist(0,[]):- !.
makelist(N,[N|Rest]):- N1=N-1, makelist(N1,Rest).
goal
nbishops(8,14).
Находится вот такая расстановка:
Код:
[q(7,1),q(6,1),q(5,1),q(4,1),q(3,1),q(2,1),q(8,8),q(7,8),q(6,8),q(5,8),q(4,8),q(3,8),q(2,8),q(1,8)]
Ответить с цитированием
Ads.
  (#6 (permalink)) Старый
Alison Alison вне форума
Member
 
Сообщений: 4,781
Сказал(а) спасибо: 0
Поблагодарили 119 раз(а) в 116 сообщениях
Регистрация: 17.11.2004
По умолчанию 24.12.2007, 23:32

Я не знаю, можно ли по-быстрому исправить эту программу.
А вот как расставить слонов, я уже писала:
http://www.hardforum.ru/t75864
Вот пример, как найти одну расстановку слонов, первую попавшуюся. Но все расстановки на доске 8x8 так не найти, надо делать более тонко.
Код:
domains
bishop    = q(integer, integer)
bishops   = bishop*
freelist = integer*
board    = board(bishops, freelist, freelist)
predicates
nondeterm placeN(integer,integer,board,board)
nondeterm place_a_bishop(integer,board,board)
determ nbishops(integer SizeOfBoard,integer NumberOfQ)
determ makelist(integer, freelist)
nondeterm findandremove(integer, freelist, freelist)
clauses
nbishops(N,Q):-
    Diagonal=N*2-1,
    makelist(Diagonal,LL),
    placeN(N,Q,board([],LL,LL),Final),
    Final=board(Bishops,_,_),
    !,
    write(Bishops),nl.

placeN(_,0,board(D,D1,D2),board(D,D1,D2)):- !.
placeN(N,Q,Board1,Result):- Q>0,
    place_a_bishop(N,Board1,Board2),
    Q1=Q-1,
    placeN(N,Q1,Board2,Result).

place_a_bishop(N,board(Bishops,Diag1,Diag2),
         board([q(R,C)|Bishops],NewD1,NewD2)):-
    findandremove(D1,Diag1,NewD1),
    findandremove(D2,Diag2,NewD2),
    C1=D1+D2-N+1,
    C1 mod 2 = 0,
    C=C1 div 2, C>0, C<=N,
    R=D2-C+1, R>0, R<=N.

findandremove(X,[X|Rest],Rest).
findandremove(X,[Y|Rest],[Y|Tail]):- findandremove(X,Rest,Tail).

makelist(0,[]):- !.
makelist(N,[N|Rest]):- N1=N-1, makelist(N1,Rest).
goal
nbishops(8,14).
Находится вот такая расстановка:
Код:
[q(7,1),q(6,1),q(5,1),q(4,1),q(3,1),q(2,1),q(8,8),q(7,8),q(6,8),q(5,8),q(4,8),q(3,8),q(2,8),q(1,8)]
Ответить с цитированием
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Растановка ферзей на шахматной доске Sonechko Prolog 17 21.10.2012 01:04
задача с шахматной доской sapbufer Pascal 1 19.09.2011 04:31
Написание шахматной игры с алгоритмом хода компьютера alexande-rus Вопросы начинающих программистов 1 20.11.2010 21:16
Ферзи и слоны Duplex Prolog 8 08.06.2009 17:39
Разработать программу обхода шахматной доски bIRKA Lisp 0 19.05.2009 20:55
расстановка слонов или коней на шахматной доске xskald Prolog 4 04.12.2007 23:34
Мин. путь на шахматной доске Grande Prolog 0 15.11.2007 21:02
4 коня на шахматной доске lendrik Prolog 2 23.04.2007 20:57
Задача про коней на шахматной доске (помогите) Azeret Prolog 23 02.06.2006 16:42
Минимальный путь на взвешеной шахматной доске Ikky Prolog 1 12.10.2005 22:09
Перемещение пешек на доске. Винитарх Prolog 3 13.03.2005 14:42
Как прописать координаты на шахматной доске для коня imported_Ventura Алгоритмы 3 15.03.2004 13:13



Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Нardforum.ru - компьютерный форум и программирование, форум программистов