Knight's tour: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Wren}}: Changed to Wren S/H)
(17 intermediate revisions by 8 users not shown)
Line 25:
{{trans|Python}}
 
<langsyntaxhighlight lang="11l">V _kmoves = [(2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2), (1, -2), (2, -1)]
 
F chess2index(=chess, boardsize)
Line 81:
V board = knights_tour(start, boardsize)
print(boardstring(board, boardsize' boardsize))
print()</langsyntaxhighlight>
 
{{out}}
Line 124:
=={{header|360 Assembly}}==
{{trans|BBC PASIC}}
<langsyntaxhighlight lang="360asm">* Knight's tour 20/03/2017
KNIGHT CSECT
USING KNIGHT,R13 base registers
Line 378:
PG DC CL128' ' buffer
YREGS
END KNIGHT</langsyntaxhighlight>
{{out}}
<pre>
Line 396:
First, we specify a naive implementation the package Knights_Tour with naive backtracking. It is a bit more general than required for this task, by providing a mechanism '''not''' to visit certain coordinates. This mechanism is actually useful for the task [[Solve a Holy Knight's tour#Ada]], which also uses the package Knights_Tour.
 
<langsyntaxhighlight Adalang="ada">generic
Size: Integer;
package Knights_Tour is
Line 417:
-- writes The_Tour to the output using Ada.Text_IO;
end Knights_Tour;</langsyntaxhighlight>
 
Here is the implementation:
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO, Ada.Integer_Text_IO;
package body Knights_Tour is
Line 505:
end Tour_IO;
end Knights_Tour;</langsyntaxhighlight>
 
Here is the main program:
 
<langsyntaxhighlight Adalang="ada">with Knights_Tour, Ada.Command_Line;
 
procedure Test_Knight is
Line 519:
begin
KT.Tour_IO(KT.Get_Tour(1, 1));
end Test_Knight;</langsyntaxhighlight>
 
For small sizes, this already works well (< 1 sec for size 8). Sample output:
Line 533:
 
For larger sizes we'll use Warnsdorff's heuristic (without any thoughtful tie breaking). We enhance the specification adding a function Warnsdorff_Get_Tour. This enhancement of the package Knights_Tour will also be used for the task [[Solve a Holy Knight's tour#Ada]]. The specification of Warnsdorff_Get_Tour is the following.
<syntaxhighlight lang="ada">
<lang Ada>
function Warnsdorff_Get_Tour(Start_X, Start_Y: Index; Scene: Tour := Empty)
return Tour;
-- uses Warnsdorff heurisitic to find a tour faster
-- same interface as Get_Tour</langsyntaxhighlight>
 
Its implementation is as follows.
 
<langsyntaxhighlight Adalang="ada"> function Warnsdorff_Get_Tour(Start_X, Start_Y: Index; Scene: Tour := Empty)
return Tour is
Done: Boolean;
Line 626:
end if;
return Visited;
end Warnsdorff_Get_Tour;</langsyntaxhighlight>
 
The modification for the main program is trivial:
<langsyntaxhighlight Adalang="ada">with Knights_Tour, Ada.Command_Line;
 
procedure Test_Fast is
Line 639:
begin
KT.Tour_IO(KT.Warnsdorff_Get_Tour(1, 1));
end Test_Fast;</langsyntaxhighlight>
 
This works still well for somewhat larger sizes:
Line 670:
=={{header|ALGOL 68}}==
{{works with|ALGOL 68G|Any - tested with release 2.8.win32}}
<langsyntaxhighlight lang="algol68"># Non-recursive Knight's Tour with Warnsdorff's algorithm #
# If there are multiple choices, backtrack if the first choice doesn't #
# find a solution #
Line 957:
FI
 
)</langsyntaxhighlight>
{{out}}
<pre>
Line 972:
1| 12 25 14 31 10 27 36 61
</pre>
 
=={{header|ANSI Standard BASIC}}==
{{trans|BBC BASIC}}
[[File:Knights_Tour.gif|right]]
 
ANSI BASIC doesn't allow function parameters to be passed by reference so X and Y were made global variables.
 
<lang ANSI Standard BASIC>100 DECLARE EXTERNAL FUNCTION choosemove
110 !
120 RANDOMIZE
130 PUBLIC NUMERIC X, Y, TRUE, FALSE
140 LET TRUE = -1
150 LET FALSE = 0
160 !
170 SET WINDOW 1,512,1,512
180 SET AREA COLOR "black"
190 FOR x=0 TO 512-128 STEP 128
200 FOR y=0 TO 512-128 STEP 128
210 PLOT AREA:x+64,y;x+128,y;x+128,y+64;x+64,y+64
220 PLOT AREA:x,y+64;x+64,y+64;x+64,y+128;x,y+128
230 NEXT y
240 NEXT x
250 !
260 SET LINE COLOR "red"
270 SET LINE WIDTH 6
280 !
290 PUBLIC NUMERIC Board(0 TO 7,0 TO 7)
300 LET X = 0
310 LET Y = 0
320 LET Total = 0
330 DO
340 LET Board(X,Y) = TRUE
350 PLOT LINES: X*64+32,Y*64+32;
360 LET Total = Total + 1
370 LOOP UNTIL choosemove(X, Y) = FALSE
380 IF Total <> 64 THEN STOP
390 END
400 !
410 EXTERNAL FUNCTION choosemove(X1, Y1)
420 DECLARE EXTERNAL SUB trymove
430 LET M = 9
440 CALL trymove(X1+1, Y1+2, M, newx, newy)
450 CALL trymove(X1+1, Y1-2, M, newx, newy)
460 CALL trymove(X1-1, Y1+2, M, newx, newy)
470 CALL trymove(X1-1, Y1-2, M, newx, newy)
480 CALL trymove(X1+2, Y1+1, M, newx, newy)
490 CALL trymove(X1+2, Y1-1, M, newx, newy)
500 CALL trymove(X1-2, Y1+1, M, newx, newy)
510 CALL trymove(X1-2, Y1-1, M, newx, newy)
520 IF M=9 THEN
530 LET choosemove = FALSE
540 EXIT FUNCTION
550 END IF
560 LET X = newx
570 LET Y = newy
580 LET choosemove = TRUE
590 END FUNCTION
600 !
610 EXTERNAL SUB trymove(X, Y, M, newx, newy)
620 !
630 DECLARE EXTERNAL FUNCTION validmove
640 IF validmove(X,Y) = 0 THEN EXIT SUB
650 IF validmove(X+1,Y+2) <> 0 THEN LET N = N + 1
660 IF validmove(X+1,Y-2) <> 0 THEN LET N = N + 1
670 IF validmove(X-1,Y+2) <> 0 THEN LET N = N + 1
680 IF validmove(X-1,Y-2) <> 0 THEN LET N = N + 1
690 IF validmove(X+2,Y+1) <> 0 THEN LET N = N + 1
700 IF validmove(X+2,Y-1) <> 0 THEN LET N = N + 1
710 IF validmove(X-2,Y+1) <> 0 THEN LET N = N + 1
720 IF validmove(X-2,Y-1) <> 0 THEN LET N = N + 1
730 IF N>M THEN EXIT SUB
740 IF N=M AND RND<.5 THEN EXIT SUB
750 LET M = N
760 LET newx = X
770 LET newy = Y
780 END SUB
790 !
800 EXTERNAL FUNCTION validmove(X,Y)
810 LET validmove = FALSE
820 IF X<0 OR X>7 OR Y<0 OR Y>7 THEN EXIT FUNCTION
830 IF Board(X,Y)=FALSE THEN LET validmove = TRUE
840 END FUNCTION</lang>
 
=={{header|ATS}}==
<langsyntaxhighlight lang="ats">(*
Find Knight’s Tours.
 
Line 1,782 ⟶ 1,700:
val _ = make_and_fprint_tours (stdout_ref, 8, 8, i, j, max_tours,
closed_only)
}</langsyntaxhighlight>
 
{{out}}
Line 1,845 ⟶ 1,763:
=={{header|AutoHotkey}}==
{{libheader|GDIP}}
<langsyntaxhighlight AutoHotkeylang="autohotkey">#SingleInstance, Force
#NoEnv
SetBatchLines, -1
Line 1,940 ⟶ 1,858:
If (A_Gui = 1)
PostMessage, 0xA1, 2
}</langsyntaxhighlight>
{{out}}
For start at b3
Line 1,947 ⟶ 1,865:
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f KNIGHTS_TOUR.AWK [-v sr=x] [-v sc=x]
#
Line 2,016 ⟶ 1,934:
}
}
</syntaxhighlight>
</lang>
<p>output:</p>
<pre>
Line 2,030 ⟶ 1,948:
</pre>
 
=={{header|BBC BASIC}}==
==={{header|ANSI BASIC}}===
{{trans|BBC BASIC}}
[[File:Knights_Tour.gif|right]]
{{works with|Decimal BASIC}}
ANSI BASIC does not allow function parameters to be passed by reference, so X and Y were made global variables.
<syntaxhighlight lang="basic">100 DECLARE EXTERNAL FUNCTION choosemove
110 !
120 RANDOMIZE
130 PUBLIC NUMERIC X, Y, TRUE, FALSE
140 LET TRUE = -1
150 LET FALSE = 0
160 !
170 SET WINDOW 1,512,1,512
180 SET AREA COLOR "black"
190 FOR x=0 TO 512-128 STEP 128
200 FOR y=0 TO 512-128 STEP 128
210 PLOT AREA:x+64,y;x+128,y;x+128,y+64;x+64,y+64
220 PLOT AREA:x,y+64;x+64,y+64;x+64,y+128;x,y+128
230 NEXT y
240 NEXT x
250 !
260 SET LINE COLOR "red"
270 SET LINE WIDTH 6
280 !
290 PUBLIC NUMERIC Board(0 TO 7,0 TO 7)
300 LET X = 0
310 LET Y = 0
320 LET Total = 0
330 DO
340 LET Board(X,Y) = TRUE
350 PLOT LINES: X*64+32,Y*64+32;
360 LET Total = Total + 1
370 LOOP UNTIL choosemove(X, Y) = FALSE
380 IF Total <> 64 THEN STOP
390 END
400 !
410 EXTERNAL FUNCTION choosemove(X1, Y1)
420 DECLARE EXTERNAL SUB trymove
430 LET M = 9
440 CALL trymove(X1+1, Y1+2, M, newx, newy)
450 CALL trymove(X1+1, Y1-2, M, newx, newy)
460 CALL trymove(X1-1, Y1+2, M, newx, newy)
470 CALL trymove(X1-1, Y1-2, M, newx, newy)
480 CALL trymove(X1+2, Y1+1, M, newx, newy)
490 CALL trymove(X1+2, Y1-1, M, newx, newy)
500 CALL trymove(X1-2, Y1+1, M, newx, newy)
510 CALL trymove(X1-2, Y1-1, M, newx, newy)
520 IF M=9 THEN
530 LET choosemove = FALSE
540 EXIT FUNCTION
550 END IF
560 LET X = newx
570 LET Y = newy
580 LET choosemove = TRUE
590 END FUNCTION
600 !
610 EXTERNAL SUB trymove(X, Y, M, newx, newy)
620 !
630 DECLARE EXTERNAL FUNCTION validmove
640 IF validmove(X,Y) = 0 THEN EXIT SUB
650 IF validmove(X+1,Y+2) <> 0 THEN LET N = N + 1
660 IF validmove(X+1,Y-2) <> 0 THEN LET N = N + 1
670 IF validmove(X-1,Y+2) <> 0 THEN LET N = N + 1
680 IF validmove(X-1,Y-2) <> 0 THEN LET N = N + 1
690 IF validmove(X+2,Y+1) <> 0 THEN LET N = N + 1
700 IF validmove(X+2,Y-1) <> 0 THEN LET N = N + 1
710 IF validmove(X-2,Y+1) <> 0 THEN LET N = N + 1
720 IF validmove(X-2,Y-1) <> 0 THEN LET N = N + 1
730 IF N>M THEN EXIT SUB
740 IF N=M AND RND<.5 THEN EXIT SUB
750 LET M = N
760 LET newx = X
770 LET newy = Y
780 END SUB
790 !
800 EXTERNAL FUNCTION validmove(X,Y)
810 LET validmove = FALSE
820 IF X<0 OR X>7 OR Y<0 OR Y>7 THEN EXIT FUNCTION
830 IF Board(X,Y)=FALSE THEN LET validmove = TRUE
840 END FUNCTION</syntaxhighlight>
 
==={{header|BBC BASIC}}===
{{works with|BBC BASIC for Windows}}
[[Image:knights_tour_bbc.gif|right]]
<langsyntaxhighlight lang="bbcbasic"> VDU 23,22,256;256;16,16,16,128
VDU 23,23,4;0;0;0;
OFF
Line 2,092:
DEF FNvalidmove(X%,Y%)
IF X%<0 OR X%>7 OR Y%<0 OR Y%>7 THEN = FALSE
= NOT(Board%(X%,Y%))</langsyntaxhighlight>
 
=={{header|Bracmat}}==
<langsyntaxhighlight lang="bracmat"> ( knightsTour
= validmoves WarnsdorffSort algebraicNotation init solve
, x y fieldsToVisit
Line 2,199:
$ (algebraicNotation$(solve$((!x.!y).!fieldsToVisit)))
)
& out$(knightsTour$a1);</langsyntaxhighlight>
 
<pre>a1 b3 a5 b7 d8 f7 h8 g6 f8 h7 g5 h3 g1 e2 c1 a2 b4 a6 b8 c6 a7 c8 e7 g8 h6 g4 h2 f1 d2 b1 a3 c2 e1 f3 h4 g2 e3 d1 b2 a4 c3 b5 d4 f5 d6 c4 e5 d3 f2 h1 g3 e4 c5 d7 b6 a8 c7 d5 f4 e6 g7 e8 f6 h5</pre>
Line 2,207:
 
The following draws on console the progress of the horsie. Specify board size on commandline, or use default 8.
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Line 2,309:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp}}==
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
 
