Reputation: 103
I'm trying to write a Python program which will solve the Knight's Tour problem using backtracking. For those unfamiliar: "The knight is placed on the first square of an empty chess board and, moving according to the rules of chess, must visit each square exactly once."
My code works mostly but not completely. It usually gets the 7th move and then returns an unfinished board. Why?
board = [
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]]
def move(x, y, count, move_x, move_y):
if count == len(board)**2:
return True
for i in range(8):
if is_valid(x + int(move_x[i]), y + int(move_y[i]), board):
if move(x + move_x[i], y + move_y[i], count + 1, move_x, move_y):
board[x][y] = count
return True
return False
def print_board(bo):
for i in range(len(bo)):
for j in range(len(bo[0])):
if j == (len(board[0]) - 1):
print(bo[i][j])
else:
print(bo[i][j], end = " ")
def is_valid(x, y, board):
if x >= 0 and y >= 0 and x < len(board) and y < len(board) and board[x][y] == 0:
return True
return False
def solve(bo):
print_board(board)
move_x = [1, 2, 2, 1, -1, -2, -2, -1]
move_y = [2, 1, -1, -2, -2, -1, 1, 2]
counter = 1
x_loc = 0
y_loc = 0
if not(move(x_loc, y_loc, counter, move_x, move_y)):
print("No solution")
else:
print(" ")
print_board(board)
solve(board)
Upvotes: 2
Views: 816
Reputation: 11
def process(i,j,cnt,board,n,query):
board[i][j]=cnt
cnt+=1
if cnt==n*n+1:
for a in range(n):
print(board[a])
print()
if query==0:
return True
else:
True
stack=[]
if i+2<n and j-1>-1 and board[i+2][j-1]==-1:
stack.append([i+2,j-1])
if i+1<n and j-2>-1 and board[i+1][j-2]==-1:
stack.append([i+1,j-2])
if i-1>-1 and j-2>-1 and board[i-1][j-2]==-1:
stack.append([i-1,j-2])
if i-2>-1 and j-1>-1 and board[i-2][j-1]==-1:
stack.append([i-2,j-1])
if i-2>-1 and j+1<n and board[i-2][j+1]==-1:
stack.append([i-2,j+1])
if i-1>-1 and j+2<n and board[i-1][j+2]==-1:
stack.append([i-1,j+2])
if i+1<n and j+2<n and board[i+1][j+2]==-1:
stack.append([i+1,j+2])
if i+2<n and j+1<n and board[i+2][j+1]==-1:
stack.append([i+2,j+1])
while (len(stack))>0:
curr=stack.pop()
if query==0:
if(process(curr[0],curr[1],cnt,board,n,query)):
return True
else :
board[curr[0]][curr[1]]=-1
else:
process(curr[0],curr[1],cnt,board,n,query)
board[curr[0]][curr[1]]=-1
return
######## Driver Code ########
query=input("If you want program to output all possible ways of KNIGHT'S TOUR, say Yes or else say No :- ")
if query[0]=='y' or query[0]=='Y':
query=input("This process may be too slow for N greater than 5, it will work fast if N is less than 6. Are u sure u want to go for it? (Yes/No) :- ")
if query[0]=='y' or query[0]=='Y':
query=1
else :
query=0
n=int(input("Enter the value of N :- "))
if(n<5):
print("Not possible for N less than 5")
else:
board= [[-1]*n for i in range(n)]
cnt=1
process(0,0,cnt,board,n,query)
######## Some precomputed outputs ########
# N = 5
#
# [1, 12, 3, 18, 21]
# [4, 17, 20, 13, 8]
# [11, 2, 7, 22, 19]
# [16, 5, 24, 9, 14]
# [25, 10, 15, 6, 23]
# N = 6
#
# [1, 20, 3, 18, 5, 22]
# [36, 11, 28, 21, 30, 17]
# [27, 2, 19, 4, 23, 6]
# [12, 35, 10, 29, 16, 31]
# [9, 26, 33, 14, 7, 24]
# [34, 13, 8, 25, 32, 15]
# N = 7
#
# [1, 14, 3, 38, 5, 34, 7]
# [12, 39, 10, 33, 8, 37, 26]
# [15, 2, 13, 4, 25, 6, 35]
# [40, 11, 32, 9, 36, 27, 44]
# [19, 16, 21, 24, 45, 48, 29]
# [22, 41, 18, 31, 28, 43, 46]
# [17, 20, 23, 42, 47, 30, 49]
# N = 8
#
# [1, 60, 39, 34, 31, 18, 9, 64]
# [38, 35, 32, 61, 10, 63, 30, 17]
# [59, 2, 37, 40, 33, 28, 19, 8]
# [36, 49, 42, 27, 62, 11, 16, 29]
# [43, 58, 3, 50, 41, 24, 7, 20]
# [48, 51, 46, 55, 26, 21, 12, 15]
# [57, 44, 53, 4, 23, 14, 25, 6]
# [52, 47, 56, 45, 54, 5, 22, 13]
Upvotes: 1
Reputation: 11209
move()
should come after setting board[x][y] = count
.
move()
returns false, then you should have board[x][y] = 0
count
does not need to be stored in each board cell. It just needs to be passed and incremented in each recursive call. You can use a boolean indicating whether a cell has been visited or not.Upvotes: 4