An object oriented solution to the N-queens problem
.so fq
The example presented in this section is a case study
in object oriented programming taken from [Budd91].
The essence of this particular solution to the queens problem
is that each queen is made an object endowed
with the power to discover a solution in cooperation with
the other queens. The definition of the object queen is given in figure \ref{obj:queen}.
To establish the functionality of a queen, we may observe that each
queen must know about its position on the board,
and hence must have non-logical instance variables row and column
to record its positions.
Since in no solution can any queen be in the same column
as another queen, each queen is initially assigned a unique
column number.
Recall that in our previous solutions to the 8-queens problem
a solution was found for n queens by extending a solution for
queens with a queen not attacking any of the queens already found.
The empty list gave a trivial solution for n is zero
and the list was extended until it contained eight mutually
non-attacking queens.
The principle of extending a solution for a smaller number of queens is reflected in the
pattern of communication between the queens.
Each queen, except the one positioned in the first column,
needs to be able to ask the queen in its left neighboring column to provide
a solution that it may extend.
The queen in the left-most column simply responds to requests to position itself on a
row or try another row.
The data maintained by each queen are hence its row index,
which may change in the process of finding a solution, its column index
which is fixed when creating the queen,
and a pointer to its neighbor, which has the constant nil as its value if the queen is the left-most
queen (in column 1).
An acceptable position for a particular column n is a configuration
of column 1 to n in which no queen can attack any other queen in those
columns.
The methods that a queen must have in order to support the generate-and-test procedure
are the methods first to initialize the row and to find an acceptable solution for
itself and its left neighbors,
the method next to advance a row (modulo the number of queens)
and find the next acceptable solution,
and the method that is used to test whether the queen itself
or any of its left neighbors can attack a position.
Both the methods first and next make use of the predicate
, which tests whether the queen can be attacked by
any of its left neighbors and advances to the next row if this is the case.
A solution to the N-queens problem, for N is 4, will be printed
by stating the goal
.ds queens.g
Calling the method print results in printing the positions
of the queen and its neighbors.