View difference between Paste ID: mUkrTTWR and m3q2zJaQ
SHOW: | | - or go back to the newest paste.
1
# knightstour.py
2
#
3
# created by: M. Peele
4
# section: 01
5
# 
6
# This program implements a brute-force solution for the Knight's tour problem 
7
# using a recursive backtracking algorithm. The Knight's tour is a chessboard 
8
# puzzle in which the objective is to find a sequence of moves by the knight in 
9
# which it visits every square on the board exactly one. It uses a 6x6 array for 
10
# the chessboard where each square is identified by a row and column index, the 
11
# range of which both start at 0. Let the upper-left square of the board be the 
12
# row 0 and column 0 square.
13
#
14
# Imports the necessary modules.
15
16
# Initializes the chessboard as a 6x6 array. 
17
chessBoard = [[None for i in range(6)] for j in range(6)]
18
19
# Gets the input start position for the knight from the user.
20
row = int(input("Enter the row: "))
21
col = int(input("Enter the column: "))
22
23
# Main driver function which starts the recursion.
24
def main():
25
    knightsTour(row, col, 1)
26
27
# Recursive function that solves the Knight's Tour problem.    
28
def knightsTour(row, col, move):
29
    # Checks if the given index is in range of the array and is legal.
30
    if _inRange(row, col) and _isLegal(row, col): 
31
        chessBoard[row][col] = move # Sets a knight-marker at the given index.
32
        # If the chessBoard is full, returns True and the solved board.
33
        if _isFull(chessBoard):
34
            return True, _draw(chessBoard)    
35
36
        # Checks to see if the knight can make another move. If so, makes that 
37
        # move by calling the function again. 
38
        possibleOffsets = ((-2, -1), (-2, 1), (-1, 2), (1, 2), \
39
                           (2, 1), (2, -1), (1, -2), (-1, -2))
40
        for offset in possibleOffsets:
41
            if knightsTour(row + offset[0], col + offset[1], move + 1):
42
                return True 
43
        # If the loop terminates, no possible move can be made. Removes the 
44
        # knight-marker at the given index. 
45
        chessBoard[row][col] = None
46
        return False 
47
    else:
48
        return False
49
50
# Determines if the given row, col index is a legal move.
51
def _isLegal(row, col):
52
    if _inRange(row, col) and chessBoard[row][col] == None:
53
        return True
54
    else:
55
        return False
56
57
# Determines if the given row, col index is in range.
58
def _inRange(row, col):
59
    try:
60
        chessBoard[row][col]
61
        return True
62
    except IndexError:
63
        return False
64
65
# A solution was found if the array is full, meaning that every element in the 
66
# array is filled with a number saying the knight has visited there.
67
def _isFull(chessBoard):
68
    for row in chessBoard:
69
        for col in row:
70
            if col is None:
71
                return False
72
    return True
73
74
# Draws a pictoral representation of the array.
75
def _draw(chessBoard):
76
    for row in chessBoard:
77
        for col in row:
78
            print("%4s" % col, end = " ")
79
        print()
80
81
# Calls the main function.
82
main()