Line 2,395:
}
}
}</langsyntaxhighlight>
 
=={{header|C++}}==
Line 2,402:
Uses Warnsdorff's rule and (iterative) backtracking if that fails.
 
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <iomanip>
#include <array>
Line 2,545:
cout << b3 << endl;
return 0;
}</langsyntaxhighlight>
 
Output:
Line 2,600:
This interactive program will ask for a starting case in algebraic notation and, also, whether a closed tour is desired. Each next move is selected according to Warnsdorff's rule; ties are broken at random.
 
The closed tour algorithm is quite crude: just find tours over and over until one happens to be closed by chance.
 
This code is quite verbose: I tried to make it easy for myself and for otherothers to follow and understand. I'm not a Lisp expert, so I probably missed some idiomatic shortcuts I could have used to make it shorter.
 
For some reason, the interactive part does not work with sbclSBCL, but it works fine witwith clispCLISP.
<langsyntaxhighlight lang="lisp">;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Solving the knight's tour. ;;;
;;; Warnsdorff's rule with random tie break. ;;;
Line 2,792:
 
(prompt)
(main)</langsyntaxhighlight>
{{out}}
<pre>Starting case (leave blank for random)? a8
Line 2,811:
=={{header|Clojure}}==
Using warnsdorff's rule
<syntaxhighlight lang="clojure">
<lang Clojure>
(defn isin? [x li]
(not= [] (filter #(= x %) li)))
Line 2,837:
(let [np (next-move mov pmoves n)]
(recur (conj mov np) (inc x)))))))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,854:
=={{header|CoffeeScript}}==
This algorithm finds 100,000 distinct solutions to the 8x8 problem in about 30 seconds. It precomputes knight moves up front, so it turns into a pure graph traversal problem. The program uses iteration and backtracking to find solutions.
<langsyntaxhighlight lang="coffeescript">
graph_tours = (graph, max_num_solutions) ->
# graph is an array of arrays
Line 2,969:
illustrate_knights_tour tours[0], BOARD_WIDTH
illustrate_knights_tour tours.pop(), BOARD_WIDTH
</syntaxhighlight>
</lang>
 
output
<syntaxhighlight lang="text">
> time coffee knight.coffee
100000 tours found (showing first and last)
Line 2,999:
user 0m25.656s
sys 0m0.253s
</syntaxhighlight>
</lang>
 
=={{header|D}}==
===Fast Version===
{{trans|C++}}
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.random, std.range,
std.conv, std.typecons, std.typetuple;
 
Line 3,080:
writeln();
}
}</langsyntaxhighlight>
{{out}}
<pre>23 16 11 6 21
Line 3,131:
===Shorter Version===
{{trans|Haskell}}
<langsyntaxhighlight lang="d">import std.stdio, std.math, std.algorithm, std.range, std.typecons;
 
alias Square = Tuple!(int,"x", int,"y");
Line 3,157:
const board = iota(1, 9).cartesianProduct(iota(1, 9)).map!Square.array;
writefln("%(%-(%s -> %)\n%)", board.knightTour([sq]).map!toAlg.chunks(8));
}</langsyntaxhighlight>
{{out}}
<pre>e5 -> d7 -> b8 -> a6 -> b4 -> a2 -> c1 -> b3
Line 3,167:
d6 -> e4 -> c5 -> d3 -> e1 -> g2 -> h4 -> f5
d4 -> e2 -> f4 -> e6 -> g5 -> f3 -> g1 -> h3</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|Forms,Types,SysUtils,Graphics,ExtCtrls}}
[[File:DelphiKnightsTour.png|thumb|none]]
Brute force method. Takes a long time for most solutions, so some optimization should be used. However, it has nice graphics.
 
<syntaxhighlight lang="Delphi">
{ These routines would normally be in a library,
but are presented here for clarity }
 
function PointAdd(V1,V2: TPoint): TPoint;
{Add V1 and V2}
begin
Result.X:= V1.X+V2.X;
Result.Y:= V1.Y+V2.Y;
end;
 
 
const KnightMoves: array [0..7] of TPoint = (
(X: 2; Y:1),(X: 2; Y:-1),
(X:-2; Y:1),(X:-2; Y:-1),
(X:1; Y: 2),(X:-1; Y: 2),
(X:1; Y:-2),(X:-1; Y:-2));
 
var Board: array [0..7,0..7] of boolean;
 
var Path: array of TPoint;
 
var CellSize,BoardSize: integer;
 
var CurPos: TPoint;
 
var BestPath: integer;
 
{-------------------------------------------------------------}
 
procedure DrawBestPath(Image: TImage);
begin
Image.Canvas.TextOut(BoardSize+5,5, IntToStr(BestPath));
end;
 
 
procedure PushPath(P: TPoint);
begin
SetLength(Path,Length(Path)+1);
Path[High(Path)]:=P;
if Length(Path)>BestPath then BestPath:=Length(Path);
end;
 
 
function PopPath: TPoint;
begin
if Length(Path)<1 then exit;
Result:=Path[High(Path)];
SetLength(Path,Length(Path)-1);
end;
 
 
procedure ClearPath;
begin
SetLength(Path,0);
end;
 
{-------- Routines to draw chess board and path --------------}
 
function GetCellCenter(P: TPoint): TPoint;
{Get pixel position of the center of cell}
begin
Result.X:=CellSize div 2 + CellSize * P.X;
Result.Y:=CellSize div 2 + CellSize * P.Y;
end;
 
 
 
procedure DrawPoint(Canvas: TCanvas; P: TPoint);
{Draw a point on the board}
begin
Canvas.Pen.Color:=clYellow;
Canvas.MoveTo(P.X-1,P.Y-1);
Canvas.LineTo(P.X+1,P.Y+1);
Canvas.MoveTo(P.X+1,P.Y-1);
Canvas.LineTo(P.X-1,P.Y+1);
end;
 
 
procedure DrawPathLine(Canvas: TCanvas; P1,P2: TPoint);
{Draw the path line}
var PS1,PS2: TPoint;
begin
PS1:=GetCellCenter(P1);
PS2:=GetCellCenter(P2);
Canvas.Pen.Width:=5;
Canvas.Pen.Color:=clRed;
Canvas.MoveTo(PS1.X,PS1.Y);
Canvas.LineTo(PS2.X,PS2.Y);
DrawPoint(Canvas,PS1);
DrawPoint(Canvas,PS2);
end;
 
 
procedure DrawPath(Canvas: TCanvas);
{Draw all points on the path}
var I: integer;
begin
for I:=0 to High(Path)-1 do
begin
DrawPathLine(Canvas, Path[I],Path[I+1]);
end;
end;
 
 
procedure DrawBoard(Canvas: TCanvas);
{Draw the chess board}
var R,R2: TRect;
var X,Y: integer;
var Color: TColor;
begin
Canvas.Pen.Color:=clBlack;
R:=Rect(0,0,BoardSize,BoardSize);
Canvas.Rectangle(R);
R:=Rect(0,0,CellSize,CellSize);
for Y:=0 to High(Board[0]) do
for X:=0 to High(Board) do
begin
R2:=R;
if ((X+Y) mod 2)=0 then Color:=clWhite
else Color:=clBlack;
Canvas.Brush.Color:=Color;
OffsetRect(R2,X * CellSize, Y * CellSize);
Canvas.Rectangle(R2);
end;
DrawPath(Canvas);
end;
 
 
function AllVisited: boolean;
{Test if all squares have been visit by path}
var X,Y: integer;
begin
Result:=False;
for Y:=0 to High(Board[0]) do
for X:=0 to High(Board) do
if not Board[X,Y] then exit;
Result:=True;
end;
 
 
 
procedure ClearBoard;
{Clear all board positions}
var X,Y: integer;
begin
for Y:=0 to High(Board[0]) do
for X:=0 to High(Board) do
Board[X,Y]:=False;
end;
 
 
 
function IsValidMove(Pos,Move: TPoint): boolean;
{Test if potential move is valid}
var NP: TPoint;
begin
Result:=False;
NP:=PointAdd(Pos,Move);
if (NP.X<0) or (NP.X>High(Board)) or
(NP.Y<0) or (NP.Y>High(Board[0])) then exit;
if Board[NP.X,NP.Y] then exit;
Result:=True;
end;
 
 
procedure ConfigureScreen(Image: TImage);
{Configure screen size}
begin
if Image.Width<Image.Height then BoardSize:=Image.Width
else BoardSize:=Image.Height;
CellSize:=BoardSize div 8;
end;
 
 
 
 
procedure SetPosition(Image: TImage; P: TPoint; Value: boolean);
{Set a new position by adding it to path}
{Marking position as used and redrawing board}
begin
if Value then PushPath(P)
else P:=PopPath;
Board[P.X,P.Y]:=Value;
DrawBoard(Image.Canvas);
DrawBestPath(Image);
Image.Repaint;
end;
 
 
 
procedure TryAllMoves(Image: TImage; Pos: TPoint);
{Recursively try all moves}
var I: integer;
var NewPos: TPoint;
begin
SetPosition(Image,Pos,True);
if AllVisited then exit;
for I:=0 to High(KnightMoves) do
begin
if AbortFlag then Exit;
if IsValidMove(Pos,KnightMoves[I]) then
begin
NewPos:=PointAdd(Pos,KnightMoves[I]);
TryAllMoves(Image,NewPos);
end;
end;
SetPosition(Image,Pos,False);
Application.ProcessMessages;
end;
 
 
procedure DoKnightsTour(Image: TImage);
{Solve Knights tour by testing all paths}
begin
BestPath:=0;
ConfigureScreen(Image);
ClearPath;
ClearBoard;
DrawBoard(Image.Canvas);
TryAllMoves(Image, Point(0,0));
end;
 
</syntaxhighlight>
{{out}}
 
<pre>
</pre>
 
=={{header|EchoLisp}}==
 
