tab = 2 def print_solution_on_board(n, solution, move, indent=0): if len(solution) != n: return # print(" "*indent, "Solution: ", solution, ", move: ", move, sep = "", end = "\n\n") indent += tab for i in range(n): if i == 0: # printing the top of the board print(" "*indent, " ", "_"*((4*n)-1), sep="") print(" "*indent, "|", sep="", end="") if solution[n-(i+1)] != -1: # queen placed in this row in the solution for j in range(n): print("_X_|" if solution[n-(i+1)] == j else "___|", end="") elif n-(i+1) == move[0]: # move is made in this row for j in range(n): print("_?_|" if move[1] == j else "___|", end="") else: # no queen in solution in this row, move not in this row print("___|"*n, end="") # so print an empty row print("") # this method determines if a queen can be placed at proposed_row, proposed_col # with current solution i.e. this move is valid only if no queen in current # solution may attack the square at proposed_row and proposed_col def is_valid_move(proposed_row, proposed_col, solution): temptab = tab temptab += 1 print("\n", temptab*" ", "Proposed row: ", proposed_row, sep="") print(temptab*" ", "Proposed column: ", proposed_col, sep="") # we need to check if any queen on the board in this solution can attack the proposed cell print_solution_on_board(len(solution), solution, [ proposed_row, proposed_col], temptab+2) for i in range(0, proposed_row): old_row = i old_col = solution[i] diagonal_offset = proposed_row - old_row print() print(temptab*" ", f"{i + 1}. Old row: ", i, sep="") print((temptab + 1)*" ", " Old column: ", solution[i], sep="") print((temptab + 1)*" ", " Diagonal offset to check: ", diagonal_offset, sep="") if (old_col == proposed_col or old_col == proposed_col - diagonal_offset or old_col == proposed_col + diagonal_offset): print((temptab + 1)*" ", f" Invalid move: the proposed cell is vulnerable to attack from the queen at [{i}, {solution[i]}].", sep="") return False else: print((temptab + 1)*" ", f" The proposed cell is safe from the queen at [{i}, {solution[i]}].", sep="") print((temptab + 1)*" ", "Valid move: the proposed cell is safe.", sep="") return True # Function to solve N-Queens problem def solve_n_queens(n): print("\n Initialising variables") results = [] solution = [0, 2, -1, -1] print(" Results: ", results, sep="") print(" An intermediate solution: ", solution, sep="") # Let's check the is_valid_move function with an intermediate solution # and some proposed moves moves = [[2, 0], [2, 1], [2, 2], [2, 3]] for m in moves: is_valid_move(m[0], m[1], solution) return len(results) def main(): n = [4] for i in range(len(n)): print(i+1, ". Queens: ", n[i], ", Chessboard: (", n[i], "x", n[i], ")", sep="") res = solve_n_queens(n[i]) print("-"*100, "\n", sep="") if __name__ == '__main__': main()