Created
November 4, 2014 21:36
-
-
Save kedarmhaswade/8a7b2acf1895045a1861 to your computer and use it in GitHub Desktop.
A rudimentary Knight's Tour using Backtracking algorithm ...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
Compile and run as java KnightsTour a1 | |
*/ | |
import java.util.*; | |
class KnightsTour { | |
public static void main(String[] args) { | |
String start = args[0]; | |
Board.setStart(start); | |
if(solve(start)) | |
Board.draw(); | |
else | |
System.out.println("No solution for: " + args[0]); | |
} | |
static boolean solve(String curr) { | |
Board.placeKnightAt(curr); | |
if (Board.isTourDone(curr)) | |
return true; | |
Set<String> candidates = Board.candidateKnightMoves(curr); | |
for (String candidate : candidates) { | |
if (solve(candidate)) | |
return true; | |
} | |
Board.removeKnightFrom(curr); | |
return false; | |
} | |
static final class Board { | |
static int[][] board = new int[8][8]; // | |
static int counter = 0; | |
static String start; | |
static { | |
for (int i = 0; i < 8; i++) | |
for (int j = 0; j < 8; j++) | |
board[i][j] = 0; | |
} | |
static void draw() { | |
for (int i = 7; i >=0 ; i--) | |
System.out.println(Arrays.toString(board[i])); | |
} | |
static void setStart(String start) { | |
Board.start = start; | |
} | |
static boolean isTourDone(String curr) { | |
if (counter != 64) | |
return false; | |
Set<String> possible = candidateKnightMoves(curr, 1); | |
//System.out.println("possible: " + possible + ", curr: " + curr); | |
return possible.contains(start); | |
} | |
static void read() { | |
try { | |
System.in.read(); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
static void placeKnightAt(String pos) { | |
//'a' <= f <= 'h', '1' <= r <= '8' | |
char f = pos.charAt(0), r = pos.charAt(1); | |
counter += 1; | |
board[r-'1'][f-'a'] = counter; | |
//draw(); | |
//read(); | |
} | |
static void removeKnightFrom(String pos) { | |
//'a' <= f <= 'h', '1' <= r <= '8' | |
char f = pos.charAt(0), r = pos.charAt(1); | |
counter -= 1; | |
board[r-'1'][f-'a'] = 0; | |
//draw(); | |
//read(); | |
} | |
static Set<String> candidateKnightMoves(String curr) { | |
return candidateKnightMoves(curr, 0); | |
} | |
static Set<String> candidateKnightMoves(String curr, int nextScore) { | |
// from a current position like "d4", returns the "available" board positions knight can move to | |
//System.out.println("curr: " + curr); | |
Set<String> candidates = new HashSet<String>(); | |
char file = curr.charAt(0); | |
char rank = curr.charAt(1); | |
char nf, nr; | |
nf = (char)(file + 1); | |
nr = (char)(rank + 2); | |
if (nf <= 'h' && nr <= '8' && board[nr-'1'][nf-'a'] == nextScore) { | |
String c = ""+nf + nr; | |
candidates.add(c); | |
//System.out.println("cand: " + c); | |
} | |
nr = (char)(rank - 2); | |
if (nf <= 'h' && nr >= '1' && board[nr-'1'][nf-'a'] == nextScore) { | |
String c = ""+nf + nr; | |
candidates.add(c); | |
//System.out.println("cand: " + c); | |
} | |
nf = (char)(file - 1); | |
nr = (char)(rank + 2); | |
if (nf >= 'a' && nr <= '8' && board[nr-'1'][nf-'a'] == nextScore) { | |
String c = ""+nf + nr; | |
candidates.add(c); | |
//System.out.println("cand: " + c); | |
} | |
nr = (char)(rank - 2); | |
if (nf >= 'a' && nr >= '1' && board[nr-'1'][nf-'a'] == nextScore) { | |
String c = ""+nf + nr; | |
candidates.add(c); | |
//System.out.println("cand: " + c); | |
} | |
nf = (char)(file + 2); | |
nr = (char)(rank + 1); | |
if (nf <= 'h' && nr <= '8' && board[nr-'1'][nf-'a'] == nextScore) { | |
String c = ""+nf + nr; | |
candidates.add(c); | |
//System.out.println("cand: " + c); | |
} | |
nr = (char)(rank - 1); | |
if (nf <= 'h' && nr >= '1' && board[nr-'1'][nf-'a'] == nextScore) { | |
String c = ""+nf + nr; | |
candidates.add(c); | |
//System.out.println("cand: " + c); | |
} | |
nf = (char)(file - 2); | |
nr = (char)(rank + 1); | |
if (nf >= 'a' && nr <= '8' && board[nr-'1'][nf-'a'] == nextScore) { | |
String c = ""+nf + nr; | |
candidates.add(c); | |
//System.out.println("cand: " + c); | |
} | |
nr = (char)(rank - 1); | |
if (nf >= 'a' && nr >= '1' && board[nr-'1'][nf-'a'] == nextScore) { | |
String c = ""+nf + nr; | |
candidates.add(c); | |
//System.out.println("cand: " + c); | |
} | |
return candidates; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For some reason, Java 7 runs this algorithm reasonably well (in ~35 seconds, a knight's tour is found with a1 as the starting position), whereas Java 8 just hangs!