import java.util.*; import javax.swing.*; import java.awt.*; /* A program to find all the knight's tours on a chessboard * A knight's tour is achieved when a knight visits each square * exactly once using legal knight moves * Rhys Price Jones * St Padraig 2009 */ public class KnightsTourApplet extends JApplet implements Runnable { private static final int n = 8; // size of the chessboard private static final int NUMKMOVES = 8; // number of ways a knight can move // possible knight moves are: // 2 across and 1 up, 1 across and 2 up, ... etc, as in: private int[] across = {2, 1, -1, -2, -2, -1, 1, 2}; private int[] up = {1, 2, 2, 1, -1, -2, -2, -1}; private int nsq = n*n; private int[][] board; private JButton[][] myButtons; private Panel myPanel; public void init() { setSize(400,400); setVisible(true); board = new int[n][n]; myPanel = new Panel(); myPanel.setLayout(new GridLayout(n,n)); myButtons = new JButton[n][n]; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { board[i][j] = 0; myButtons[i][j] = new JButton(" "); myPanel.add(myButtons[i][j]); } add(myPanel, BorderLayout.CENTER); validate(); board[0][0] = 1; new Thread(this).start(); } public void printSolution() { // for the web version, let's just beep and pause Toolkit.getDefaultToolkit().beep(); try { Thread.sleep(10000); } catch (InterruptedException ie) {} Toolkit.getDefaultToolkit().beep(); } public void run() { board[0][0] = 1; myButtons[0][0].setText("1"); findall(2, 0, 0); // find all knight's tours that start at (0,0) } public void findall(int i, int x, int y) { // This is the workhorse // Proceeding from square (x,y) try to make the i'th move to (u,v) // If successful then make a recursive call to make the (i+1)th move // When you return from that, undo (u,v) // Effectively uses a stack because recursive calls use a stack // This is exhaustive search and should ultimately get all solutions // that start from the existing path int u, v; for (int k = 0; k < NUMKMOVES; k++) { // try each knight move u = x + across[k]; v = y + up[k]; if ((0 <= u) && (u < n) && (0 <= v) && (v < n)) // still on board? if (board[u][v] == 0) { // getting to an unvisited square? board[u][v] = i; // mark it myButtons[u][v].setText(""+i); if (i < nsq) findall(i+1, u, v); // and proceed else printSolution(); // unless solved, so print it // backtrack board[u][v] = 0; myButtons[u][v].setText(""); } } } }