44import java .util .Comparator ;
55import java .util .List ;
66
7- /*
8- * Problem Statement: -
9-
10- Given a N*N board with the Knight placed on the first block of an empty board. Moving according
11- to the rules of chess knight must visit each square exactly once. Print the order of each cell in
12- which they are visited.
13-
14- Example: -
15-
16- Input : N = 8
17-
18- Output:
19- 0 59 38 33 30 17 8 63
20- 37 34 31 60 9 62 29 16
21- 58 1 36 39 32 27 18 7
22- 35 48 41 26 61 10 15 28
23- 42 57 2 49 40 23 6 19
24- 47 50 45 54 25 20 11 14
25- 56 43 52 3 22 13 24 5
26- 51 46 55 44 53 4 21 12
27-
7+ /**
8+ * The KnightsTour class solves the Knight's Tour problem using backtracking.
9+ *
10+ * Problem Statement:
11+ * Given an N*N board with a knight placed on the first block, the knight must
12+ * move according to chess rules and visit each square on the board exactly once.
13+ * The class outputs the sequence of moves for the knight.
14+ *
15+ * Example:
16+ * Input: N = 8 (8x8 chess board)
17+ * Output: The sequence of numbers representing the order in which the knight visits each square.
2818 */
2919public final class KnightsTour {
3020 private KnightsTour () {
3121 }
3222
23+ // The size of the chess board (12x12 grid, with 2 extra rows/columns as a buffer around a 8x8 area)
3324 private static final int BASE = 12 ;
25+
26+ // Possible moves for a knight in chess
3427 private static final int [][] MOVES = {
3528 {1 , -2 },
3629 {2 , -1 },
@@ -40,36 +33,40 @@ private KnightsTour() {
4033 {-2 , 1 },
4134 {-2 , -1 },
4235 {-1 , -2 },
43- }; // Possible moves by knight on chess
44- private static int [][] grid ; // chess grid
45- private static int total ; // total squares in chess
36+ };
37+
38+ // Chess grid representing the board
39+ static int [][] grid ;
40+
41+ // Total number of cells the knight needs to visit
42+ static int total ;
4643
47- public static void main (String [] args ) {
44+ /**
45+ * Resets the chess board to its initial state.
46+ * Initializes the grid with boundary cells marked as -1 and internal cells as 0.
47+ * Sets the total number of cells the knight needs to visit.
48+ */
49+ public static void resetBoard () {
4850 grid = new int [BASE ][BASE ];
4951 total = (BASE - 4 ) * (BASE - 4 );
50-
5152 for (int r = 0 ; r < BASE ; r ++) {
5253 for (int c = 0 ; c < BASE ; c ++) {
5354 if (r < 2 || r > BASE - 3 || c < 2 || c > BASE - 3 ) {
54- grid [r ][c ] = -1 ;
55+ grid [r ][c ] = -1 ; // Mark boundary cells
5556 }
5657 }
5758 }
58-
59- int row = 2 + (int ) (Math .random () * (BASE - 4 ));
60- int col = 2 + (int ) (Math .random () * (BASE - 4 ));
61-
62- grid [row ][col ] = 1 ;
63-
64- if (solve (row , col , 2 )) {
65- printResult ();
66- } else {
67- System .out .println ("no result" );
68- }
6959 }
7060
71- // Return True when solvable
72- private static boolean solve (int row , int column , int count ) {
61+ /**
62+ * Recursive method to solve the Knight's Tour problem.
63+ *
64+ * @param row The current row of the knight
65+ * @param column The current column of the knight
66+ * @param count The current move number
67+ * @return True if a solution is found, False otherwise
68+ */
69+ static boolean solve (int row , int column , int count ) {
7370 if (count > total ) {
7471 return true ;
7572 }
@@ -80,49 +77,72 @@ private static boolean solve(int row, int column, int count) {
8077 return false ;
8178 }
8279
80+ // Sort neighbors by Warnsdorff's rule (fewest onward moves)
8381 neighbor .sort (Comparator .comparingInt (a -> a [2 ]));
8482
8583 for (int [] nb : neighbor ) {
86- row = nb [0 ];
87- column = nb [1 ];
88- grid [row ][ column ] = count ;
89- if (!orphanDetected (count , row , column ) && solve (row , column , count + 1 )) {
84+ int nextRow = nb [0 ];
85+ int nextCol = nb [1 ];
86+ grid [nextRow ][ nextCol ] = count ;
87+ if (!orphanDetected (count , nextRow , nextCol ) && solve (nextRow , nextCol , count + 1 )) {
9088 return true ;
9189 }
92- grid [row ][ column ] = 0 ;
90+ grid [nextRow ][ nextCol ] = 0 ; // Backtrack
9391 }
9492
9593 return false ;
9694 }
9795
98- // Returns List of neighbours
99- private static List <int []> neighbors (int row , int column ) {
96+ /**
97+ * Returns a list of valid neighboring cells where the knight can move.
98+ *
99+ * @param row The current row of the knight
100+ * @param column The current column of the knight
101+ * @return A list of arrays representing valid moves, where each array contains:
102+ * {nextRow, nextCol, numberOfPossibleNextMoves}
103+ */
104+ static List <int []> neighbors (int row , int column ) {
100105 List <int []> neighbour = new ArrayList <>();
101106
102107 for (int [] m : MOVES ) {
103108 int x = m [0 ];
104109 int y = m [1 ];
105- if (grid [row + y ][column + x ] == 0 ) {
110+ if (row + y >= 0 && row + y < BASE && column + x >= 0 && column + x < BASE && grid [row + y ][column + x ] == 0 ) {
106111 int num = countNeighbors (row + y , column + x );
107112 neighbour .add (new int [] {row + y , column + x , num });
108113 }
109114 }
110115 return neighbour ;
111116 }
112117
113- // Returns the total count of neighbors
114- private static int countNeighbors (int row , int column ) {
118+ /**
119+ * Counts the number of possible valid moves for a knight from a given position.
120+ *
121+ * @param row The row of the current position
122+ * @param column The column of the current position
123+ * @return The number of valid neighboring moves
124+ */
125+ static int countNeighbors (int row , int column ) {
115126 int num = 0 ;
116127 for (int [] m : MOVES ) {
117- if (grid [row + m [1 ]][column + m [0 ]] == 0 ) {
128+ int x = m [0 ];
129+ int y = m [1 ];
130+ if (row + y >= 0 && row + y < BASE && column + x >= 0 && column + x < BASE && grid [row + y ][column + x ] == 0 ) {
118131 num ++;
119132 }
120133 }
121134 return num ;
122135 }
123136
124- // Returns true if it is orphan
125- private static boolean orphanDetected (int count , int row , int column ) {
137+ /**
138+ * Detects if moving to a given position will create an orphan (a position with no further valid moves).
139+ *
140+ * @param count The current move number
141+ * @param row The row of the current position
142+ * @param column The column of the current position
143+ * @return True if an orphan is detected, False otherwise
144+ */
145+ static boolean orphanDetected (int count , int row , int column ) {
126146 if (count < total - 1 ) {
127147 List <int []> neighbor = neighbors (row , column );
128148 for (int [] nb : neighbor ) {
@@ -133,17 +153,4 @@ private static boolean orphanDetected(int count, int row, int column) {
133153 }
134154 return false ;
135155 }
136-
137- // Prints the result grid
138- private static void printResult () {
139- for (int [] row : grid ) {
140- for (int i : row ) {
141- if (i == -1 ) {
142- continue ;
143- }
144- System .out .printf ("%2d " , i );
145- }
146- System .out .println ();
147- }
148- }
149156}
0 commit comments