Скачиваний:
14
Добавлен:
01.05.2014
Размер:
442.37 Кб
Скачать

4. Текст программы

%*************************************************************************************************

% Список, содержащий параметры всех кораблей

%*************************************************************************************************

navy([[X1/Y1/1/0,X2/Y2/1/0,X3/Y3/1/0,X4/Y4/1/0], % однопалубные корабли

[X5/Y5/2/R5,X6/Y6/2/R6,X7/Y7/2/R7], % двухпалубные корабли

[X8/Y8/3/R8,X9/Y9/3/R9], % трехпалубные корабли

[X10/Y10/4/R10]]). % четырехпалубный корабль

%*************************************************************************************************

% Главная функция

%*************************************************************************************************

main(Ships,Reefs):-navy(Ships),read(Reefs),search(Ships,Reefs).

%*************************************************************************************************

% Поиск решения

%*************************************************************************************************

search([],_).

search([Head|Tail],Reefs):-search(Tail,Reefs),search_navy(Head,Reefs,Tail).

%*************************************************************************************************

% Расстановка всех кораблей

%*************************************************************************************************

search_navy([X/Y/N/R|Others],Reefs,Tail):-

(N=:=1,search_1deck([X/Y/N/R|Others],Reefs,Tail));

(N=:=2,search_2deck([X/Y/N/R|Others],Reefs,Tail));

(N=:=3,search_3deck([X/Y/N/R|Others],Reefs,Tail));

(N=:=4,search_4deck([X/Y/N/R|Others],Reefs)).

%*************************************************************************************************

% Расстановка четырех однопалубных кораблей

%*************************************************************************************************

search_1deck([X1/Y1/N1/R1,X2/Y2/N2/R2,X3/Y3/N3/R3,X4/Y4/N4/R4],Reefs,Tail):-

% Выбор места для 1-го однопалубного корабля

choose_place(X1/Y1/N1/R1,0,0),A1 is X1+R1*(N1-1),B1 is Y1+(1-R1)*(N1-1),

is_ship_ndeck(X1/Y1/A1/B1,Tail),is_reef_ndeck(X1/Y1/A1/B1,Reefs),

% Выбор места для 2-го однопалубного корабля

choose_place(X2/Y2/N2/R2,X1,Y1),A2 is X2+R2*(N2-1),B2 is Y2+(1-R2)*(N2-1),

conc([X1/Y1/N1/R1],Tail,Tail1),

is_ship_ndeck(X2/Y2/A2/B2,Tail1),is_reef_ndeck(X2/Y2/A2/B2,Reefs),

% Выбор места для 3-го однопалубного корабля

choose_place(X3/Y3/N3/R3,X2,Y2),A3 is X3+R3*(N3-1),B3 is Y3+(1-R3)*(N3-1),

conc([X2/Y2/N2/R2],Tail1,Tail2),

is_ship_ndeck(X3/Y3/A3/B3,Tail2),is_reef_ndeck(X3/Y3/A3/B3,Reefs),

% Выбор места для 4-го однопалубного корабля

choose_place(X4/Y4/N4/R4,X3,Y3),A4 is X4+R4*(N4-1),B4 is Y4+(1-R4)*(N4-1),

conc([X3/Y3/N3/R3],Tail2,Tail3),

is_ship_ndeck(X4/Y4/A4/B4,Tail3),is_reef_ndeck(X4/Y4/A4/B4,Reefs).

%*************************************************************************************************

% Расстановка трех двухпалубных кораблей

%*************************************************************************************************

search_2deck([X1/Y1/N1/R1,X2/Y2/N2/R2,X3/Y3/N3/R3],Reefs,Tail):-

% Выбор места для 1-го двухпалубного корабля

choose_place(X1/Y1/N1/R1,0,0),A1 is X1+R1*(N1-1),B1 is Y1+(1-R1)*(N1-1),

is_ship_ndeck(X1/Y1/A1/B1,Tail),is_reef_ndeck(X1/Y1/A1/B1,Reefs),

% Выбор места для 2-го двухпалубного корабля

choose_place(X2/Y2/N2/R2,X1,Y1),A2 is X2+R2*(N2-1),B2 is Y2+(1-R2)*(N2-1),

conc([X1/Y1/N1/R1],Tail,Tail1),

is_ship_ndeck(X2/Y2/A2/B2,Tail1),is_reef_ndeck(X2/Y2/A2/B2,Reefs),

% Выбор места для 3-го двухпалубного корабля

choose_place(X3/Y3/N3/R3,X2,Y2),A3 is X3+R3*(N3-1),B3 is Y3+(1-R3)*(N3-1),

conc([X2/Y2/N2/R2],Tail1,Tail2),

is_ship_ndeck(X3/Y3/A3/B3,Tail2),is_reef_ndeck(X3/Y3/A3/B3,Reefs).

%*************************************************************************************************

% Расстановка двух трехпалубных кораблей

%*************************************************************************************************

search_3deck([X1/Y1/N1/R1,X2/Y2/N2/R2],Reefs,Tail):-

% Выбор места для 1-го трехпалубного корабля

