/* Find a knight tour that connects all the squares by Neng-Fa Zhou, 2001 */ go:- cgWindow(W,"Knight tour"), W^width #= 780, W^height #= 680, % knight_tour(W,Comps). knight_tour(Win,Comps):- solve(Vars), output(Vars,Win,Comps). solve(Vars):- length(Vars,64), % 8*8=64 computeDomain(Vars,1), all_different(Vars), % no position is visited more than once circuit(Vars), % built-in labeling_ff(Vars). computeDomain([],N). computeDomain([V|Vs],N):- I is (N-1)//8+1, J is N-(I-1)*8, feasiblePositions(I,J,D), sort(D,SortedD), V in SortedD, N1 is N+1, computeDomain(Vs,N1). feasiblePositions(I,J,D):- I1 is I+1, J1 is J+2, I2 is I+1, J2 is J-2, I3 is I-1, J3 is J+2, I4 is I-1, J4 is J-2, I5 is I+2, J5 is J+1, I6 is I+2, J6 is J-1, I7 is I-2, J7 is J+1, I8 is I-2, J8 is J-1, addFeasiblePositions([(I1,J1),(I2,J2),(I3,J3),(I4,J4),(I5,J5),(I6,J6),(I7,J7),(I8,J8)],D). addFeasiblePositions([],D):-D=[]. addFeasiblePositions([(I,J)|IJs],D):- (I>=1,I=<8,J>=1,J=<8),!, N is (I-1)*8+J, D=[N|D1], addFeasiblePositions(IJs,D1). addFeasiblePositions([_|IJs],D):- addFeasiblePositions(IJs,D). output(Vars,W,AllComps):- drawBoard(8,Comps,[]), cgSame(Comps,window,W), cgPack(Comps), % Array=..[a|Vars], output(Array,1,1,1,W,Lines), closetail(Lines), append(Comps,Lines,AllComps), % cgScale(AllComps,0.3), cgShow(AllComps). drawBoard(N,Comps,CompsR):- drawHorizontalLines(0,N,Comps,Comps1), drawVerticalLines(0,N,Comps1,CompsR). drawHorizontalLines(I,N,Comps,CompsR):-I>N,!,Comps=CompsR. drawHorizontalLines(I,N,Comps,CompsR):- cgLine(Line), LM #= 100, TM #= 100, Line^x1 #= LM, Line^y1 #= 60*I+TM, Line^x2 #= 60*N+LM, Line^y2 #= Line^y1, Comps=[Line|Comps1], I1 is I+1, drawHorizontalLines(I1,N,Comps1,CompsR). drawVerticalLines(I,N,Comps,CompsR):-I>N,!,Comps=CompsR. drawVerticalLines(I,N,Comps,CompsR):- cgLine(Line), LM #= 100, TM #= 100, Line^x1 #= 60*I+LM, Line^y1 #= TM, Line^x2 #= Line^x1, Line^y2 #= N*60+TM, Comps=[Line|Comps1], I1 is I+1, drawVerticalLines(I1,N,Comps1,CompsR). output(Array,I,J,N,Win,Lines):-N>64,!. output(Array,I,J,N,Win,Lines):- P is (I-1)*8+J, arg(P,Array,P1), I1 is (P1-1)//8+1, J1 is P1-(I1-1)*8, drawStep(I,J,I1,J1,Win,Lines), N1 is N+1, output(Array,I1,J1,N1,Win,Lines). drawStep(I,J,I1,J1,Win,Lines):- cgLine(Line), LM #= 100, TM #= 100, Line^x1 #= (I-1)*60+LM+30, Line^y1 #= (J-1)*60+TM+30, Line^x2 #= (I1-1)*60+LM+30, Line^y2 #= (J1-1)*60+TM+30, Line^color #= blue, cgCircle(Circle), Circle^centerX #= Line^x1, Circle^centerY #= Line^y1, Circle^width #= 10, Circle^color #= blue, Circle^window #= Win, Line^window #= Win, cgPack([Line,Circle]), attach(Line,Lines), attach(Circle,Lines).