I'm trying to write a program to solve the n-queens problem
. To check if a queen attacks the other that are stored in a list L
as lists with their coordinates ([X,Y], etc...
), I wrote this piece of code :
safe_queens([X1,Y1],[X2,Y2]) :-
X1 \== X2,
Y1 \== Y2,
abs(X1 - X2) \== abs(Y1 - Y2).
no_attack([_,_],[]).
no_attack(R0,[R|L]) :-
maplist(safe_queens(R0,_),L)
no_attack(R,L).
safe_queens
checks if 2 queens cannot attack each other. I want to apply safe_queens
for a queen R0
over the rest of the list.
How can I freeze R0 as one argument of the predicate, and let the other takes its value in the list L
?
You can do so by building another predicate to loop through the list and apply safe_queens on each element with R0 Like This:
safe_queens([X1,Y1],[X2,Y2]) :-
X1 \== X2,
Y1 \== Y2,
abs(X1 - X2) \== abs(Y1 - Y2).
mapThroughList(_,[]).
mapThroughList(R0,[H|T]):-
safe_queens(R0,H),
mapThroughList(R0,T).
no_attack([_,_],[]).
no_attack(R0,[R|L]) :-
mapThroughList(R0,[R|L]),
no_attack(R,L).
Also, this is a solution for the N-Queen Problem you can find this code:
solve(N,P) :-
numlist(0,N,NL),
permutation(NL,P),
diagonals(NL,P,S,D),
all_diff(S),
all_diff(D).
diagonals([],[],[],[]).
diagonals([X1|X],[Y1|Y],[S1|S],[D1|D]):-
S1 is X1 + Y1,
D1 is X1- Y1,
diagonals(X,Y,S,D).
all_diff([_]).
all_diff([X|Y]) :-
\+member(X,Y),
all_diff(Y).