Professional Documents
Culture Documents
Problem:
Placing 8 queens on a chessboard such that they don’t attack each other
A chess-board is an 8x8 grid
Each X:Y pair represents the position of one queen on the board
The problem is now finding such a list with the queens positioned on
the board in such a way that they don’t attack one another. We will
define a predicate:
solution(Pos).
solution(Pos)
returns a solution in a list “Pos”.
Here is an example solution:
[1:4, 2:2, 3:7, 4:3, 5:6, 6:8, 7:5, 8:1]
Y1 = 4, Y2 = 2, Y3 = 7, Y4 = 3, Y5 = 6, Y6 = 8, Y7 = 5, Y8 = 1
X
Q1 X=1 Y=6 Q2 X=5 Y=6
X
Y \= Y1, % different rows
(Y1 - Y) \= (X1 - X),
(Y1 - Y) \= (X - X1), % different diagonals
To avoid vertical attacks, queens have to be on different columns.
We may fix the X coordinates to achieve this.
Solution 1
We will put the queens on the board one by one making sure they
do not attack one another until we have them all on the board. We
may break the problem down to two cases of having an empty list
or a list with a head and a tail as we usually do with problems
involving lists.
Case 1
There are no queens on the board then the no attack condition holds and we have:
solution([ ]).
noattack(_, [ ]).
noattack(X:Y, [X1:Y1 | Rest]):-
Y =\= Y1, % different rows
(Y1 - Y) =\= (X1 - X),
(Y1 - Y) =\= (X - X1), % different diagonals
noattack(X:Y, Rest). % OK with the others.
% A solution template
template([1:Y1, 2:Y2, 3:Y3, 4:Y4, 5:Y5, 6:Y6, 7:Y7, 8:Y8])
The query:
?-template(Pos),solution(Pos).
generates
Y1 = 4, Y2 = 2, Y3 = 7, Y4 = 3, Y5 = 6, Y6 = 8, Y7 = 5, Y8 = 1