def canvas_click(self, event: tk.EventType) -> None:
     x = math.floor((event.x - self.app_frame.x_axis_padding) /
                    self.app_frame.grid_col_width)
     y = math.floor((event.y - self.app_frame.y_axis_padding) /
                    self.app_frame.grid_row_height)
     if self.choosing_start:
         self.start = SearchNode(GridState(x, y))
         self.chose_start = True
         self.choosing_start = False
         self.app_frame.entry1.delete(0, tk.END)
         self.app_frame.entry1.insert(0, str(self.start.state.x))
         self.app_frame.entry2.delete(0, tk.END)
         self.app_frame.entry2.insert(0, str(self.start.state.y))
     elif self.choosing_goal:
         self.goal = SearchNode(GridState(x, y))
         self.chose_goal = True
         self.choosing_goal = False
         self.app_frame.entry3.delete(0, tk.END)
         self.app_frame.entry3.insert(0, str(self.goal.state.x))
         self.app_frame.entry4.delete(0, tk.END)
         self.app_frame.entry4.insert(0, str(self.goal.state.y))
     else:
         print(f"clicked ({x}, {y})")
         return
     self.draw_initial()
 def apply_action(self, state: GridState,
                  action: CardinalGridAction) -> GridState:
     if not self.is_defined(state):
         raise StateDoesNotExistError(state)
     if not self.is_valid(state):
         raise StateNotValidError(state)
     x = 0
     y = 0
     if action == CardinalGridAction.UP:
         y -= 1
     elif action == CardinalGridAction.RIGHT:
         x += 1
     elif action == CardinalGridAction.DOWN:
         y += 1
     elif action == CardinalGridAction.LEFT:
         x -= 1
     else:
         raise NotImplementedError(f"GridAction {action} not supported.")
     test_state = GridState(state.x + x, state.y + y)
     valid = self.is_valid(test_state)
     if not valid:
         raise StateNotValidError(test_state)
     new_state = GridState(state.x + x, state.y + y, valid=valid)
     if not self.is_defined(new_state):
         raise StateDoesNotExistError
     return new_state
Example #3
0
def test_grid_state_undefined():
    undefined_state = GridState(-1, env.get_random().y)
    assert not env.is_defined(undefined_state)
    undefined_state = GridState(env.get_random().x, -1)
    assert not env.is_defined(undefined_state)
    undefined_state = GridState(env._width + 1, env.get_random().y)
    assert not env.is_defined(undefined_state)
    undefined_state = GridState(env.get_random().x, env._height + 1)
    assert not env.is_defined(undefined_state)
Example #4
0
def test_simple_shortest_search():
    """Test a search where the start and goal are neighbors. Ensure
    correct path and open list sizes. Assumes start is in an
    'open area' where all neighbors are valid.
    """
    start = GridState(18, 24, valid=True)
    goal = GridState(19, 24, valid=True)
    astar = GenericBFS(env,
                        start=start,
                        goal=goal)
    astar.get_path()
    assert len(astar.path) == 2  # start, goal
Example #5
0
def test_simple_shortest_search():
    """Test a search where the start and goal are neighbors. Ensure
    correct path and open list sizes. Assumes start is in an
    'open area' where all neighbors are valid.
    """
    start = GridState(18, 24, valid=True)
    goal = GridState(19, 24, valid=True)
    astar = GenericAstar(env,
                         heuristic=OctileGridHeuristic(),
                         start=start,
                         goal=goal)
    astar.get_path()
    print(astar.open)
    assert len(astar.path) == 2  # start, goal
    assert astar.nodes_expanded == 2  # start, goal
    assert len(astar.open) == 7  # start + 8 neighbors - start - goal
Example #6
0
def test_undefined_goal():
    """Test all 4 map boundaries <0, >width, <0, >height.
    if unchecked, negatives would index backwards into grid.env[][]
    """
    bad_goal = GridState(-1, env.get_random().y)
    with pytest.raises(StateDoesNotExistError):
        GenericAstar(env, heuristic=OctileGridHeuristic(), goal=bad_goal)
    bad_goal = GridState(env.get_random().x, -1)
    with pytest.raises(StateDoesNotExistError):
        GenericAstar(env, heuristic=OctileGridHeuristic(), goal=bad_goal)
    bad_goal = GridState(env.width + 1, env.get_random().y)
    with pytest.raises(StateDoesNotExistError):
        GenericAstar(env, heuristic=OctileGridHeuristic(), goal=bad_goal)
    bad_goal = GridState(env.get_random().x, env._height + 1)
    with pytest.raises(StateDoesNotExistError):
        GenericAstar(env, heuristic=OctileGridHeuristic(), goal=bad_goal)
Example #7
0
def test_search_failure_undefined_goal():
    """Test scenario where someone bypasses the properties and messes with the private _goal member. 
    Making the _start invalid or undefined after initialization should not impact the search at all.
    Making the goal invalid should let the search run until it has exhausted the state space and then 
    return no path.
    """
    gastar = get_random_search()
    gastar._goal = GridState(-1, -1)
    assert len(gastar.get_path()) == 0
Example #8
0
def test_grid_get_actions():
    middle_state = GridState(18, 23, valid=True)
    action_cost_tuples = env.get_actions(middle_state, None)
    actions = [
        OctileGridAction.UP, OctileGridAction.DOWN, OctileGridAction.LEFT,
        OctileGridAction.RIGHT, OctileGridAction.DOWN_LEFT,
        OctileGridAction.DOWN_RIGHT, OctileGridAction.UP_LEFT,
        OctileGridAction.UP_RIGHT
    ]
    for action, _ in action_cost_tuples:
        assert action in actions
Example #9
0
def test_grid_apply_action():
    undefined_state = GridState(-1, env.get_random().y)
    with pytest.raises(StateDoesNotExistError):
        env.apply_action(undefined_state, CardinalGridAction.UP)
    impassable_state = GridState(18, 9)
    with pytest.raises(StateNotValidError):
        env.apply_action(impassable_state, CardinalGridAction.UP)
    middle_state = GridState(18, 23, valid=True)
    assert env.apply_action(middle_state,
                            CardinalGridAction.UP) == GridState(18, 22)
    assert env.apply_action(middle_state,
                            CardinalGridAction.LEFT) == GridState(17, 23)
    assert env.apply_action(middle_state,
                            CardinalGridAction.DOWN) == GridState(18, 24)
    assert env.apply_action(middle_state,
                            CardinalGridAction.RIGHT) == GridState(19, 23)
Example #10
0
def test_history_on_failure():
    """Test to make sure history dict is being filled in with all the correct info
    for a failed search. Checking keys are correct - not validating data.
    """
    gastar = get_random_search()
    gastar._goal = GridState(-1, -1)
    gastar.get_path()
    assert 'start' in gastar.history
    assert 'goal' in gastar.history
    assert 'heuristic' in gastar.history
    assert 'nodes_expanded' in gastar.history
    assert 'steps' in gastar.history
    assert 'path' not in gastar.history
    for i in range(gastar.history['nodes_expanded'] - 1):
        step = 'step-' + str(i + 1)
        assert step in gastar.history['steps']
        assert 'expanded' in gastar.history['steps'][step]
        assert 'to_open' in gastar.history['steps'][step]
Example #11
0
def test_grid_state_passable():
    passable_state = GridState(18, 10)
    assert env.is_valid(passable_state)
    assert not env.is_valid(GridState(18, 9))