%         Demonstrationsprogramm fr Prolog-68
%
%         Copyright  1990,91,92 Jens Kilian.

test :- queens(5).

queens(N) :-
   queens(N, N, Solution),
   show_solution(N, 0, Solution),
   fail.

queens(0, N, []).
queens(M, N, [Pos | Board]) :-
   M > 0, M1 is M - 1,
   queens(M1, N, Board),
   range(1, Pos, N),
   check_solution(Board, 0, Pos).

range(I, I, I) :- !.
range(I, J, K) :-
   L is (I+K) / 2,
   range(I, J, L).
range(I, J, K) :-
   L is 1 + (I+K) / 2,
   range(L, J, K).

check_solution([], _, _).
check_solution([Place | Board], Distance, Pos) :-
   Dist1 is Distance + 1,
   check_place(Place, Dist1, Pos),
   check_solution(Board, Dist1, Pos).

check_place(Place, Distance, Pos) :-
   Place =\= Pos - Distance,
   Place =\= Pos,
   Place =\= Pos + Distance.

show_solution(N, N, _) :- !, nl.
show_solution(N, M, Solution) :-
   F is M and 1,
   M1 is M + 1,
   show_line(Solution, M1, F),
   show_solution(N, M1, Solution).

show_line([], _, _) :- nl.
show_line([P | S], P, F) :- !,
   F1 is 1 - F,
   field(F, 42),
   show_line(S, P, F1).
show_line([_ | S], P, F) :-
   F1 is 1 - F,
   field(F, 32),
   show_line(S, P, F1).

field(0, C) :- put(C), put(C).
field(1, C) :- put(27), put(112), put(C), put(C), put(27), put(113).

