# Prerequisites¶

- Install VSCode
- Install Anaconda (Python3)

Environment Set Up

    $ conda create -n maze python=3.8
    $ conda activate maze

    $ pip install gym numpy jupyter

    $ cd gym-maze
    $ python setup.py install
    $ cd ..
    $ jupyter notebook

# Why do we need BFS DFS A*?¶

### Maze 2D http://maze2.trustai.uk/ ¶

Solving a small maze is trivial.

How about this one?

### Maze 2.5D http://maze25.trustai.uk/ ¶

For Local Search, we do not have access to the whole map. Only surrounding info available.

### Maze 3D http://maze3.trustai.uk/ ¶

We can not see through walls. Only to decide which direction to go.

# Real-World Applications¶

In [1]:

    from IPython.display import Video

In [2]:

    Video("./doc/robot-maze.mp4")

Out[2]:
Your browser does not support the `video` element.

# Let's build this robot¶

Different Games available here at OpenAI Gym https://gym.openai.com/

In [3]:

    import time
    import numpy as np

    import gym
    import gym_maze

Create a 10x10 map

In [4]:

    # env = gym.make("maze-sample-3x3-v0"); goal = (2, 2)
    # env = gym.make("maze-sample-5x5-v0"); goal = (4, 4)
    env = gym.make("maze-sample-10x10-v0"); goal = (9, 9)
    # env = gym.make("maze-sample-100x100-v0"); goal = (99, 99)

    pygame 1.9.6
    Hello from the pygame community. https://www.pygame.org/contribute.html

Take a loot at the maze

In [5]:

    _ = env.render()

Where are we now?

In [6]:

    observation = env.reset()
    print("Now we are at:", observation)

    Now we are at: [0. 0.]

0 - Up
1 - Down
2 - Right
3 - Left

       0
    3     2
       1

Let's move around

In [7]:

    action = 2

    observation, reward, done, info = env.step(action)
    print(observation)
    _ = env.render()

    [1 0]

In [8]:

    _ = env.step(1)
    _ = env.render()

Reset to the starting point

In [9]:

    _ = env.reset()

## Depth Firtst Search¶

In [10]:

    class Node():
        def __init__(self, state, parent, action, done):
            self.state = state
            self.parent = parent
            self.action = action
            self.done = False

    class StackFrontier():
        def __init__(self):
            self.frontier = []

        def add(self, node):
            self.frontier.append(node)

        def contains_state(self, state):
            return any(node.state == state for node in self.frontier)

        def empty(self):
            return len(self.frontier) == 0

        def remove(self):
            if self.empty():
                raise Exception("empty frontier")
            else:
                node = self.frontier[-1]
                self.frontier = self.frontier[:-1]
                return node

       0
    3     2
       1

Find neighnors

In [11]:

    reverse_action = [1, 0, 3, 2]

    def neighbors(state):
        candidates = [0, 1, 2, 3]
        result = []

        for action in candidates:
            # Take each possible action
            observation, _, done, _ = env.step(action)
            env.render()
            # If the position remains the same, it means there is a wall.
            # The action is valid only when the position changes. (no wall)
            if ( not (observation == np.array(state)).all() ):
                result.append((action, tuple(observation), done))
                # Go back first, and try next action
                _, _, _, _ = env.step(reverse_action[action])
                env.render()

        return result

### First, reset the maze¶

In [12]:

    _ = env.reset()
    _ = env.render()

### Time to Explore¶

In [13]:

    # Keep track of number of states explored
    num_explored = 0

    # Initialize frontier to just the starting position
    start = Node(state=env.reset(), parent=None, action=0, done=False)
    frontier = StackFrontier()
    frontier.add(start)

    # Initialize an empty explored set
    explored = set()
    solution = None

    action_stack = []

In [14]:

    # Keep looping until solution found
    while True:

        # If nothing left in frontier, then no path
        if frontier.empty():
            raise Exception("no solution")

        # Choose a node from the frontier
        # 0 - Up
        # 1 - Down
        # 2 - Right
        # 3 - Left
        node = frontier.remove()

        _, _, done, _ = env.step(node.action)
        action_stack.append(node.action)
        env.render()
        time.sleep(0.1)
        num_explored += 1

        # If node is the goal, then we have a solution
        if done:
            actions = []
            cells = []
            while node.parent is not None:
                actions.append(node.action)
                cells.append(node.state)
                node = node.parent
            actions.reverse()
            cells.reverse()
            solution = (actions, cells)
            break

        # Mark node as explored
        explored.add( tuple(node.state) )

        # Add neighbors to frontier
        i = 0
        for action, state, done in neighbors(node.state):
            if (not frontier.contains_state(state)) and (state not in explored):
                i = i + 1
                child = Node(state=state, parent=node, action=action, done=done)
                frontier.add(child)

        # No available neighbors, go back
        if(i == 0):
            while (not (np.array(frontier.frontier[-1].parent.state) == np.array(node.state)).all()):
                observation, _, done, _ = env.step(reverse_action[action_stack.pop()])
                env.render()
                node.state =  tuple(observation)

### Reset the maze¶

In [15]:

    _ = env.reset()
    _ = env.render()

### Run solution¶

In [16]:

    for action in solution[0]:
        _ = env.step(action)
        time.sleep(0.5)
        env.render()

In [17]:

    env.close()

## Assignment¶

    1. From DFS to BFS                   (3 LOC)
    2. Implement GBFS (BFS)              (2 LOC)
    3. From GBFS (BFS) to GBFS (DFS)     (2 LOC)

| maze1 | maze2 | maze3
--- | --- | --- | ---
DFS | 11 | 194 | 17
BFS |  |  |
GBFS (BFS) |  |  |
GBFS (DFS) |  |  |
A* | - | - | -

In [ ]:

# Congradulations, See you next week¶

A* Search

https://www.youtube.com/watch?v=-L-WgKMFuhE

In [ ]: