2 left, 1 down 2 left, 1 up 2 right, 1 down 2 right, 1 up 2 up, 1 left 2 up, 1 right 2 down, 1 left 2 down, 1 right
In knight's tour problem the goal is to find a series of legal moves in which the knight lands on each square of the chessboard exactly once.
We will look at a simplified verions in which the goal is to find a series of legal moves that takes the knight from one square to another on a 3 x 3 chessboard.
1 2 3 4 5 6 7 8 9Then the following list of predicates describe all of the legal moves that a knight can make on such a chess board:
move(1,6). move(3,4). move(6,7). move(8,3). move(1,8). move(3,8). move(6,1). move(8,1). move(2,7). move(4,3). move(7,6). move(9,4). move(2,9). move(4,9). move(7,2). move(9,2).Suppose you wanted to determine whether a path exists from one square to another using just the legal knight moves. Here's a recursive predicate for path:
path(Z,Z). path(X,Y) :- move(X,W),not(visited(W)),asserta(visited(W)),path(W,Y).This version of path() uses the asserta() predicate to maintain a list of visited states. This will prevent looping. Here's a PROLOG implementation of this design.
An alternative design would be to use a list to represent the visited states, and just carry the list along as a third parameter:
path(Z,Z,L). path(X,Y,L) :- move(X,Z),not(member(Z,L)),path(Z,Y,[Z|L]).The third parameter maintains a list of visited states. Note how the state Z is added to the list in the recursive call. Here's a PROLOG implementation of this design.
Another way to code the rules that would work better for an 8 x 8 board. We illustrate this approach using a 4 x 4 board but the same principles and relations will apply for an N x N board. Suppose the board is numbered starting from 0:
0 1 2 3 (0,0) (0,1) (0,2) (0,3) 4 5 6 7 (1,0) (1,1) (1,2) (1,3) 8 9 10 11 (2,0) (2,1) (2,2) (2,3) 12 13 14 15 (3,0) (3,1) (3,2) (3,3)There 8 types of knight moves:
right 1 down 2 left 1 down 2 right 2 down 1 left 2 down 1 right 1 up 2 left 1 up 2 right 2 up 1 left 2 up 1
Here's a definition for right 1 down 2. If the present location is X, then find the row and column numbers for Y. For any X, ColX is X mod 4 and RowX is X div 4. E.g., if X = 0, then (RowX,ColX) = (0,0); if X = 6, then (RowX,ColX) = (1,2); if X = 15, the (RowX,ColX) = (3,3). After you compute (RowX,ColX), then moving right 1 down 2 gives (RowX+2,ColX+1). But then these numbers have to be converted back to square number using the formula: Y = Row * 4 + Col. Here's what it looks like in PROLOG.
move(X,Y) :-
ColX is X mod 4, % remainder of X/4
RowX is X // 4, % divisor of X/4
Col is ColX + 1, % right 1
Col < 4,
Row is RowX + 2, % down 2
Row < 4,
Y is Row * 4 + Col,
Y >= 0.
Could the above exhaustive approach be extended to the full Knight's Tour?
The goal of the Knight's Tour is to construct a path from an arbitrary position on the chess board such that it visits each square on the board exactly once. Can this problem be solved through exhaustive search?
What's the (average) branching factor, B for the Knight's Tour?
What's the path length, L for a successful solution of the Knight's Tour?
Approximately how many states, T, would be involved in the exhaustive search of the Knight's Tour? (approximately BL)
The heuristic tells us to select as our next move the one that has the fewest choices for moving on from there.