The algorithm uses iterative backtracking and Warnsdorff's heuristic. It can output closed or non-closed tours.
<langsyntaxhighlight lang="lisp">
(require 'plot)
(define *knight-moves*
Line 3,240 ⟶ 3,476:
(play starter 0 starter (dim n) wants-open)
(catch (hit mess) (show-steps n wants-open))))
</syntaxhighlight>
</lang>
 
 
{{out}}
<langsyntaxhighlight lang="lisp">
(k-tour 8 0 #f)
♞-closed-tour: 66 tries.
Line 3,278 ⟶ 3,514:
79 76 83 18 91 74 137 16 169 72 153 14 167 70 157 12 63 68 55 10
82 19 80 75 84 17 92 73 152 15 168 71 154 13 62 69 54 11 52 67
</syntaxhighlight>
</lang>
 
;Plotting:
64 shades of gray. We plot the move sequence in shades of gray, from black to white. The starting square is red. The ending square is green. One can observe that the squares near the border are played first (dark squares).
<langsyntaxhighlight lang="lisp">
(define (step-color x y n last-one)
(letrec ((sq (square (floor x) (floor y) n))
Line 3,292 ⟶ 3,528:
(define ( k-plot n)
(plot-rgb (lambda (x y) (step-color x y n (dim n))) (- n epsilon) (- n epsilon)))
</syntaxhighlight>
</lang>
 
 
Line 3,301 ⟶ 3,537:
=={{header|Elixir}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="elixir">defmodule Board do
import Integer, only: [is_odd: 1]
Line 3,364 ⟶ 3,600:
Board.knight_tour(4,9,1,1)
Board.knight_tour(5,5,1,2)
Board.knight_tour(12,12,2,2)</langsyntaxhighlight>
 
{{out}}
Line 3,410 ⟶ 3,646:
 
=={{header|Elm}}==
<langsyntaxhighlight lang="elm">module Main exposing (main)
 
import Browser exposing (element)
Line 3,755 ⟶ 3,991:
, subscriptions = subscriptions
}
</syntaxhighlight>
</lang>
 
Link to live demo: https://dmcbane.github.io/knights-tour/
Line 3,761 ⟶ 3,997:
=={{header|Erlang}}==
Again I use backtracking. It seemed easier this time.
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( knights_tour ).
 
Line 3,840 ⟶ 4,076:
next_moves_row( 8 ) -> [6, 7];
next_moves_row( N ) -> [N - 2, N - 1, N + 1, N + 2].
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,866 ⟶ 4,102:
=={{header|ERRE}}==
Taken from ERRE distribution disk. Comments are in Italian.
<syntaxhighlight lang="erre">
<lang ERRE>
! **********************************************************************
! * *
Line 4,076 ⟶ 4,312:
UNTIL A$<>""
END PROGRAM
</syntaxhighlight>
</lang>
{{out}}
<pre> *** LA GALOPPATA DEL CAVALIERE ***
Line 4,097 ⟶ 4,333:
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">
Dim Shared As Integer tamano, xc, yc, nm
Dim As Integer f, qm, nmov, n = 0
Line 4,155 ⟶ 4,391:
Sleep
End
</syntaxhighlight>
</lang>
{{out}}
[https://www.dropbox.com/s/s3bpwechpoueum4/Knights%20Tour%20FreeBasic.png?dl=0 Knights Tour FreeBasic image]
Line 4,180 ⟶ 4,416:
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Knight%27s_tour}}
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation &mdash;i.e. XML, JSON&mdash; they are intended for storage and transfer purposes more than visualization and edition.
 
Programs in Fōrmulæ are created/edited online in its [https://formulae.org website], However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used.
 
In '''[https://formulae.org/?example=Knight%27s_tour this]''' page you can see the program(s) related to this task and their results.
 
=={{header|Fortran}}==
Line 4,191 ⟶ 4,423:
{{works with|gfortran|11.2.1}}
{{works with|f2c}}
<langsyntaxhighlight lang="fortran">C-----------------------------------------------------------------------
C
C Find Knight’s Tours.
Line 4,841 ⟶ 5,073:
end
 
C-----------------------------------------------------------------------</langsyntaxhighlight>
{{out}}
$ echo "c5 2 T" | ./knights_tour
<pre> Tour number 1
c5 -> a6 -> b8 -> d7 -> f8 -> h7 -> g5 -> h3 ->
g1 -> e2 -> c1 -> a2 -> b4 -> d3 -> e1 -> g2 ->
h4 -> g6 -> h8 -> f7 -> d8 -> b7 -> a5 -> b3 ->
a1 -> c2 -> a3 -> b1 -> d2 -> f3 -> h2 -> f1 ->
g3 -> h1 -> f2 -> e4 -> c3 -> a4 -> b2 -> d1 ->
e3 -> g4 -> h6 -> g8 -> f6 -> h5 -> f4 -> d5 ->
e7 -> c8 -> a7 -> c6 -> e5 -> c4 -> b6 -> a8 ->
c7 -> e8 -> d6 -> b5 -> d4 -> f5 -> g7 -> e6 -> cycle
+----+----+----+----+----+----+----+----+
8 | 56 | 3 | 50 | 21 | 58 | 5 | 44 | 19 |
+----+----+----+----+----+----+----+----+
7 | 51 | 22 | 57 | 4 | 49 | 20 | 63 | 6 |
+----+----+----+----+----+----+----+----+
6 | 2 | 55 | 52 | 59 | 64 | 45 | 18 | 43 |
+----+----+----+----+----+----+----+----+
5 | 23 | 60 | 1 | 48 | 53 | 62 | 7 | 46 |
+----+----+----+----+----+----+----+----+
4 | 38 | 13 | 54 | 61 | 36 | 47 | 42 | 17 |
+----+----+----+----+----+----+----+----+
3 | 27 | 24 | 37 | 14 | 41 | 30 | 33 | 8 |
+----+----+----+----+----+----+----+----+
2 | 12 | 39 | 26 | 29 | 10 | 35 | 16 | 31 |
+----+----+----+----+----+----+----+----+
1 | 25 | 28 | 11 | 40 | 15 | 32 | 9 | 34 |
+----+----+----+----+----+----+----+----+
a b c d e f g h
 
Tour number 2
c5 -> a6 -> b8 -> d7 -> f8 -> h7 -> g5 -> h3 ->
g1 -> e2 -> c1 -> a2 -> b4 -> d3 -> e1 -> g2 ->
h4 -> g6 -> h8 -> f7 -> d8 -> b7 -> a5 -> b3 ->
a1 -> c2 -> a3 -> b1 -> d2 -> f3 -> h2 -> f1 ->
g3 -> h1 -> f2 -> e4 -> c3 -> a4 -> b2 -> d1 ->
e3 -> g4 -> h6 -> g8 -> f6 -> h5 -> f4 -> d5 ->
e7 -> c8 -> a7 -> c6 -> e5 -> c4 -> b6 -> a8 ->
c7 -> b5 -> d6 -> e8 -> g7 -> f5 -> d4 -> e6 -> cycle
+----+----+----+----+----+----+----+----+
8 | 56 | 3 | 50 | 21 | 60 | 5 | 44 | 19 |
+----+----+----+----+----+----+----+----+
7 | 51 | 22 | 57 | 4 | 49 | 20 | 61 | 6 |
+----+----+----+----+----+----+----+----+
6 | 2 | 55 | 52 | 59 | 64 | 45 | 18 | 43 |
+----+----+----+----+----+----+----+----+
5 | 23 | 58 | 1 | 48 | 53 | 62 | 7 | 46 |
+----+----+----+----+----+----+----+----+
4 | 38 | 13 | 54 | 63 | 36 | 47 | 42 | 17 |
+----+----+----+----+----+----+----+----+
3 | 27 | 24 | 37 | 14 | 41 | 30 | 33 | 8 |
+----+----+----+----+----+----+----+----+
2 | 12 | 39 | 26 | 29 | 10 | 35 | 16 | 31 |
+----+----+----+----+----+----+----+----+
1 | 25 | 28 | 11 | 40 | 15 | 32 | 9 | 34 |
+----+----+----+----+----+----+----+----+
a b c d e f g h
</pre>
 
===Ratfor77===
{{trans|ATS}}
For use with the public domain ratfor77 translator and a FORTRAN 77 compiler.
<lang ratfor>#-----------------------------------------------------------------------
#
# Find Knight’s Tours.
#
# Using Warnsdorff’s heuristic, find multiple solutions.
# Optionally accept only closed tours.
#
# This program is migrated from my implementation for ATS/Postiats.
# Arrays with dimension 1:64 take the place of stack frames.
#
# Compile with, for instance:
#
# ratfor77 knights_tour.r > knights_tour.f
# gfortran -O2 -g -std=legacy -o knights_tour knights_tour.f
#
# or
#
# ratfor77 knights_tour.r > knights_tour.f
# f2c knights_tour.f
# cc -O -o knights_tour knights_tour.c -lf2c
#
# Usage examples:
#
# One tour starting at a1, either open or closed:
#
# echo "a1 1 F" | ./knights_tour
#
# No more than 2000 closed tours starting at c5:
#
# echo "c5 2000 T" | ./knights_tour
#
#-----------------------------------------------------------------------
 
program ktour
implicit none
 
character*2 alg
integer i, j
integer mxtour
logical closed
 
read (*,*) alg, mxtour, closed
call alg2ij (alg, i, j)
call explor (i, j, mxtour, closed)
 
end
 
#-----------------------------------------------------------------------
 
subroutine explor (istart, jstart, mxtour, closed)
implicit none
 
# Explore the space of 'Warnsdorffian' knight’s paths, looking for
# and printing complete tours.
 
integer istart, jstart # The starting position.
integer mxtour # The maximum number of tours to print.
logical closed # Closed tours only?
 
integer board(1:8,1:8)
integer imove(1:8,1:64)
integer jmove(1:8,1:64)
integer nmove(1:64)
integer n
integer itours
logical goodmv
logical isclos
 
itours = 0
call initbd (board)
n = 1
nmove(1) = 8
imove(8, 1) = istart
jmove(8, 1) = jstart
 
while (itours < mxtour && n != 0) {
if (nmove(n) == 9) {
n = n - 1
if (n != 0) {
call unmove (board, imove, jmove, nmove, n)
nmove(n) = nmove(n) + 1
}
} else if (goodmv (imove, nmove, n)) {
call mkmove (board, imove, jmove, nmove, n)
if (n == 64) {
if (.not. closed) {
itours = itours + 1
call prnt (board, itours)
} else if (isclos (board)) {
itours = itours + 1
call prnt (board, itours)
}
call unmove (board, imove, jmove, nmove, n)
nmove(n) = 9
} else if (n == 63) {
call possib (board, n, imove, jmove, nmove)
n = n + 1
nmove(n) = 1
} else {
call nxtmov (board, n, imove, jmove, nmove)
n = n + 1
nmove(n) = 1
}
} else {
nmove(n) = nmove(n) + 1
}
}
 
end
 
#-----------------------------------------------------------------------
 
subroutine initbd (board)
implicit none
 
# Initialize a chessboard with empty squares.
 
integer board(1:8,1:8)
 
integer i, j
 
do j = 1, 8 {
do i = 1, 8 {
board(i, j) = -1
}
}
 
end
 
#-----------------------------------------------------------------------
 
subroutine mkmove (board, imove, jmove, nmove, n)
implicit none
 
# Fill a square with a move number.
 
integer board(1:8, 1:8)
integer imove(1:8, 1:64)
integer jmove(1:8, 1:64)
integer nmove(1:64)
integer n
 
board(imove(nmove(n), n), jmove(nmove(n), n)) = n
 
end
 
#-----------------------------------------------------------------------
 
subroutine unmove (board, imove, jmove, nmove, n)
implicit none
 
# Unmake a mkmove.
 
integer board(1:8, 1:8)
integer imove(1:8, 1:64)
integer jmove(1:8, 1:64)
integer nmove(1:64)
integer n
 
board(imove(nmove(n), n), jmove(nmove(n), n)) = -1
 
end
 
#-----------------------------------------------------------------------
 
function goodmv (imove, nmove, n)
implicit none
 
logical goodmv
integer imove(1:8, 1:64)
integer nmove(1:64)
integer n
 
goodmv = (imove(nmove(n), n) != -1)
 
end
 
#-----------------------------------------------------------------------
 
subroutine prnt (board, itours)
implicit none
 
# Print a knight's tour.
 
integer board(1:8,1:8)
integer itours
 
10000 format (1X)
 
# The following plethora of format statements seemed a simple way to
# get this working with f2c. (For gfortran, the 'I0' format
# sufficed.)
10010 format (1X, "Tour number ", I1)
10020 format (1X, "Tour number ", I2)
10030 format (1X, "Tour number ", I3)
10040 format (1X, "Tour number ", I4)
10050 format (1X, "Tour number ", I5)
10060 format (1X, "Tour number ", I6)
10070 format (1X, "Tour number ", I20)
 
if (itours < 10) {
write (*, 10010) itours
} else if (itours < 100) {
write (*, 10020) itours
} else if (itours < 1000) {
write (*, 10030) itours
} else if (itours < 10000) {
write (*, 10040) itours
} else if (itours < 100000) {
write (*, 10050) itours
} else if (itours < 1000000) {
write (*, 10060) itours
} else {
write (*, 10070) itours
}
call prntmv (board)
call prntbd (board)
write (*, 10000)
 
end
 
#-----------------------------------------------------------------------
 
subroutine prntbd (board)
implicit none
 
# Print a chessboard with the move number in each square.
 
integer board(1:8,1:8)
 
integer i, j
 
10000 format (1X, " ", 8("+----"), "+")
10010 format (1X, I2, " ", 8(" | ", I2), " | ")
10020 format (1X, " ", 8(" ", A1))
 
do i = 8, 1, -1 {
write (*, 10000)
write (*, 10010) i, (board(i, j), j = 1, 8)
}
write (*, 10000)
write (*, 10020) 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'
 
end
 
#-----------------------------------------------------------------------
 
subroutine prntmv (board)
implicit none
 
# Print the moves of a knight's path, in algebraic notation.
 
integer board(1:8,1:8)
 
integer ipos(1:64)
integer jpos(1:64)
integer numpos
character*2 alg(1:64)
integer columns(1:8)
integer k
integer m
 
character*72 lines(1:8)
 
10000 format (1X, A)
 
call bd2pos (board, ipos, jpos, numpos)
 
# Convert the positions to algebraic notation.
do k = 1, numpos {
call ij2alg (ipos(k), jpos(k), alg(k))
}
 
# Fill lines with algebraic notations.
do m = 1, 8 {
columns(m) = 1
}
m = 1
do k = 1, numpos {
lines(m)(columns(m) : columns(m) + 1) = alg(k)(1:2)
columns(m) = columns(m) + 2
if (k != numpos) {
lines(m)(columns(m) : columns(m) + 3) = " -> "
columns(m) = columns(m) + 4
} else if (numpos == 64 && _
((abs (ipos(numpos) - ipos(1)) == 2 _
&& abs (jpos(numpos) - jpos(1)) == 1) _
|| ((abs (ipos(numpos) - ipos(1)) == 1 _
&& abs (jpos(numpos) - jpos(1)) == 2)))) {
lines(m)(columns(m) : columns(m) + 8) = " -> cycle"
columns(m) = columns(m) + 9
}
if (mod (k, 8) == 0) m = m + 1
}
 
# Print the lines that have stuff in them.
do m = 1, 8 {
if (columns(m) != 1) {
write (*, 10000) lines(m)(1 : columns(m) - 1)
}
}
 
end
 
#-----------------------------------------------------------------------
 
function isclos (board)
implicit none
 
# Is a board a closed tour?
 
logical isclos
integer board(1:8,1:8)
integer ipos(1:64) # The i-positions in order.
integer jpos(1:64) # The j-positions in order.
integer numpos # The number of positions so far.
 
call bd2pos (board, ipos, jpos, numpos)
 
isclos = (numpos == 64 && _
((abs (ipos(numpos) - ipos(1)) == 2 _
&& abs (jpos(numpos) - jpos(1)) == 1) _
|| ((abs (ipos(numpos) - ipos(1)) == 1 _
&& abs (jpos(numpos) - jpos(1)) == 2))))
 
end
 
#-----------------------------------------------------------------------
 
subroutine bd2pos (board, ipos, jpos, numpos)
implicit none
 
# Convert from a board to a list of board positions.
 
integer board(1:8,1:8)
integer ipos(1:64) # The i-positions in order.
integer jpos(1:64) # The j-positions in order.
integer numpos # The number of positions so far.
 
integer i, j
 
numpos = 0
do i = 1, 8 {
do j = 1, 8 {
if (board(i, j) != -1) {
numpos = max (board(i, j), numpos)
ipos(board(i, j)) = i
jpos(board(i, j)) = j
}
}
}
 
end
 
#-----------------------------------------------------------------------
 
subroutine nxtmov (board, n, imove, jmove, nmove)
implicit none
 
# Find possible next moves. Prune and sort the moves according to
# Warnsdorff's heuristic, keeping only those that have the minimum
# number of legal following moves.
 
integer board(1:8,1:8)
integer n
integer imove(1:8,1:64)
integer jmove(1:8,1:64)
integer nmove(1:64)
 
integer w1, w2, w3, w4, w5, w6, w7, w8
integer w
integer n1
integer pickw
 
call possib (board, n, imove, jmove, nmove)
 
n1 = n + 1
nmove(n1) = 1
call countf (board, n1, imove, jmove, nmove, w1)
nmove(n1) = 2
call countf (board, n1, imove, jmove, nmove, w2)
nmove(n1) = 3
call countf (board, n1, imove, jmove, nmove, w3)
nmove(n1) = 4
call countf (board, n1, imove, jmove, nmove, w4)
nmove(n1) = 5
call countf (board, n1, imove, jmove, nmove, w5)
nmove(n1) = 6
call countf (board, n1, imove, jmove, nmove, w6)
nmove(n1) = 7
call countf (board, n1, imove, jmove, nmove, w7)
nmove(n1) = 8
call countf (board, n1, imove, jmove, nmove, w8)
 
w = pickw (w1, w2, w3, w4, w5, w6, w7, w8)
 
if (w == 0) {
call disabl (imove(1, n1), jmove(1, n1))
call disabl (imove(2, n1), jmove(2, n1))
call disabl (imove(3, n1), jmove(3, n1))
call disabl (imove(4, n1), jmove(4, n1))
call disabl (imove(5, n1), jmove(5, n1))
call disabl (imove(6, n1), jmove(6, n1))
call disabl (imove(7, n1), jmove(7, n1))
call disabl (imove(8, n1), jmove(8, n1))
} else {
if (w != w1) call disabl (imove(1, n1), jmove(1, n1))
if (w != w2) call disabl (imove(2, n1), jmove(2, n1))
if (w != w3) call disabl (imove(3, n1), jmove(3, n1))
if (w != w4) call disabl (imove(4, n1), jmove(4, n1))
if (w != w5) call disabl (imove(5, n1), jmove(5, n1))
if (w != w6) call disabl (imove(6, n1), jmove(6, n1))
if (w != w7) call disabl (imove(7, n1), jmove(7, n1))
if (w != w8) call disabl (imove(8, n1), jmove(8, n1))
}
 
end
 
#-----------------------------------------------------------------------
 
subroutine countf (board, n, imove, jmove, nmove, w)
implicit none
 
# Count the number of moves possible after an nth move.
 
integer board(1:8,1:8)
integer n
integer imove(1:8,1:64)
integer jmove(1:8,1:64)
integer nmove(1:64)
integer w
 
logical goodmv
integer n1
 
if (goodmv (imove, nmove, n)) {
call mkmove (board, imove, jmove, nmove, n)
call possib (board, n, imove, jmove, nmove)
n1 = n + 1
w = 0
if (imove(1, n1) != -1) w = w + 1
if (imove(2, n1) != -1) w = w + 1
if (imove(3, n1) != -1) w = w + 1
if (imove(4, n1) != -1) w = w + 1
if (imove(5, n1) != -1) w = w + 1
if (imove(6, n1) != -1) w = w + 1
if (imove(7, n1) != -1) w = w + 1
if (imove(8, n1) != -1) w = w + 1
call unmove (board, imove, jmove, nmove, n)
} else {
# The nth move itself is impossible.
w = 0
}
 
end
 
#-----------------------------------------------------------------------
 
function pickw (w1, w2, w3, w4, w5, w6, w7, w8)
implicit none
 
# From w1..w8, pick out the least nonzero value (or zero if they all
# equal zero).
 
integer pickw
integer w1, w2, w3, w4, w5, w6, w7, w8
 
integer w
integer pickw1
 
w = 0
w = pickw1 (w, w1)
w = pickw1 (w, w2)
w = pickw1 (w, w3)
w = pickw1 (w, w4)
w = pickw1 (w, w5)
w = pickw1 (w, w6)
w = pickw1 (w, w7)
w = pickw1 (w, w8)
 
pickw = w
 
end
 
#-----------------------------------------------------------------------
 
function pickw1 (u, v)
implicit none
 
# A small function used by pickw.
 
integer pickw1
integer u, v
 
if (v == 0) {
pickw1 = u
} else if (u == 0) {
pickw1 = v
} else {
pickw1 = min (u, v)
}
 
end
 
#-----------------------------------------------------------------------
 
subroutine possib (board, n, imove, jmove, nmove)
implicit none
 
# Find moves that are possible from an nth-move position.
 
integer board(1:8,1:8)
integer n
integer imove(1:8,1:64)
integer jmove(1:8,1:64)
integer nmove(1:64)
 
integer i, j
integer n1
 
i = imove(nmove(n), n)
j = jmove(nmove(n), n)
n1 = n + 1
call trymov (board, i + 1, j + 2, imove(1, n1), jmove(1, n1))
call trymov (board, i + 2, j + 1, imove(2, n1), jmove(2, n1))
call trymov (board, i + 1, j - 2, imove(3, n1), jmove(3, n1))
call trymov (board, i + 2, j - 1, imove(4, n1), jmove(4, n1))
call trymov (board, i - 1, j + 2, imove(5, n1), jmove(5, n1))
call trymov (board, i - 2, j + 1, imove(6, n1), jmove(6, n1))
call trymov (board, i - 1, j - 2, imove(7, n1), jmove(7, n1))
call trymov (board, i - 2, j - 1, imove(8, n1), jmove(8, n1))
 
end
 
#-----------------------------------------------------------------------
 
subroutine trymov (board, i, j, imove, jmove)
implicit none
 
# Try a move to square (i, j).
 
integer board(1:8,1:8)
integer i, j
integer imove, jmove
 
call disabl (imove, jmove)
if (1 <= i && i <= 8 && 1 <= j && j <= 8) {
if (board(i,j) == -1) {
call enable (i, j, imove, jmove)
}
}
 
end
 
#-----------------------------------------------------------------------
 
subroutine enable (i, j, imove, jmove)
implicit none
 
# Enable a potential move.
 
integer i, j
integer imove, jmove
 
imove = i
jmove = j
 
end
 
#-----------------------------------------------------------------------
 
subroutine disabl (imove, jmove)
implicit none
 
# Disable a potential move.
 
integer imove, jmove
 
imove = -1
jmove = -1
 
end
 
#-----------------------------------------------------------------------
 
subroutine alg2ij (alg, i, j)
implicit none
 
# Convert, for instance, 'c5' to i=3,j=5.
 
character*2 alg
integer i, j
 
if (alg(1:1) == 'a') j = 1
if (alg(1:1) == 'b') j = 2
if (alg(1:1) == 'c') j = 3
if (alg(1:1) == 'd') j = 4
if (alg(1:1) == 'e') j = 5
if (alg(1:1) == 'f') j = 6
if (alg(1:1) == 'g') j = 7
if (alg(1:1) == 'h') j = 8
 
if (alg(2:2) == '1') i = 1
if (alg(2:2) == '2') i = 2
if (alg(2:2) == '3') i = 3
if (alg(2:2) == '4') i = 4
if (alg(2:2) == '5') i = 5
if (alg(2:2) == '6') i = 6
if (alg(2:2) == '7') i = 7
if (alg(2:2) == '8') i = 8
 
end
 
#-----------------------------------------------------------------------
 
subroutine ij2alg (i, j, alg)
implicit none
 
# Convert, for instance, i=3,j=5 to 'c5'.
 
integer i, j
character*2 alg
 
character alg1
character alg2
 
if (j == 1) alg1 = 'a'
if (j == 2) alg1 = 'b'
if (j == 3) alg1 = 'c'
if (j == 4) alg1 = 'd'
if (j == 5) alg1 = 'e'
if (j == 6) alg1 = 'f'
if (j == 7) alg1 = 'g'
if (j == 8) alg1 = 'h'
 
if (i == 1) alg2 = '1'
if (i == 2) alg2 = '2'
if (i == 3) alg2 = '3'
if (i == 4) alg2 = '4'
if (i == 5) alg2 = '5'
if (i == 6) alg2 = '6'
if (i == 7) alg2 = '7'
if (i == 8) alg2 = '8'
 
alg(1:1) = alg1
alg(2:2) = alg2
 
end
 
#-----------------------------------------------------------------------</lang>
 
{{out}}
$ echo "c5 2 T" | ./knights_tour
Line 5,617 ⟶ 5,136:
{{works with|gfortran|11.2.1}}
{{trans|ATS}}
<langsyntaxhighlight lang="fortran">!-----------------------------------------------------------------------
!
! Find Knight’s Tours.
Line 6,177 ⟶ 5,696:
end program
 
!-----------------------------------------------------------------------</langsyntaxhighlight>
 
{{out}}
Line 6,241 ⟶ 5,760:
{{works with|gfortran|11.2.1}}
(This one is ''not'' a translation of my ATS implementation. I wrote it earlier.)
<langsyntaxhighlight lang="fortran">!!!
!!! Find a Knight’s Tour.
!!!
Line 6,566 ⟶ 6,085:
end if
end do
end program knights_tour_main</langsyntaxhighlight>
 
$ ./knights_tour a1 b2 c3
Line 6,598 ⟶ 6,117:
=={{header|Go}}==
===Warnsdorf's rule===
<langsyntaxhighlight lang="go">package main
 
import (
Line 6,705 ⟶ 6,224:
}
return true
}</langsyntaxhighlight>
{{out}}
<pre>
Line 6,718 ⟶ 6,237:
</pre>
===Ant colony===
<langsyntaxhighlight lang="go">/* Adapted from "Enumerating Knight's Tours using an Ant Colony Algorithm"
by Philip Hingston and Graham Kendal,
PDF at http://www.cs.nott.ac.uk/~gxk/papers/cec05knights.pdf. */
Line 6,909 ⟶ 6,428:
tourCh <- moves
}
}</langsyntaxhighlight>
Output:
<pre>
Line 6,925 ⟶ 6,444:
 
=={{header|Haskell}}==
<langsyntaxhighlight Haskelllang="haskell">import Data.Bifunctor (bimap)
import Data.Char (chr, ord)
import Data.List (intercalate, minimumBy, sort, (\\))
Line 6,986 ⟶ 6,505:
printTour tour = do
putStrLn $ intercalate " -> " $ take 8 tour
printTour $ drop 8 tour</langsyntaxhighlight>
{{Out}}
<pre>e5 -> f7 -> h8 -> g6 -> h4 -> g2 -> e1 -> f3
Line 7,004 ⟶ 6,523:
 
The algorithm doesn't always generate a complete tour.
<langsyntaxhighlight Iconlang="icon">link printf
 
procedure main(A)
Line 7,104 ⟶ 6,623:
}
every write(hdr2|hdr1|&null)
end</langsyntaxhighlight>
 
