def set_game_preconditions(): number_of_tiles = int( input("Enter 8, 15 or 24 as for number of the square tiles:")) index_of_zero_in_solved_puzzle = int( input( "Enter index of zero in solved puzzle (-1 is for the last index):") ) print("Now enter the puzzle") number_of_rows = int(sqrt(number_of_tiles + 1)) puzzle = [] zero_position_in_input_puzzle = None row_count = 0 #the puzzle is square shaped so rows = cols for row in range(number_of_rows): r = input("Enter row: ") row_as_list = [int(i) for i in r.split(',')] puzzle.append(row_as_list) if 0 in row_as_list: zero_position_in_input_puzzle = (row_count, row_as_list.index(0)) row_count += 1 return (number_of_rows, index_of_zero_in_solved_puzzle, Puzzle_node(puzzle, zero_position_in_input_puzzle))
def test_with_given_3_x_3_puzzle_and_not_last_position_of_zero_in_solved_puzzle( self): puzzle_board = [[1, 2, 3], [4, 5, 8], [6, 7, 0]] position_of_zero_in_given_puzzle = (2, 2) position_of_zero_in_solved_puzzle = -1 puzzle = Puzzle_node(puzzle_board, position_of_zero_in_given_puzzle) final_state_board = [[1, 2, 3], [0, 4, 5], [6, 7, 8]] position_of_zero_in_final_state = (1, 0) final_state = Puzzle_node(final_state_board, position_of_zero_in_final_state) steps, directions = iterative_deepening_a_star( puzzle, final_state, final_state.tile_number_position_dict) expected_steps = 3 #list of reversed directions expected_directions = ['right', 'right', 'down'] self.assertEqual(steps, expected_steps) self.assertEqual(directions, expected_directions)
def test_with_second_example_from_presentations(self): puzzle_board = [[2, 3, 6], [1, 5, 8], [4, 7, 0]] position_of_zero_in_given_puzzle = (2, 2) position_of_zero_in_solved_puzzle = -1 puzzle = Puzzle_node(puzzle_board, position_of_zero_in_given_puzzle) final_state_board = [[1, 2, 3], [4, 5, 6], [7, 8, 0]] position_of_zero_in_final_state = (2, 2) final_state = Puzzle_node(final_state_board, position_of_zero_in_final_state) steps, directions = iterative_deepening_a_star( puzzle, final_state, final_state.tile_number_position_dict) expected_steps = 8 #list of reversed directions expected_directions = [ 'down', 'down', 'right', 'right', 'up', 'up', 'left', 'left' ] self.assertEqual(steps, expected_steps) self.assertEqual(directions, expected_directions[::-1])
def test_with_given_4_x_4_puzzle_and_not_last_position_of_zero_in_solved_puzzle( self): puzzle_board = [[1, 2, 3, 4], [5, 6, 7, 11], [8, 9, 10, 0], [12, 13, 14, 15]] position_of_zero_in_given_puzzle = (2, 3) position_of_zero_in_solved_puzzle = -1 puzzle = Puzzle_node(puzzle_board, position_of_zero_in_given_puzzle) final_state_board = [[1, 2, 3, 4], [5, 6, 0, 7], [8, 9, 10, 11], [12, 13, 14, 15]] position_of_zero_in_final_state = (1, 2) final_state = Puzzle_node(final_state_board, position_of_zero_in_final_state) steps, directions = iterative_deepening_a_star( puzzle, final_state, final_state.tile_number_position_dict) expected_steps = 2 #list of reversed directions expected_directions = ['right', 'down'] self.assertEqual(steps, expected_steps) self.assertEqual(directions, expected_directions)
def test_with_given_4_x_4_puzzle_and_last_position_of_zero_in_solved_puzzle( self): puzzle_board = [[1, 2, 3, 4], [0, 6, 7, 8], [5, 10, 11, 12], [9, 13, 14, 15]] position_of_zero_in_given_puzzle = (1, 0) position_of_zero_in_solved_puzzle = -1 puzzle = Puzzle_node(puzzle_board, position_of_zero_in_given_puzzle) final_state_board = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 0]] position_of_zero_in_final_state = (3, 3) final_state = Puzzle_node(final_state_board, position_of_zero_in_final_state) steps, directions = iterative_deepening_a_star( puzzle, final_state, final_state.tile_number_position_dict) expected_steps = 5 #list of reversed directions expected_directions = ['left', 'left', 'left', 'up', 'up'] self.assertEqual(steps, expected_steps) self.assertEqual(directions, expected_directions)
def test_with_given_5_x_5_solved_puzzle_and_not_last_position_of_zero_in_solved_puzzle( self): puzzle_board = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 0, 13, 14], [15, 16, 17, 18, 19], [20, 21, 22, 23, 24]] position_of_zero_in_given_puzzle = (2, 2) position_of_zero_in_solved_puzzle = -1 puzzle = Puzzle_node(puzzle_board, position_of_zero_in_given_puzzle) final_state_board = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 0, 13, 14], [15, 16, 17, 18, 19], [20, 21, 22, 23, 24]] position_of_zero_in_final_state = (2, 2) final_state = Puzzle_node(final_state_board, position_of_zero_in_final_state) steps, directions = iterative_deepening_a_star( puzzle, final_state, final_state.tile_number_position_dict) expected_steps = 0 #list of reversed directions expected_directions = [] self.assertEqual(steps, expected_steps) self.assertEqual(directions, expected_directions)
def test_with_given_5_x_5_puzzle_and_last_position_of_zero_in_solved_puzzle( self): puzzle_board = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [0, 17, 18, 19, 20], [16, 21, 22, 23, 24]] position_of_zero_in_given_puzzle = (3, 0) position_of_zero_in_solved_puzzle = -1 puzzle = Puzzle_node(puzzle_board, position_of_zero_in_given_puzzle) final_state_board = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 0]] position_of_zero_in_final_state = (4, 4) final_state = Puzzle_node(final_state_board, position_of_zero_in_final_state) steps, directions = iterative_deepening_a_star( puzzle, final_state, final_state.tile_number_position_dict) expected_steps = 5 #list of reversed directions expected_directions = ['left', 'left', 'left', 'left', 'up'] self.assertEqual(steps, expected_steps) self.assertEqual(directions, expected_directions)
def find_puzzle_children(puzzle, final_state_dict_values): puzzle_children = [] puzzle_zero_x = puzzle.zero_position[0] puzzle_zero_y = puzzle.zero_position[1] content = deepcopy(puzzle.content) #UP #otherwise if zero is first element in list with index - 1 will get the last element if puzzle_zero_x - 1 >= 0: try: content[puzzle_zero_x][puzzle_zero_y], content[ puzzle_zero_x - 1][puzzle_zero_y] = content[ puzzle_zero_x - 1][puzzle_zero_y], content[puzzle_zero_x][puzzle_zero_y] except Exception as e: pass else: puzzle_children.append( Puzzle_node(content, (puzzle_zero_x - 1, puzzle_zero_y), puzzle.distance_from_root + 1, puzzle, movement_direction="down")) finally: content = deepcopy(puzzle.content) #LEFT #otherwise if zero is first element in list with index - 1 will get the last element if puzzle_zero_y - 1 >= 0: try: content[puzzle_zero_x][puzzle_zero_y], content[puzzle_zero_x][ puzzle_zero_y - 1] = content[puzzle_zero_x][ puzzle_zero_y - 1], content[puzzle_zero_x][puzzle_zero_y] except Exception as e: pass else: puzzle_children.append( Puzzle_node(content, (puzzle_zero_x, puzzle_zero_y - 1), puzzle.distance_from_root + 1, puzzle, movement_direction="right")) finally: content = deepcopy(puzzle.content) #DOWN try: content[puzzle_zero_x][puzzle_zero_y], content[ puzzle_zero_x + 1][puzzle_zero_y] = content[ puzzle_zero_x + 1][puzzle_zero_y], content[puzzle_zero_x][puzzle_zero_y] except Exception as e: pass else: puzzle_children.append( Puzzle_node(content, (puzzle_zero_x + 1, puzzle_zero_y), puzzle.distance_from_root + 1, puzzle, movement_direction="up")) finally: content = deepcopy(puzzle.content) #RIGHT try: content[puzzle_zero_x][puzzle_zero_y], content[puzzle_zero_x][ puzzle_zero_y + 1] = content[puzzle_zero_x][ puzzle_zero_y + 1], content[puzzle_zero_x][puzzle_zero_y] except Exception as e: pass else: puzzle_children.append( Puzzle_node(content, (puzzle_zero_x, puzzle_zero_y + 1), puzzle.distance_from_root + 1, puzzle, movement_direction="left")) finally: content = deepcopy(puzzle.content) return sorted(puzzle_children, key=lambda x: x.calculate_heuristic(final_state_dict_values), reverse=True)
i for i in list_of_sequentive_numbers[0 + size * j:size + size * j] ] for j in range(0, size)] return final_state_of_puzzle def is_puzzle_solved(puzzle, final_state): return puzzle == final_state if __name__ == "__main__": game_attributes = set_game_preconditions() #3 for 3x3, 4 for 4x4 and 5 for 5x5 size = game_attributes[0] index_of_zero_in_solved_puzzle = game_attributes[1] puzzle = game_attributes[2] final_state = create_final_state_of_puzzle_from_given_size_and_zero_position( size, index_of_zero_in_solved_puzzle) final_state_puzzle = Puzzle_node(final_state, (index_of_zero_in_solved_puzzle / size, index_of_zero_in_solved_puzzle % size)) final_state_dict_values = final_state_puzzle.tile_number_position_dict steps, directions = iterative_deepening_a_star(puzzle, final_state_puzzle, final_state_dict_values) print_puzzle_solution(steps, directions) assert puzzle.is_solvable, "Puzzle is not solvable!"