Tell me more x
, there is a new speed test available. Give it a try, leave feedback!
dslreports logo
    All Forums Hot Topics Gallery


Search Topic:
share rss forum feed


Knights tour Prolog

Hello People,

I am currently trying to write a knights tour program on a 5 x 5 chessboard that visits every square at least

once. At the moment it only maps the path from 1 square to another and does not visit all squares on the

board.What I am trying to get the knight to do is visit all the squares rather than map a path from one square to


I have tried to get the program to visit all the squares by using a list length that matches the number of squares

visited by the knight on the board i.e. 25 on 5 x 5 board. Once it has visited all squares it will output the

solution path on screen. Although at the moment it infinite loops and does not find a search result. I have also

tried to do this using depth_first and breadth_first search and I am still having the same problems.

A copy of code I have got so far can be found below, any help you could give would be much appreciated:

/* **************************************************************
Simplified Knight's tour - In this simplified version of the knight's
tour, a knight's path is built between any two squares on the chess board.
The main predicate, path(X,Y), prints out a path between X and Y.

This version extends the initial representation
to a 5 x 5 grid, with the grid numbered as follows:

1 2 3 16 25
4 5 6 15 24
7 8 9 14 23
10 11 12 13 22
17 18 19 20 21

This version uses a recursive path/3 predicate, with the third
argument representing the list of squares visited along the path:


To run the program, type path(X,Y)


/* An exhaustive list of moves. These are moves for a 3 x 3 board */

move(2,9). move(2,7). move(3,4). move(3,8). move(4,9). move(4,3).
move(6,1). move(6,7). move(7,2). move(7,6). move(8,3). move(8,1).
move(9,2). move(9,4). move(1,6). move(1,8).

/* The additional moves for the 4 x 4 board */

move(2,15). move(3,14). move(4,11). move(5,10). move(5,12). move(5,14).
move(5,16). move(6,11). move(6,13). move(7,12). move(8,15). move(8,13).
move(9,10). move(9,16). move(10,5). move(10,9). move(11,4). move(11,6).
move(11,14). move(12,5). move(12,7). move(12,15). move(13,8). move(13,6).
move(14,11). move(14,5). move(14,3). move(15,12). move(15,8). move(15,2).
move(16,5). move(16,9).

/* The additional moves for the 5 x 5 board */

move(3,24). move(6,23). move(6,25). move(7,18). move(8,17). move(8,19).
move(9,18). move(9,20). move(9,22). move(9,24). move(10,19). move(11,20).
move(12,17). move(12,21). move(12,23). move(13,18). move(13,24). move(14,19).
move(14,21). move(14,25). move(15,22). move(16,23). move(17,8). move(17,12).
move(18,7). move(18,9). move(18,13). move(19,8). move(19,10). move(19,14).
move(19,22). move(20,9). move(20,11). move(20,23). move(21,12). move(21,14).
move(22,9). move(22,15). move(22,19). move(23,6). move(23,12). move(23,16).
move(23,20). move(24,3). move(24,9). move(24,13). move(25,6). move(25,14).

/*********** PROGRAM STARTS HERE ********************/

path(X,Y) :- path(X,Y,[X]). /* Build a path between X and Y by
calling path/3. */

path(Z,Z,L):- !,printlist(L),size(L,N), N = 25,nl, write(N). /* Base case: prints the solution */
path(X,Y,L):- move(X,Z), /* Recursive case: find a move from X to Z */
not(member(Z,L)), /* Cycle prevention */
path(Z,Y,[Z|L]). /* Find a path from Z to Y */

/* Print the list L in reverse order */
printlist([H|T]) :- printlist(T),nl,write(H).

/* Basic utility predicates */

/*not(P):- call(P),!,fail,*/
/*not(P). */

/* member(H,[H|T]). */
/* member(M,[Y|T]) :- member(M,T). */

member(X,[H|T]) :- member(X,T).

(X == bottom, !, L = []
; L = [X | Rest], collect(Rest)).

findall(X, Goal, Xlist):-

append([X|L1],L2,[X|L12]) :-

next_node(Current, Next,Path) :-
move(Current, Next),
write('next node: '), write(Next), nl,

depth_first(Start, Goal, Path) :-
depth_first1(Start, Goal, [Start], Path),
size(Path, N),
N 25.

size([H|T],N):- size(T,N1),N is N1+1.
depth_first1(Current,Goal, _, [Goal]):-
/*size(Goal, N), */
N = 25.
depth_first1(Start, Goal, Visited, [Start | Path]) :-
Goal = 25,
next_node(Start, Next_node, Visited),
write('Visited: '), write(Visited), nl,
depth_first1(Next_node, Goal, [Next_node|Visited], Path), !.

breadth_first(Start, Goal, Path) :-
breadth_first1([[Start]], Goal, Path).

breadth_first1([[Goal|Path]|_], Goal, [Goal|Path]).

breadth_first1([[Current|Trail]|OtherPaths], Goal, Path) :-
Goal = 25,
findall([Next,Current|Trail], next_node(Current, Next, Trail), NewPaths),
write('New paths: '), write(NewPaths), nl,
append(OtherPaths, NewPaths, AllPaths),
breadth_first1(AllPaths, Goal, Path), !.