diff --git a/main.py b/main.py
index 6a3ed43c5b838bc873135fd59571f85a9dc5fd46..b9cb26cbacb69021528bfde9b2d57da53910b2ad 100644
--- a/main.py
+++ b/main.py
@@ -9,7 +9,7 @@ import sdl2.ext
 # User Imports.
 from src.entities import GuiCore, Roomba, TileSet
 from src.logging import init_logging
-from src.misc import DataManager, handle_key_press, handle_mouse_click
+from src.misc import calc_trash_distances, calc_traveling_salesman, DataManager, handle_key_press, handle_mouse_click
 from src.systems import AISystem, MovementSystem, SoftwareRendererSystem
 
 
@@ -23,6 +23,8 @@ RESOURCES = sdl2.ext.Resources(__file__, './src/images/')
 # Initialize window width/height.
 WINDOW_WIDTH = 640
 WINDOW_HEIGHT = 480
+# WINDOW_WIDTH = 400
+# WINDOW_HEIGHT = 200
 WINDOW_WIDTH_MIN = 400
 WINDOW_HEIGHT_MIN = 200
 
@@ -52,7 +54,7 @@ def main():
     movement = MovementSystem(data_manager, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT)
 
     # Add subsystems to world manager.
-    # world.add_system(ai)
+    world.add_system(ai)
     world.add_system(movement)
     world.add_system(sprite_renderer)
 
@@ -220,6 +222,10 @@ def initialize_data():
     # Initialize GUI object data.
     data_manager.gui = GuiCore(data_manager)
 
+    # Calculate path distances for initial setup.
+    data_manager.ideal_trash_paths = calc_trash_distances(data_manager)
+    calc_traveling_salesman(data_manager)
+
     # Return generated window object.
     return data_manager
 
diff --git a/src/entities/object_entities.py b/src/entities/object_entities.py
index 6bfac7ddcd55504a925a2b483d400e99aeeff4a1..d75580ddb0066a808561d22134656e361d7187cb 100644
--- a/src/entities/object_entities.py
+++ b/src/entities/object_entities.py
@@ -277,7 +277,7 @@ class TileSet:
         # Ensure all paths are accessible by roomba.
         self.tiles[0][0].walls.bipartite_color_validation()
 
-        # Recalculate trash distances for new wall setup.
+        # Recalculate path distances for new wall setup.
         self.data_manager.ideal_trash_paths = calc_trash_distances(self.data_manager)
         calc_traveling_salesman(self.data_manager)
 
@@ -302,8 +302,9 @@ class TileSet:
                     if self.tiles[row_index][col_index].trashpile.exists:
                         self.tiles[row_index][col_index].trashpile.clean()
 
-        # Recalculate trash distances for new trash pile setup.
+        # Recalculate path distances for new trash pile setup.
         self.data_manager.ideal_trash_paths = calc_trash_distances(self.data_manager)
+        calc_traveling_salesman(self.data_manager)
 
 
 class Trash(sdl2.ext.Entity):
diff --git a/src/misc.py b/src/misc.py
index e5153482a91d1fa757c68038b80004796e3991cf..ff57c5553c64519b6ba4f2966404819584435b0b 100644
--- a/src/misc.py
+++ b/src/misc.py
@@ -48,6 +48,7 @@ class DataManager:
         self.ai_active = False
         self.roomba_vision = 1
         self.ideal_trash_paths = None