choose_place(X1/Y1/N1/R1,0,0),A1 is X1+R1*(N1-1),B1 is Y1+(1-R1)*(N1-1),

is_ship_ndeck(X1/Y1/A1/B1,Tail),is_reef_ndeck(X1/Y1/A1/B1,Reefs),

% Выбор места для 2-го трехпалубного корабля

choose_place(X2/Y2/N2/R2,X1,Y1),A2 is X2+R2*(N2-1),B2 is Y2+(1-R2)*(N2-1),

conc([X1/Y1/N1/R1],Tail,Tail1),

is_ship_ndeck(X2/Y2/A2/B2,Tail1),is_reef_ndeck(X2/Y2/A2/B2,Reefs).

%*************************************************************************************************

% Расстановка одного четырехпалубного корабля

%*************************************************************************************************

search_4deck([X1/Y1/N1/R1],Reefs):-

choose_place(X1/Y1/N1/R1,0,0),A1 is X1+R1*(N1-1),B1 is Y1+(1-R1)*(N1-1),

is_reef_ndeck(X1/Y1/A1/B1,Reefs).

%*************************************************************************************************

% Выбор места для корабля

%*************************************************************************************************

choose_place(X/Y/N/R,StartX,StartY):-

member(X,[0,1,2,3,4,5,6,7,8,9]),X>=StartX,

member(Y,[0,1,2,3,4,5,6,7,8,9]),

member(R,[0,1]),X*10+Y>StartX*10+StartY,

A is X+R*(N-1),member(A,[0,1,2,3,4,5,6,7,8,9]),

B is Y+(1-R)*(N-1),member(B,[0,1,2,3,4,5,6,7,8,9]).

%*************************************************************************************************

% Проверка на столкновение с рифами

%*************************************************************************************************

% Одна из палуб корабля попадает на риф

is_reef_ndeck(_,[]).

is_reef_ndeck(X/Y/A/B,[Xx/Yy|Rest]):-is_reef_1deck(X/Y/A/B,Xx/Yy),is_reef_ndeck(X/Y/A/B,Rest).

% Палуба корабля попадает на риф

is_reef_1deck(X/Y/A/B,Xx/Yy):-X>Xx,A>Xx,!.

is_reef_1deck(X/Y/A/B,Xx/Yy):-X<Xx,A<Xx,!.

is_reef_1deck(X/Y/A/B,Xx/Yy):-Y>Yy,B>Yy,!.

is_reef_1deck(X/Y/A/B,Xx/Yy):-Y<Yy,B<Yy,!.

%*************************************************************************************************

% Проверка на столкновение с другими кораблями

%*************************************************************************************************

% Одна из палуб корабля попадает на другой корабль

is_ship_ndeck(_,[]).

is_ship_ndeck(X/Y/A/B,[List|Rest]):-is_deck_ndeck(X/Y/A/B,List),is_ship_ndeck(X/Y/A/B,Rest),!.

is_ship_ndeck(X/Y/A/B,[Xx/Yy/Nn/Rr|Rest]):- is_deck_ndeck(X/Y/A/B,[Xx/Yy/Nn/Rr]),is_ship_ndeck(X/Y/A/B,Rest).

% Одна из палуб корабля попадает на палубу другого корабля

is_deck_ndeck(_,[]).

is_deck_ndeck(X/Y/A/B,[Xx/Yy/Nn/Rr|Rest]):- Aa is Xx+Rr*(Nn-1),Bb is Yy+(1-Rr)*(Nn-1),

is_ship_1deck(X/Y/A/B,Xx/Yy/Aa/Bb),is_ship_ndeck(X/Y/A/B,Rest).

% Палуба корабля попадает на палубу другого корабля

is_ship_1deck(X/Y/A/B,_):- X>A,!.

is_ship_1deck(X/Y/A/B,_):- Y>B,!.

is_ship_1deck(X/Y/A/B,Xx/Yy/Aa/Bb):-

X=:=A,X1 is X,Y1 is Y+1,is_deck_1deck(Xx/Yy/Aa/Bb,X/Y),

is_ship_1deck(X1/Y1/A/B,Xx/Yy/Aa/Bb),!.

is_ship_1deck(X/Y/A/B,Xx/Yy/Aa/Bb):-

Y=:=B,X1 is X+1,Y1 is Y,is_deck_1deck(Xx/Yy/Aa/Bb,X/Y),

is_ship_1deck(X1/Y1/A/B,Xx/Yy/Aa/Bb),!.

is_deck_1deck(X/Y/A/B,Xx/Yy):-X>Xx+1,A>Xx+1,!.

is_deck_1deck(X/Y/A/B,Xx/Yy):-X<Xx-1,A<Xx-1,!.

is_deck_1deck(X/Y/A/B,Xx/Yy):-Y>Yy+1,B>Yy+1,!.

is_deck_1deck(X/Y/A/B,Xx/Yy):-Y<Yy-1,B<Yy-1,!.

%*************************************************************************************************

% Вспомогательные функции

%*************************************************************************************************

% Конкатенация двух списков

conc([],L,L).

conc([X|L1],L2,[X|L3]):-conc(L1,L2,L3).

Соседние файлы в папке Морской бой на языке Пролог