The following can be used when debugging to validate the board structure and to image the available moves on the board.
<langsyntaxhighlight Iconlang="icon">procedure DumpBoard(B) #: Dump Board internals
write("Board size=",B.N)
write("Available Moves at start of tour:", ImageMovesTo(B.movesto))
Line 7,117 ⟶ 6,636:
every s ||:= " " || (!sort(movesto[k])|"\n")
return s
end</langsyntaxhighlight>
 
 
Line 7,169 ⟶ 6,688:
'''Solution:'''<br>
[[j:Essays/Knight's Tour|The Knight's tour essay on the Jwiki]] shows a couple of solutions including one using [[wp:Knight's_tour#Warnsdorff.27s_algorithm|Warnsdorffs algorithm]].
<langsyntaxhighlight lang="j">NB. knight moves for each square of a (y,y) board
kmoves=: monad define
t=. (>,{;~i.y) +"1/ _2]\2 1 2 _1 1 2 1 _2 _1 2 _1 _2 _2 1 _2 _1
Line 7,185 ⟶ 6,704:
assert. ~:p
(,~y)$/:p
)</langsyntaxhighlight>
 
'''Example Use:'''
<langsyntaxhighlight lang="j"> ktourw 8 NB. solution for an 8 x 8 board
0 25 14 23 28 49 12 31
15 22 27 50 13 30 63 48
Line 7,209 ⟶ 6,728:
555 558 553 778 563 570 775 780 785 772 1000...
100 551 556 561 102 777 572 771 104 781 57...
557 554 101 552 571 562 103 776 573 770 10...</langsyntaxhighlight>
 
=={{header|Java}}==
{{Works with|Java|7}}
<langsyntaxhighlight lang="java">import java.util.*;
 
public class KnightsTour {
Line 7,310 ⟶ 6,829:
}
}
}</langsyntaxhighlight>
<pre>34 17 20 3 36 7 22 5
19 2 35 40 21 4 37 8
Line 7,321 ⟶ 6,840:
===More efficient non-trackback solution===
{{Works with|Java|8}}
<syntaxhighlight lang="text">
package com.knight.tour;
import java.util.ArrayList;
Line 7,480 ⟶ 6,999:
}
}
</syntaxhighlight>
</lang>
<pre>
Found a path for 8 X 8 chess board.
Line 7,497 ⟶ 7,016:
You can test it [http://paulo-jorente.de/webgames/repos/knightsTour/ here].
 
<langsyntaxhighlight lang="javascript">
class KnightTour {
constructor() {
Line 7,713 ⟶ 7,232:
}
new KnightTour();
</syntaxhighlight>
</lang>
To test it, you'll need an index.html
<pre>
Line 7,783 ⟶ 7,302:
A composition of values, drawing on generic abstractions:
{{Trans|Haskell}}
<langsyntaxhighlight lang="javascript">(() => {
'use strict';
 
Line 8,076 ⟶ 7,595:
// MAIN ---
return main();
})();</langsyntaxhighlight>
{{Out}}
<pre>(Board size 8*8)
Line 8,105 ⟶ 7,624:
=={{header|Julia}}==
Uses the Hidato puzzle solver module, which has its source code listed [[Solve_a_Hidato_puzzle#Julia | here]] in the Hadato task.
<langsyntaxhighlight lang="julia">using .Hidato # Note that the . here means to look locally for the module rather than in the libraries
 
const chessboard = """
Line 8,123 ⟶ 7,642:
hidatosolve(board, maxmoves, knightmoves, fixed, starts[1][1], starts[1][2], 1)
printboard(board)
</langsyntaxhighlight>{{output}}<pre>
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
Line 8,146 ⟶ 7,665:
{{trans|Haskell}}
 
<langsyntaxhighlight lang="scala">data class Square(val x : Int, val y : Int)
 
val board = Array(8 * 8, { Square(it / 8 + 1, it % 8 + 1) })
Line 8,174 ⟶ 7,693:
col = (col + 1) % 8
}
}</langsyntaxhighlight>
 
{{out}}
Line 8,190 ⟶ 7,709:
Influenced by the Python version, although computed tours are different.
 
<langsyntaxhighlight lang="locobasic">10 mode 1:defint a-z
20 input "Board size: ",size
30 input "Start position: ",a$
Line 8,236 ⟶ 7,755:
450 ' skip this move
460 next
470 return</langsyntaxhighlight>
 
[[File:Knights tour Locomotive Basic.png]]
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">N = 8
 
moves = { {1,-2},{2,-1},{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2} }
Line 8,291 ⟶ 7,810:
print( string.format( "%s%d - %s%d", string.sub("ABCDEFGH",last[1],last[1]), last[2], string.sub("ABCDEFGH",lst[i][1],lst[i][1]), lst[i][2] ) )
last = lst[i]
end</langsyntaxhighlight>
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Function KnightTour$(StartW=1, StartH=1){
def boolean swapH, swapV=True
Line 8,396 ⟶ 7,915:
Clipboard ex$
Report ex$
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 8,440 ⟶ 7,959:
Warnsdorff’s rule, with random tie-breaks. The program keeps trying
until it finds a solution. Running time can vary a lot.
 
<lang m4>divert(-1)
Beware the program writes to a file ‘__random_number__’ in the working directory. (This can be avoided in GNU m4 by using ‘esyscmd’ instead of ‘syscmd’. I do not know how to avoid it in general.)
 
<syntaxhighlight lang="m4">divert(-1)
 
----------------------------------------------------------------------
Line 8,551 ⟶ 8,073:
 
dnl Extract the nth position from the path.
define(`path_nth',`substr($1,eval(( $2 ) * 2),2)')
`ifelse($2,0,`path_car($1)',`path_nth(path_cdr($1),eval(( $2 ) - 1))')')
 
define(`random_position',`path_nth($1,randnum(path_length($1)))')
 
define(`random_move',`path_nth($1,randnum(path_length($1)))')
dnl For example, a1d3c5 -> c5d3a1
define(`path_reverse',`ifelse($1,`',`',`$0(path_cdr($1))`'path_car($1)')') dnl FIXME: IS THIS NEEDED? FIXME FIXME FIXME
 
dnl Is the position $1 contained in the path $2?
Line 8,605 ⟶ 8,123:
`path_car($1)`'$0(path_cdr($1),string_cdr($2))')')')
 
dnl Find possiblepotential next moves for the given path.
define(`next_moves',
`ifelse(path_length($1),63,`possible_moves(path_last($1),$1)',
Line 8,615 ⟶ 8,133:
`pushdef(`moves',next_moves($2))`'dnl
ifelse(moves,`',`find_tour($1)',
`find_tour($1,$2`'random_positionrandom_move(next_moves($2)))')`'dnl
popdef(`moves')')')
 
Line 8,622 ⟶ 8,140:
find_tour(a1)
find_tour(c5)
find_tour(h8)</langsyntaxhighlight>
 
{{out}}
Line 8,634 ⟶ 8,152:
=={{header|Mathematica}}/{{header|Wolfram Language}}==
'''Solution'''
<langsyntaxhighlight Mathematicalang="mathematica">knightsTourMoves[start_] :=
Module[{
vertexLabels = (# -> ToString@c[[Quotient[# - 1, 8] + 1]] <> ToString[Mod[# - 1, 8] + 1]) & /@ Range[64], knightsGraph,
Line 8,641 ⟶ 8,159:
hamiltonianCycle = ((FindHamiltonianCycle[knightsGraph] /. UndirectedEdge -> DirectedEdge) /. labels)[[1]];
end = Cases[hamiltonianCycle, (x_ \[DirectedEdge] start) :> x][[1]];
FindShortestPath[g, start, end]]</langsyntaxhighlight>
 
'''Usage'''
<langsyntaxhighlight Mathematicalang="mathematica">knightsTourMoves["d8"]
 
(* out *)
Line 8,650 ⟶ 8,168:
"c7", "a8", "b6", "c8", "d6", "e4", "d2", "f1", "e3", "d1", "f2", "h1", "g3", "e2", "c1", "d3", "e1", "g2", "h4", "f5", "e7", "d5", \
"f4", "h5", "g7", "e8", "f6", "g8", "h6", "g4", "h2", "f3", "g1", "h3", "g5", "h7", "f8", "d7", "e5", "g6", "h8", "f7"}
</syntaxhighlight>
</lang>
 
'''Analysis'''
 
'''vertexLabels''' replaces the default vertex (i.e. square) names of the chessboard with the standard algebraic names "a1", "a2",...,"h8".
<syntaxhighlight lang="mathematica">
<lang Mathematica>
vertexLabels = (# -> ToString@c[[Quotient[# - 1, 8] + 1]] <> ToString[Mod[# - 1, 8] + 1]) & /@ Range[64]
 
Line 8,666 ⟶ 8,184:
41 -> "f1", 42 -> "f2", 43 -> "f3", 44 -> "f4", 45 -> "f5", 46 -> "f6", 47 -> "f7", 48 -> "f8",
49 -> "g1", 50 -> "g2", 51 -> "g3", 52 -> "g4", 53 -> "g5", 54 -> "g6",55 -> "g7", 56 -> "g8",
57 -> "h1", 58 -> "h2", 59 -> "h3", 60 -> "h4", 61 -> "h5", 62 -> "h6", 63 -> "h7", 64 -> "h8"}</langsyntaxhighlight>
 
'''knightsGraph''' creates a graph of the solution space.
<langsyntaxhighlight Mathematicalang="mathematica">knightsGraph = KnightTourGraph[i, i, VertexLabels -> vertexLabels, ImagePadding -> 15];</langsyntaxhighlight>
[[File:KnightsTour-3.png]]
 
Find a Hamiltonian cycle (a path that visits each square exactly one time.)
 
<langsyntaxhighlight Mathematicalang="mathematica">hamiltonianCycle = ((FindHamiltonianCycle[knightsGraph] /. UndirectedEdge -> DirectedEdge) /. labels)[[1]];</langsyntaxhighlight>
 
Find the end square:
 
<langsyntaxhighlight Mathematicalang="mathematica">end = Cases[hamiltonianCycle, (x_ \[DirectedEdge] start) :> x][[1]];</langsyntaxhighlight>
 
Find shortest path from the start square to the end square.
 
<syntaxhighlight lang Mathematica="mathematica">FindShortestPath[g, start, end]]</langsyntaxhighlight>
 
=={{header|Mathprog}}==
Line 8,691 ⟶ 8,209:
2. It is possible to specify which square is used for any Knights Move.
 
<syntaxhighlight lang="text">
/*Knights.mathprog
Line 8,753 ⟶ 8,271:
end;
</syntaxhighlight>
</lang>
 
Produces:
 
<syntaxhighlight lang="text">
GLPSOL: GLPK LP/MIP Solver, v4.47
Parameter(s) specified in the command line:
Line 8,803 ⟶ 8,321:
23 10 21 16 25
Model has been successfully processed
</syntaxhighlight>
</lang>
 
and
 
<syntaxhighlight lang="text">
/*Knights.mathprog
Line 8,872 ⟶ 8,390:
end;
</syntaxhighlight>
</lang>
 
Produces:
 
<syntaxhighlight lang="text">
GLPSOL: GLPK LP/MIP Solver, v4.47
Parameter(s) specified in the command line:
Line 8,941 ⟶ 8,459:
10 55 20 57 12 37 40 1
Model has been successfully processed
</syntaxhighlight>
</lang>
 
=={{header|Nim}}==
Line 8,949 ⟶ 8,467:
We have added a case to test the absence of solution. Note that, in this case, there is a lot of backtracking which considerably slows down the execution.
 
<langsyntaxhighlight Nimlang="nim">import algorithm, options, random, parseutils, strutils, strformat
 
type
Line 9,050 ⟶ 8,568:
#run[5]("c4") # No solution, so very slow compared to other cases.
run[8]("b5")
run[31]("a1")</langsyntaxhighlight>
 
{{out}}
Line 9,108 ⟶ 8,626:
=={{header|ObjectIcon}}==
{{trans|ATS}}
<langsyntaxhighlight lang="objecticon">#
# Find Knight’s Tours.
#
Line 9,470 ⟶ 8,988:
return (((i_diff = 2 & j_diff = 1) |
(i_diff = 1 & j_diff = 2)) & &yes) | fail
end</langsyntaxhighlight>
 
{{out}}
Line 9,533 ⟶ 9,051:
=={{header|Perl}}==
Knight's tour using [[wp:Knight's_tour#Warnsdorff.27s_algorithm|Warnsdorffs algorithm]]
<langsyntaxhighlight lang="perl">use strict;
use warnings;
# Find a knight's tour
Line 9,619 ⟶ 9,137:
return unless $square =~ /^([a-h])([1-8])$/;
return (8-$2, ord($1) - ord('a'));
}</langsyntaxhighlight>
 
Sample output (start square c3):
Line 9,627 ⟶ 9,145:
=={{header|Phix}}==
This is pretty fast (<<1s) up to size 48, before some sizes start to take quite some time to complete. It will even solve a 200x200 in 0.67s
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">size</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span>
Line 9,712 ⟶ 9,230:
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"no solutions found\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 9,725 ⟶ 9,243:
50 27 12 35 64 25 10 7
solution found in 64 tries (0.00s)
</pre>
 
=={{header|Picat}}==
<syntaxhighlight lang="picat">import cp.
 
main =>
N = 8,
A = new_array(N,N),
foreach (R in 1..N, C in 1..N)
Connected = [(R+1, C+2),
(R+1, C-2),
(R-1, C+2),
(R-1, C-2),
(R+2, C+1),
(R+2, C-1),
(R-2, C+1),
(R-2, C-1)],
A[R,C] :: [(R1-1)*N+C1 : (R1,C1) in Connected, R1 >= 1, R1 =< N, C1 >= 1, C1 =< N]
end,
V = vars(A),
circuit(V),
solve([ff],V),
OutputM = new_array(N,N),
fill_output_matrix(N,OutputM,V,1,1),
foreach (R in 1..N)
foreach (C in 1..N)
printf("%3d ", OutputM[R,C])
end,
nl
end.
 
fill_output_matrix(N,OutputM,V,I,Count) =>
if Count =< N*N then
R = (I-1) div N + 1,
C = (I-1) mod N + 1,
OutputM[R,C] = Count,
fill_output_matrix(N,OutputM,V,V[I],Count+1)
end.
</syntaxhighlight>
 
{{out}}
<pre>
1 62 5 10 13 24 55 8
4 11 2 63 6 9 14 23
61 64 35 12 25 56 7 54
34 3 26 59 36 15 22 57
39 60 37 18 27 58 53 16
30 33 40 43 46 17 50 21
41 38 31 28 19 48 45 52
32 29 42 47 44 51 20 49
</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(load "@lib/simul.l")
 
# Build board
Line 9,757 ⟶ 9,325:
(moves Tour) )
(push 'Tour @) )
(flip Tour) )</langsyntaxhighlight>
Output:
<pre>-> (b1 a3 b5 a7 c8 b6 a8 c7 a6 b8 d7 f8 h7 g5 h3 g1 e2 c1 a2 b4 c2 a1 b3 a5 b7
Line 9,765 ⟶ 9,333:
=={{header|PostScript}}==
You probably shouldn't send this to a printer. Solution using Warnsdorffs algorithm.
<langsyntaxhighlight lang="postscript">%!PS-Adobe-3.0
%%BoundingBox: 0 0 300 300
 
Line 9,874 ⟶ 9,442:
3 1 100 { solve } for
 
%%EOF</langsyntaxhighlight>
 
=={{header|Prolog}}==
Line 9,880 ⟶ 9,448:
Knights tour using [[wp:Knight's_tour#Warnsdorff.27s_algorithm|Warnsdorffs algorithm]]
 
<langsyntaxhighlight Prologlang="prolog">% N is the number of lines of the chessboard
knight(N) :-
Max is N * N,
Line 9,960 ⟶ 9,528:
M1 is M + 1,
display(N, M1, T).
</syntaxhighlight>
</lang>
 
Output :
Line 9,999 ⟶ 9,567:
===Alternative version===
{{Works with|GNU Prolog}}
<langsyntaxhighlight lang="prolog">:- initialization(main).
 
 
Line 10,055 ⟶ 9,623:
 
 
main :- make_graph, hamiltonian(5*3,Pn), show_path(Pn), halt.</langsyntaxhighlight>
{{Output}}
<pre> 5 18 35 22 3 16 55 24
Line 10,069 ⟶ 9,637:
=={{header|Python}}==
Knights tour using [[wp:Knight's_tour#Warnsdorff.27s_algorithm|Warnsdorffs algorithm]]
<langsyntaxhighlight lang="python">import copy
 
boardsize=6
Line 10,133 ⟶ 9,701:
start = input('Start position: ')
board = knights_tour(start, boardsize)
print(boardstring(board, boardsize=boardsize))</langsyntaxhighlight>
 
;Sample runs
Line 10,214 ⟶ 9,782:
Based on a slight modification of [[wp:Knight%27s_tour#Warnsdorff.27s_rule|Warnsdorff's algorithm]], in that if a dead-end is reached, the program backtracks to the next best move.
 
<langsyntaxhighlight lang="r">#!/usr/bin/Rscript
# M x N Chess Board.
Line 10,282 ⟶ 9,850:
# Begin tour.
setboard(position, 1); knightTour(position, 2)</langsyntaxhighlight>
 
Output:
Line 10,300 ⟶ 9,868:
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
(define N 8)
Line 10,325 ⟶ 9,893:
" "))))
(draw (tour (random N) (random N)))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 10,341 ⟶ 9,909:
(formerly Perl 6)
{{trans|Perl}}
<syntaxhighlight lang="raku" line>my @board;
{{works with|rakudo|2015-09-17}}
<lang perl6>my @board;
 
my $I = 8;
Line 10,365 ⟶ 9,932:
# Record current move
push @moves, to_algebraic($i,$j);
# @board[$i] //= []; # (uncomment if autoviv is broken)
@board[$i][$j] = $move;
Line 10,415 ⟶ 9,981:
sub from_algebraic($square where /^ (<[a..z]>) (\d+) $/) {
$I - $1, ord(~$0) - ord('a');
}</langsyntaxhighlight>
(Output identical to Perl's above.)
 
=={{Header|RATFOR}}==
{{trans|ATS}}
For use with the public domain ratfor77 translator and a FORTRAN 77 compiler.
<syntaxhighlight lang="ratfor">#-----------------------------------------------------------------------
#
# Find Knight’s Tours.
#
# Using Warnsdorff’s heuristic, find multiple solutions.
# Optionally accept only closed tours.
#
# This program is migrated from my implementation for ATS/Postiats.
# Arrays with dimension 1:64 take the place of stack frames.
#
# Compile with, for instance:
#
# ratfor77 knights_tour.r > knights_tour.f
# gfortran -O2 -g -std=legacy -o knights_tour knights_tour.f
#
# or
#
# ratfor77 knights_tour.r > knights_tour.f
# f2c knights_tour.f
# cc -O -o knights_tour knights_tour.c -lf2c
#
# Usage examples:
#
# One tour starting at a1, either open or closed:
#
# echo "a1 1 F" | ./knights_tour
#
# No more than 2000 closed tours starting at c5:
#
# echo "c5 2000 T" | ./knights_tour
#
#-----------------------------------------------------------------------
 
program ktour
implicit none
 
character*2 alg
integer i, j
integer mxtour
logical closed
 
read (*,*) alg, mxtour, closed
call alg2ij (alg, i, j)
call explor (i, j, mxtour, closed)
 
end
 
#-----------------------------------------------------------------------
 
subroutine explor (istart, jstart, mxtour, closed)
implicit none
 
# Explore the space of 'Warnsdorffian' knight’s paths, looking for
# and printing complete tours.
 
integer istart, jstart # The starting position.
integer mxtour # The maximum number of tours to print.
logical closed # Closed tours only?
 
integer board(1:8,1:8)
integer imove(1:8,1:64)
integer jmove(1:8,1:64)
integer nmove(1:64)
integer n
integer itours
logical goodmv
logical isclos
 
itours = 0
call initbd (board)
n = 1
nmove(1) = 8
imove(8, 1) = istart
jmove(8, 1) = jstart
 
while (itours < mxtour && n != 0) {
if (nmove(n) == 9) {
n = n - 1
if (n != 0) {
call unmove (board, imove, jmove, nmove, n)
nmove(n) = nmove(n) + 1
}
} else if (goodmv (imove, nmove, n)) {
call mkmove (board, imove, jmove, nmove, n)
if (n == 64) {
if (.not. closed) {
itours = itours + 1
call prnt (board, itours)
} else if (isclos (board)) {
itours = itours + 1
call prnt (board, itours)
}
call unmove (board, imove, jmove, nmove, n)
nmove(n) = 9
} else if (n == 63) {
call possib (board, n, imove, jmove, nmove)
n = n + 1
nmove(n) = 1
} else {
call nxtmov (board, n, imove, jmove, nmove)
n = n + 1
nmove(n) = 1
}
} else {
nmove(n) = nmove(n) + 1
}
}
 
end
 
#-----------------------------------------------------------------------
 
subroutine initbd (board)
implicit none
 
# Initialize a chessboard with empty squares.
 
integer board(1:8,1:8)
 
integer i, j
 
do j = 1, 8 {
do i = 1, 8 {
board(i, j) = -1
}
}
 
end
 
#-----------------------------------------------------------------------
 
subroutine mkmove (board, imove, jmove, nmove, n)
implicit none
 
# Fill a square with a move number.
 
integer board(1:8, 1:8)
integer imove(1:8, 1:64)
integer jmove(1:8, 1:64)
integer nmove(1:64)
integer n
 
board(imove(nmove(n), n), jmove(nmove(n), n)) = n
 
end
 
#-----------------------------------------------------------------------
 
subroutine unmove (board, imove, jmove, nmove, n)
implicit none
 
# Unmake a mkmove.
 
integer board(1:8, 1:8)
integer imove(1:8, 1:64)
integer jmove(1:8, 1:64)
integer nmove(1:64)
integer n
 
board(imove(nmove(n), n), jmove(nmove(n), n)) = -1
 
end
 
#-----------------------------------------------------------------------
 
function goodmv (imove, nmove, n)
implicit none
 
logical goodmv
integer imove(1:8, 1:64)
integer nmove(1:64)
integer n
 
goodmv = (imove(nmove(n), n) != -1)
 
end
 
#-----------------------------------------------------------------------
 
subroutine prnt (board, itours)
implicit none
 
# Print a knight's tour.
 
integer board(1:8,1:8)
integer itours
 
10000 format (1X)
 
# The following plethora of format statements seemed a simple way to
# get this working with f2c. (For gfortran, the 'I0' format
# sufficed.)
10010 format (1X, "Tour number ", I1)
10020 format (1X, "Tour number ", I2)
10030 format (1X, "Tour number ", I3)
10040 format (1X, "Tour number ", I4)
10050 format (1X, "Tour number ", I5)
10060 format (1X, "Tour number ", I6)
10070 format (1X, "Tour number ", I20)
 
if (itours < 10) {
write (*, 10010) itours
} else if (itours < 100) {
write (*, 10020) itours
} else if (itours < 1000) {
write (*, 10030) itours
} else if (itours < 10000) {
write (*, 10040) itours
} else if (itours < 100000) {
write (*, 10050) itours
} else if (itours < 1000000) {
write (*, 10060) itours
} else {
write (*, 10070) itours
}
call prntmv (board)
call prntbd (board)
write (*, 10000)
 
end
 
#-----------------------------------------------------------------------
 
subroutine prntbd (board)
implicit none
 
# Print a chessboard with the move number in each square.
 
integer board(1:8,1:8)
 
integer i, j
 
10000 format (1X, " ", 8("+----"), "+")
10010 format (1X, I2, " ", 8(" | ", I2), " | ")
10020 format (1X, " ", 8(" ", A1))
 
do i = 8, 1, -1 {
write (*, 10000)
write (*, 10010) i, (board(i, j), j = 1, 8)
}
write (*, 10000)
write (*, 10020) 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'
 
end
 
#-----------------------------------------------------------------------
 
subroutine prntmv (board)
implicit none
 
# Print the moves of a knight's path, in algebraic notation.
 
integer board(1:8,1:8)
 
integer ipos(1:64)
integer jpos(1:64)
integer numpos
character*2 alg(1:64)
integer columns(1:8)
integer k
integer m
 
character*72 lines(1:8)
 
10000 format (1X, A)
 
call bd2pos (board, ipos, jpos, numpos)
 
# Convert the positions to algebraic notation.
do k = 1, numpos {
call ij2alg (ipos(k), jpos(k), alg(k))
}
 
# Fill lines with algebraic notations.
do m = 1, 8 {
columns(m) = 1
}
m = 1
do k = 1, numpos {
lines(m)(columns(m) : columns(m) + 1) = alg(k)(1:2)
columns(m) = columns(m) + 2
if (k != numpos) {
lines(m)(columns(m) : columns(m) + 3) = " -> "
columns(m) = columns(m) + 4
} else if (numpos == 64 && _
((abs (ipos(numpos) - ipos(1)) == 2 _
&& abs (jpos(numpos) - jpos(1)) == 1) _
|| ((abs (ipos(numpos) - ipos(1)) == 1 _
&& abs (jpos(numpos) - jpos(1)) == 2)))) {
lines(m)(columns(m) : columns(m) + 8) = " -> cycle"
columns(m) = columns(m) + 9
}
if (mod (k, 8) == 0) m = m + 1
}
 
# Print the lines that have stuff in them.
do m = 1, 8 {
if (columns(m) != 1) {
write (*, 10000) lines(m)(1 : columns(m) - 1)
}
}
 
end
 
#-----------------------------------------------------------------------
 
function isclos (board)
implicit none
 
# Is a board a closed tour?
 
logical isclos
integer board(1:8,1:8)
integer ipos(1:64) # The i-positions in order.
integer jpos(1:64) # The j-positions in order.
integer numpos # The number of positions so far.
 
call bd2pos (board, ipos, jpos, numpos)
 
isclos = (numpos == 64 && _
((abs (ipos(numpos) - ipos(1)) == 2 _
&& abs (jpos(numpos) - jpos(1)) == 1) _
|| ((abs (ipos(numpos) - ipos(1)) == 1 _
&& abs (jpos(numpos) - jpos(1)) == 2))))
 
end
 
#-----------------------------------------------------------------------
 
subroutine bd2pos (board, ipos, jpos, numpos)
implicit none
 
# Convert from a board to a list of board positions.
 
integer board(1:8,1:8)
integer ipos(1:64) # The i-positions in order.
integer jpos(1:64) # The j-positions in order.
integer numpos # The number of positions so far.
 
integer i, j
 
numpos = 0
do i = 1, 8 {
do j = 1, 8 {
if (board(i, j) != -1) {
numpos = max (board(i, j), numpos)
ipos(board(i, j)) = i
jpos(board(i, j)) = j
}
}
}
 
end
 
#-----------------------------------------------------------------------
 
subroutine nxtmov (board, n, imove, jmove, nmove)
implicit none
 
# Find possible next moves. Prune and sort the moves according to
# Warnsdorff's heuristic, keeping only those that have the minimum
# number of legal following moves.
 
integer board(1:8,1:8)
integer n
integer imove(1:8,1:64)
integer jmove(1:8,1:64)
integer nmove(1:64)
 
integer w1, w2, w3, w4, w5, w6, w7, w8
integer w
integer n1
integer pickw
 
call possib (board, n, imove, jmove, nmove)
 
n1 = n + 1
nmove(n1) = 1
call countf (board, n1, imove, jmove, nmove, w1)
nmove(n1) = 2
call countf (board, n1, imove, jmove, nmove, w2)
nmove(n1) = 3
call countf (board, n1, imove, jmove, nmove, w3)
nmove(n1) = 4
call countf (board, n1, imove, jmove, nmove, w4)
nmove(n1) = 5
call countf (board, n1, imove, jmove, nmove, w5)
nmove(n1) = 6
call countf (board, n1, imove, jmove, nmove, w6)
nmove(n1) = 7
call countf (board, n1, imove, jmove, nmove, w7)
nmove(n1) = 8
call countf (board, n1, imove, jmove, nmove, w8)
 
w = pickw (w1, w2, w3, w4, w5, w6, w7, w8)
 
if (w == 0) {
call disabl (imove(1, n1), jmove(1, n1))
call disabl (imove(2, n1), jmove(2, n1))
call disabl (imove(3, n1), jmove(3, n1))
call disabl (imove(4, n1), jmove(4, n1))
call disabl (imove(5, n1), jmove(5, n1))
call disabl (imove(6, n1), jmove(6, n1))
call disabl (imove(7, n1), jmove(7, n1))
call disabl (imove(8, n1), jmove(8, n1))
} else {
if (w != w1) call disabl (imove(1, n1), jmove(1, n1))
if (w != w2) call disabl (imove(2, n1), jmove(2, n1))
if (w != w3) call disabl (imove(3, n1), jmove(3, n1))
if (w != w4) call disabl (imove(4, n1), jmove(4, n1))
if (w != w5) call disabl (imove(5, n1), jmove(5, n1))
if (w != w6) call disabl (imove(6, n1), jmove(6, n1))
if (w != w7) call disabl (imove(7, n1), jmove(7, n1))
if (w != w8) call disabl (imove(8, n1), jmove(8, n1))
}
 
end
 
#-----------------------------------------------------------------------
 
subroutine countf (board, n, imove, jmove, nmove, w)
implicit none
 
# Count the number of moves possible after an nth move.
 
integer board(1:8,1:8)
integer n
integer imove(1:8,1:64)
integer jmove(1:8,1:64)
integer nmove(1:64)
integer w
 
logical goodmv
integer n1
 
if (goodmv (imove, nmove, n)) {
call mkmove (board, imove, jmove, nmove, n)
call possib (board, n, imove, jmove, nmove)
n1 = n + 1
w = 0
if (imove(1, n1) != -1) w = w + 1
if (imove(2, n1) != -1) w = w + 1
if (imove(3, n1) != -1) w = w + 1
if (imove(4, n1) != -1) w = w + 1
if (imove(5, n1) != -1) w = w + 1
if (imove(6, n1) != -1) w = w + 1
if (imove(7, n1) != -1) w = w + 1
if (imove(8, n1) != -1) w = w + 1
call unmove (board, imove, jmove, nmove, n)
} else {
# The nth move itself is impossible.
w = 0
}
 
end
 
#-----------------------------------------------------------------------
 
function pickw (w1, w2, w3, w4, w5, w6, w7, w8)
implicit none
 
# From w1..w8, pick out the least nonzero value (or zero if they all
# equal zero).
 
integer pickw
integer w1, w2, w3, w4, w5, w6, w7, w8
 
integer w
integer pickw1
 
w = 0
w = pickw1 (w, w1)
w = pickw1 (w, w2)
w = pickw1 (w, w3)
w = pickw1 (w, w4)
w = pickw1 (w, w5)
w = pickw1 (w, w6)
w = pickw1 (w, w7)
w = pickw1 (w, w8)
 
pickw = w
 
end
 
#-----------------------------------------------------------------------
 
function pickw1 (u, v)
implicit none
 
# A small function used by pickw.
 
integer pickw1
integer u, v
 
if (v == 0) {
pickw1 = u
} else if (u == 0) {
pickw1 = v
} else {
pickw1 = min (u, v)
}
 
end
 
#-----------------------------------------------------------------------
 
subroutine possib (board, n, imove, jmove, nmove)
implicit none
 
# Find moves that are possible from an nth-move position.
 
integer board(1:8,1:8)
integer n
integer imove(1:8,1:64)
integer jmove(1:8,1:64)
integer nmove(1:64)
 
integer i, j
integer n1
 
i = imove(nmove(n), n)
j = jmove(nmove(n), n)
n1 = n + 1
call trymov (board, i + 1, j + 2, imove(1, n1), jmove(1, n1))
call trymov (board, i + 2, j + 1, imove(2, n1), jmove(2, n1))
call trymov (board, i + 1, j - 2, imove(3, n1), jmove(3, n1))
call trymov (board, i + 2, j - 1, imove(4, n1), jmove(4, n1))
call trymov (board, i - 1, j + 2, imove(5, n1), jmove(5, n1))
call trymov (board, i - 2, j + 1, imove(6, n1), jmove(6, n1))
call trymov (board, i - 1, j - 2, imove(7, n1), jmove(7, n1))
call trymov (board, i - 2, j - 1, imove(8, n1), jmove(8, n1))
 
end
 
#-----------------------------------------------------------------------
 
subroutine trymov (board, i, j, imove, jmove)
implicit none
 
# Try a move to square (i, j).
 
integer board(1:8,1:8)
integer i, j
integer imove, jmove
 
call disabl (imove, jmove)
if (1 <= i && i <= 8 && 1 <= j && j <= 8) {
if (board(i,j) == -1) {
call enable (i, j, imove, jmove)
}
}
 
end
 
#-----------------------------------------------------------------------
 
subroutine enable (i, j, imove, jmove)
implicit none
 
# Enable a potential move.
 
integer i, j
integer imove, jmove
 
imove = i
jmove = j
 
end
 
#-----------------------------------------------------------------------
 
subroutine disabl (imove, jmove)
implicit none
 
# Disable a potential move.
 
integer imove, jmove
 
imove = -1
jmove = -1
 
end
 
#-----------------------------------------------------------------------
 
subroutine alg2ij (alg, i, j)
implicit none
 
# Convert, for instance, 'c5' to i=3,j=5.
 
character*2 alg
integer i, j
 
if (alg(1:1) == 'a') j = 1
if (alg(1:1) == 'b') j = 2
if (alg(1:1) == 'c') j = 3
if (alg(1:1) == 'd') j = 4
if (alg(1:1) == 'e') j = 5
if (alg(1:1) == 'f') j = 6
if (alg(1:1) == 'g') j = 7
if (alg(1:1) == 'h') j = 8
 
if (alg(2:2) == '1') i = 1
if (alg(2:2) == '2') i = 2
if (alg(2:2) == '3') i = 3
if (alg(2:2) == '4') i = 4
if (alg(2:2) == '5') i = 5
if (alg(2:2) == '6') i = 6
if (alg(2:2) == '7') i = 7
if (alg(2:2) == '8') i = 8
 
end
 
#-----------------------------------------------------------------------
 
subroutine ij2alg (i, j, alg)
implicit none
 
# Convert, for instance, i=3,j=5 to 'c5'.
 
integer i, j
character*2 alg
 
character alg1
character alg2
 
if (j == 1) alg1 = 'a'
if (j == 2) alg1 = 'b'
if (j == 3) alg1 = 'c'
if (j == 4) alg1 = 'd'
if (j == 5) alg1 = 'e'
if (j == 6) alg1 = 'f'
if (j == 7) alg1 = 'g'
if (j == 8) alg1 = 'h'
 
if (i == 1) alg2 = '1'
if (i == 2) alg2 = '2'
if (i == 3) alg2 = '3'
if (i == 4) alg2 = '4'
if (i == 5) alg2 = '5'
if (i == 6) alg2 = '6'
if (i == 7) alg2 = '7'
if (i == 8) alg2 = '8'
 
alg(1:1) = alg1
alg(2:2) = alg2
 
end
 
#-----------------------------------------------------------------------</syntaxhighlight>
 
{{out}}
$ echo "c5 2 T" | ./knights_tour
<pre> Tour number 1
c5 -> a6 -> b8 -> d7 -> f8 -> h7 -> g5 -> h3 ->
g1 -> e2 -> c1 -> a2 -> b4 -> d3 -> e1 -> g2 ->
h4 -> g6 -> h8 -> f7 -> d8 -> b7 -> a5 -> b3 ->
a1 -> c2 -> a3 -> b1 -> d2 -> f3 -> h2 -> f1 ->
g3 -> h1 -> f2 -> e4 -> c3 -> a4 -> b2 -> d1 ->
e3 -> g4 -> h6 -> g8 -> f6 -> h5 -> f4 -> d5 ->
e7 -> c8 -> a7 -> c6 -> e5 -> c4 -> b6 -> a8 ->
c7 -> e8 -> d6 -> b5 -> d4 -> f5 -> g7 -> e6 -> cycle
+----+----+----+----+----+----+----+----+
8 | 56 | 3 | 50 | 21 | 58 | 5 | 44 | 19 |
+----+----+----+----+----+----+----+----+
7 | 51 | 22 | 57 | 4 | 49 | 20 | 63 | 6 |
+----+----+----+----+----+----+----+----+
6 | 2 | 55 | 52 | 59 | 64 | 45 | 18 | 43 |
+----+----+----+----+----+----+----+----+
5 | 23 | 60 | 1 | 48 | 53 | 62 | 7 | 46 |
+----+----+----+----+----+----+----+----+
4 | 38 | 13 | 54 | 61 | 36 | 47 | 42 | 17 |
+----+----+----+----+----+----+----+----+
3 | 27 | 24 | 37 | 14 | 41 | 30 | 33 | 8 |
+----+----+----+----+----+----+----+----+
2 | 12 | 39 | 26 | 29 | 10 | 35 | 16 | 31 |
+----+----+----+----+----+----+----+----+
1 | 25 | 28 | 11 | 40 | 15 | 32 | 9 | 34 |
+----+----+----+----+----+----+----+----+
a b c d e f g h
 
Tour number 2
c5 -> a6 -> b8 -> d7 -> f8 -> h7 -> g5 -> h3 ->
g1 -> e2 -> c1 -> a2 -> b4 -> d3 -> e1 -> g2 ->
h4 -> g6 -> h8 -> f7 -> d8 -> b7 -> a5 -> b3 ->
a1 -> c2 -> a3 -> b1 -> d2 -> f3 -> h2 -> f1 ->
g3 -> h1 -> f2 -> e4 -> c3 -> a4 -> b2 -> d1 ->
e3 -> g4 -> h6 -> g8 -> f6 -> h5 -> f4 -> d5 ->
e7 -> c8 -> a7 -> c6 -> e5 -> c4 -> b6 -> a8 ->
c7 -> b5 -> d6 -> e8 -> g7 -> f5 -> d4 -> e6 -> cycle
+----+----+----+----+----+----+----+----+
8 | 56 | 3 | 50 | 21 | 60 | 5 | 44 | 19 |
+----+----+----+----+----+----+----+----+
7 | 51 | 22 | 57 | 4 | 49 | 20 | 61 | 6 |
+----+----+----+----+----+----+----+----+
6 | 2 | 55 | 52 | 59 | 64 | 45 | 18 | 43 |
+----+----+----+----+----+----+----+----+
5 | 23 | 58 | 1 | 48 | 53 | 62 | 7 | 46 |
+----+----+----+----+----+----+----+----+
4 | 38 | 13 | 54 | 63 | 36 | 47 | 42 | 17 |
+----+----+----+----+----+----+----+----+
3 | 27 | 24 | 37 | 14 | 41 | 30 | 33 | 8 |
+----+----+----+----+----+----+----+----+
2 | 12 | 39 | 26 | 29 | 10 | 35 | 16 | 31 |
+----+----+----+----+----+----+----+----+
1 | 25 | 28 | 11 | 40 | 15 | 32 | 9 | 34 |
+----+----+----+----+----+----+----+----+
a b c d e f g h
</pre>
 
 
 
 
=={{header|REXX}}==
Line 10,424 ⟶ 10,706:
 
This is an &nbsp; ''open tour'' &nbsp; solution. &nbsp; (See this task's &nbsp; ''discussion'' &nbsp; page for an explanation, the section is &nbsp; ''The 7x7 problem''.)
<langsyntaxhighlight lang="rexx">/*REXX program solves the knight's tour problem for a (general) NxN chessboard.*/
parse arg N sRank sFile . /*obtain optional arguments from the CL*/
if N=='' | N=="," then N=8 /*No boardsize specified? Use default.*/
Line 10,461 ⟶ 10,743:
end /*try different move. */
end /*t*/ /* [↑] all moves tried.*/
return 0 /*tour is not possible. */</langsyntaxhighlight>
'''output''' &nbsp; when using the default input:
<pre>
Line 10,487 ⟶ 10,769:
=={{header|Ruby}}==
Knights tour using [[wp:Knight's_tour#Warnsdorff.27s_rule|Warnsdorffs rule]]
<langsyntaxhighlight lang="ruby">class Board
Cell = Struct.new(:value, :adj) do
def self.end=(end_val)
Line 10,558 ⟶ 10,840:
knight_tour(5,5,0,1)
 
knight_tour(12,12,1,1)</langsyntaxhighlight>
Which produces:
<pre>
Line 10,604 ⟶ 10,886:
 
=={{header|Rust}}==
<langsyntaxhighlight lang="rust">use std::fmt;
 
const SIZE: usize = 8;
Line 10,714 ⟶ 10,996:
None => println!("Fail!"),
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 10,730 ⟶ 11,012:
 
=={{header|Scala}}==
<syntaxhighlight lang="scala">
<lang Scala>
val b=Seq.tabulate(8,8,8,8)((x,y,z,t)=>(1L<<(x*8+y),1L<<(z*8+t),f"${97+z}%c${49+t}%c",(x-z)*(x-z)+(y-t)*(y-t)==5)).flatten.flatten.flatten.filter(_._4).groupBy(_._1)
def f(p:Long,s:Long,v:Any){if(-1L!=s)b(p).foreach(x=>if((s&x._2)==0)f(x._2,s|x._2,v+x._3))else println(v)}
f(1,1,"a1")
</syntaxhighlight>
</lang>
<pre>
a1b3a5b7c5a4b2c4a3b1c3a2b4a6b8c6a7b5c7a8b6c8d6e4d2f1e3c2d4e2c1d3e1g2f4d5e7g8h6f5h4g6h8f7d8e6f8d7e5g4h2f3g1h3g5h7f6e8g7h5g3h1f2d1
Line 10,740 ⟶ 11,022:
 
=={{header|Scheme}}==
<langsyntaxhighlight lang="scheme">
;;/usr/bin/petite
;;encoding:utf-8
Line 10,787 ⟶ 11,069:
(display (map (lambda(x) (decode x)) result)))
(go (renew position))))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 10,796 ⟶ 11,078:
=={{header|SequenceL}}==
Knights tour using [[wp:Knight's_tour#Warnsdorff.27s_rule|Warnsdorffs rule]] (No Backtracking)
<syntaxhighlight lang="sequencel">
<lang sequenceL>
import <Utilities/Sequence.sl>;
import <Utilities/Conversion.sl>;
Line 10,847 ⟶ 11,129:
value when x = i and y = j else
board[i,j] foreach i within 1 ... size(board), j within 1 ... size(board[1]);
</syntaxhighlight>
</lang>
{{out}}
8 X 8 board:
Line 10,886 ⟶ 11,168:
=={{header|Sidef}}==
{{trans|Raku}}
<langsyntaxhighlight lang="ruby">var board = []
var I = 8
var J = 8
Line 10,946 ⟶ 11,228:
}
print "\n"
}</langsyntaxhighlight>
 
=={{header|Swift}}==
Line 10,952 ⟶ 11,234:
{{trans|Rust}}
 
<langsyntaxhighlight lang="swift">public struct CPoint {
public var x: Int
public var y: Int
Line 11,081 ⟶ 11,363:
}
 
b.printBoard()</langsyntaxhighlight>
 
{{out}}
Line 11,096 ⟶ 11,378:
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.6; # For object support, which makes coding simpler
 
oo::class create KnightsTour {
Line 11,202 ⟶ 11,484:
expr {$a in [my ValidMoves $b]}
}
}</langsyntaxhighlight>
Demonstrating:
<langsyntaxhighlight lang="tcl">set kt [KnightsTour new]
$kt constructRandom
$kt print
Line 11,211 ⟶ 11,493:
} else {
puts "This is an open tour"
}</langsyntaxhighlight>
Sample output:
<pre>
Line 11,223 ⟶ 11,505:
</pre>
The above code supports other sizes of boards and starting from nominated locations:
<langsyntaxhighlight lang="tcl">set kt [KnightsTour new 7 7]
$kt constructFrom {0 0}
$kt print
Line 11,230 ⟶ 11,512:
} else {
puts "This is an open tour"
}</langsyntaxhighlight>
Which could produce this output:
<pre>
Line 11,243 ⟶ 11,525:
=={{header|Wren}}==
{{trans|Kotlin}}
<langsyntaxhighlight ecmascriptlang="wren">class Square {
construct new(x, y) {
_x = x
Line 11,300 ⟶ 11,582:
System.write((col == 7) ? "\n" : " ")
col = (col + 1) % 8
}</langsyntaxhighlight>
 
{{out}}
Line 11,315 ⟶ 11,597:
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">int Board(8+2+2, 8+2+2); \board array with borders
int LegalX, LegalY; \arrays of legal moves
def IntSize=4; \number of bytes in an integer (4 or 2)
Line 11,365 ⟶ 11,647:
]
else Text(0, "No Solution.^M^J");
]</langsyntaxhighlight>
 
Example output:
Line 11,384 ⟶ 11,666:
 
First we build a generic package for solving any kind of tour over the chess board. Here it is…
<syntaxhighlight lang="text">
<xsl:package xsl:version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
Line 11,441 ⟶ 11,723:
</xsl:package>
</syntaxhighlight>
</lang>
 
And now for the style-sheet to solve the Knight’s tour…
 
<syntaxhighlight lang="text">
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
Line 11,484 ⟶ 11,766:
</xsl:stylesheet>
</syntaxhighlight>
</lang>
 
So an input like this…
 
<syntaxhighlight lang="text">
<tt>
<knight>
Line 11,494 ⟶ 11,776:
</knight>
</tt>
</syntaxhighlight>
</lang>
 
…should be transformed in something like this…
 
<syntaxhighlight lang="text">
<tt>
<knight>
Line 11,507 ⟶ 11,789:
</knight>
</tt>
</syntaxhighlight>
</lang>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl"> // Use Warnsdorff's rule to perform a knights tour of a 8x8 board in
// linear time.
// See Pohl, Ira (July 1967),
Line 11,557 ⟶ 11,839:
fcn(ns){ vm.arglist.apply("%2s".fmt).concat(",")+"\n" });
}
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="zkl">b:=Board(); b.knightsTour(3,3);
b.println();</langsyntaxhighlight>
{{out}}
<pre>
Line 11,573 ⟶ 11,855:
</pre>
Check that a solution for all squares is found:
<langsyntaxhighlight lang="zkl">[[(x,y); [0..7]; [0..7];
{ b:=Board(); n:=b.knightsTour(x,y); if(n!=64) b.println(">>>",x,",",y) } ]];</langsyntaxhighlight>
{{out}}Nada
 
9,476

edits