+        self.ideal_overall_path = None
         self.graph = networkx.Graph()
         self.graph.data = {
             'trash_tiles': []
@@ -164,8 +165,9 @@ def handle_mouse_click(data_manager, button_state, pos_x, pos_y):
             logger.info('    Decrementing tile walls.')
             tile.walls.decrement_wall_state()
 
-        # Recalculate trash distances for new tile wall setup.
+        # Recalculate path distances for new tile wall setup.
         data_manager.ideal_trash_paths = calc_trash_distances(data_manager)
+        calc_traveling_salesman(data_manager)
 
 # endregion GUI Logic Functions
 
@@ -663,8 +665,6 @@ def calc_traveling_salesman(data_manager, debug=False):
     Calculates the approximately-ideal overall path to visit all trash tiles.
     :param data_manager: Data manager data structure. Consolidates useful program data to one location.
     """
-    debug = True
-
     # Clear all debug entities.
     clear_debug_entities(data_manager)
 
@@ -673,10 +673,10 @@ def calc_traveling_salesman(data_manager, debug=False):
     trash_tile_set = data_manager.graph.data['trash_tiles']
     trash_paths = data_manager.ideal_trash_paths
 
-    print('\n\n\n\n')
-    print(' ==== TRAVELING SALESMAN ===== ')
-    print('\n')
-    print('trash_paths: {0}'.format(trash_paths))
+    logger.info('\n\n\n\n')
+    logger.info(' ==== TRAVELING SALESMAN ===== ')
+    logger.info('\n')
+    logger.info('trash_paths: {0}'.format(trash_paths))
 
     # Initialize path by just going to trash tiles in original ordering.
     curr_total_dist = 999999
@@ -773,6 +773,9 @@ def calc_traveling_salesman(data_manager, debug=False):
             calculated_path['ordering'][conn_1_index_1] = conn_2_id_1
             calculated_path['ordering'][conn_2_index_1] = conn_1_id_1
 
+    # Save found path.
+    data_manager.ideal_overall_path = calculated_path
+
     # Optionally display debug tile sprites.
     if debug:
         from src.entities.object_entities import DebugTile
diff --git a/src/systems.py b/src/systems.py
index 6558fb7c0964c944536a051e53db96d3b0eaade0..8ff392c102210f471d95b491e40f286f7962be94 100644
--- a/src/systems.py
+++ b/src/systems.py
@@ -11,6 +11,7 @@ from abc import ABC
 # User Imports.
 from src.entities.system_entities import AI, Movement, SearchOptimalDistance
 from src.logging import init_logging
+from src.misc import calc_trash_distances, calc_traveling_salesman, get_tile_coord_from_id
 
 
 # Initialize logger.
@@ -196,6 +197,10 @@ class AbstractMovementSystem(ABC):
         if roomba_location[0] == tile_x and roomba_location[1] == tile_y and curr_tile.trashpile.exists:
             curr_tile.trashpile.clean()
 
+        # Recalculate path distances for new roomba location.
+        self.data_manager.ideal_trash_paths = calc_trash_distances(self.data_manager)
+        calc_traveling_salesman(self.data_manager)
+
 
 class MovementSystem(sdl2.ext.Applicator, AbstractMovementSystem):
     """
@@ -398,9 +403,50 @@ class AISystem(sdl2.ext.Applicator, AbstractMovementSystem):
             self.prev_direction = prev_direction
 
     def move_full_sight(self, sprite):
-        """"""
-        # Move roomba.
-        self.move_east(sprite)
+        """
+        Move roomba with "full sight" setting.
+
+        Assumes some "outside entity" knows what the full environment setup is, and is feeding the roomba this
+        information. Roomba intelligently attempts to take the "most efficient path" to get to all trash piles.
+        :param sprite: Roomba sprite entity.
+        """
+        # Get first set in "calculated ideal path".
+        end_tile_group_id = self.data_manager.ideal_overall_path['ordering'][1]
+        path_set = self.data_manager.ideal_trash_paths['roomba'][end_tile_group_id]
+        print('path_set: {0}'.format(path_set))
+
+        # Get first tile in path set.
+        curr_tile_id = path_set[0]
+        desired_next_tile_id = path_set[1]
+        curr_tile_x, curr_tile_y = get_tile_coord_from_id(curr_tile_id)
+        desired_tile_x, desired_tile_y = get_tile_coord_from_id(desired_next_tile_id)
+
+        print('curr_tile: ({0}, {1})'.format(curr_tile_x, curr_tile_y))
+        print('desired_tile: ({0}, {1})'.format(desired_tile_x, desired_tile_y))
+
+        # Determine which direction we move, in order to reach desired tile.
+        if curr_tile_x != desired_tile_x:
+            # Moving east/west.
+            if curr_tile_x < desired_tile_x:
+                # Move east.
+                self.move_east(sprite)
+                self.prev_direction = 'east'
+            else:
+                # Move west.
+                self.move_west(sprite)
+                self.prev_direction = 'west'
+        elif curr_tile_y != desired_tile_y:
+            # Moving north/south.
+            if curr_tile_y < desired_tile_y:
+                # Move south.
+                self.move_south(sprite)
+                self.prev_direction = 'south'
+            else:
+                # Move north.
+                self.move_north(sprite)
+                self.prev_direction = 'north'
+        else:
+            raise RuntimeError('Unable to determine where to move.')
 
     def move_limited_vision(self, sprite):
         """"""