<jupyter_start><jupyter_text>Tarea 3---* Integrantes    - <NAME>     - <NAME>    - <NAME> ---Instructions to run pip install tabulate ( lo usamos para imprimir el grafo de la matriz)run entire notebook<jupyter_code>from agents import *
from notebook import psource
psource(Agent)

psource(Environment)

from random import choice

turn = False
class Roomba(Agent):
    location = [0,0]
    direction = Direction("down")
    
    def moveforward(self, success=True):
        global turn
        if not success:
            turn = True 
            return
        if self.direction.direction == Direction.R:
            self.location[0] += 1
        elif self.direction.direction == Direction.L:
            self.location[0] -= 1
        elif self.direction.direction == Direction.D:
            self.location[1] += 1
        elif self.direction.direction == Direction.U:
            self.location[1] -= 1
    
    def turn(self, d):
        self.direction = self.direction + d
        
    def clean(self, thing):
        '''returns True upon success or False otherwise'''
        if isinstance(thing, Food):
            return True
        return False
        
    def avoid(self, thing):
        '''returns True upon success or False otherwise'''
        if isinstance(thing, Obstacle):
            return True
        return False
    
def program(percepts):
    '''Returns an action based on it's percepts'''
    global turn
    for p in percepts: 
        if isinstance(p, Food):
            return 'clean'
    for p in percepts: 
        if isinstance(p, Obstacle):
            return 'avoid'
    if turn: # then recall if you were at an edge and had to turn
        turn = False
        choice = random.choice((1,2));
    else:
        choice = random.choice((1,2,3,4,5,6)) # 1-right, 2-left, others-forward
    if choice == 1:
        return 'turnright'
    elif choice == 2:
        return 'turnleft'
    else:
        return 'moveforward'
class Food(Thing):
    pass

class Obstacle(Thing):
    pass

class Room2D(GraphicEnvironment):
    def percept(self, agent):
        things = self.list_things_at(agent.location)
        return things
    
    def execute_action(self, agent, action):
        print("Magenta: Vacuum")
        print("Orange: Dirty Tile")
        print("Green: Obstacle")
        if action == 'turnright':
            print('{} decided to {} at location: {}'.format(str(agent)[1:-1], action, agent.location))
            agent.turn(Direction.R)
            #print('now facing {}'.format(agent.direction.direction))
        elif action == 'turnleft':
            print('{} decided to {} at location: {}'.format(str(agent)[1:-1], action, agent.location))
            agent.turn(Direction.L)
            #print('now facing {}'.format(agent.direction.direction))
        elif action == 'moveforward':
            loc = copy.deepcopy(agent.location) # find out the target location
            if agent.direction.direction == Direction.R:
                loc[0] += 2 # dos porque la matriz de graphic env y el sistema empiezan en 1 y 0 respectivamente
            elif agent.direction.direction == Direction.L:
                loc[0] -= 1
            elif agent.direction.direction == Direction.D:
                loc[1] += 2 # dos porque la matriz de graphic env y el sistema empiezan en 1 y 0 respectivamente
            elif agent.direction.direction == Direction.U:
                loc[1] -= 1
            #print('{} at {} facing {}'.format(agent, loc, agent.direction.direction))
            if self.is_inbounds(loc):# move only if the target is a valid location
                print('{} decided to move {}wards at location: {}'.format(str(agent)[1:-1], agent.direction.direction, agent.location))
                agent.moveforward()
            else:
                print('{} decided to move {}wards at location: {}, but couldnt'.format(str(agent)[1:-1], agent.direction.direction, agent.location))
                agent.moveforward(False)
        elif action == "clean":
            items = self.list_things_at(agent.location, tclass=Food)
            if len(items) != 0:
                if agent.clean(items[0]):
                    print('{} cleaned {} at location: {}'
                          .format(str(agent)[1:-1], str(items[0])[1:-1], agent.location))
                    self.delete_thing(items[0])
        elif action == "avoid":
            items = self.list_things_at(agent.location, tclass=Obstacle)
            if len(items) != 0:
                if agent.avoid(items[0]):
                    print('{} jumped over obstacle {} at location: {}'
                          .format(str(agent)[1:-1], str(items[0])[1:-1], agent.location))
                    
    def is_done(self):
        '''By default, we're done when we can't find a live agent, 
        but to prevent killing our cute dog, we will stop before itself - when there is no more food or water'''
        no_dirtness = not any(isinstance(thing, Food) for thing in self.things)
        dead_agents = not any(agent.is_alive() for agent in self.agents)
        return dead_agents or no_dirtness<jupyter_output><empty_output><jupyter_text>Part 1: Random movement---*  We created a 6x6 room and the roomba moves randomly in each step (50 Steps)    - If it finds a dirty tile it cleans it and then proceeds to keep moving.    - If there are no more dirty tiles, the program finishes---<jupyter_code>room = Room2D(6,6, color={'Roomba': (220,100,200), 'Food': (230, 115, 40), 'Obstacle' : (115,230,40)})
vacuum = Roomba(program)
initialRoombaLocation = [2,1]
vacuum.location = initialRoombaLocation
dirtyFloor = Food()
dirtyFloor2 = Food()
dirtyFloor3 = Food()
obstacle = Obstacle()
obstacle2 = Obstacle()


room.add_thing(vacuum, initialRoombaLocation)
room.add_thing(dirtyFloor, [2,2])
room.add_thing(dirtyFloor2, [0,0])
room.add_thing(dirtyFloor3, [0,5])
room.add_thing(obstacle, [3,0])
room.add_thing(obstacle2, [4,2])

room.run(50) # 50 steps para que se mueva<jupyter_output><empty_output><jupyter_text>Part 2 and 3: Vacuum with search algorithm and obstacles<jupyter_code>from collections import deque, namedtuple
from tabulate import tabulate
import numpy
import matplotlib.pyplot as plt

inf = float('inf')
Edge = namedtuple('Edge', 'start, end, cost')


def make_edge(start, end, cost=1):
  return Edge(start, end, cost)


class Graph:
    def __init__(self, edges):
        # let's check that the data is right
        wrong_edges = [i for i in edges if len(i) not in [2, 3]]
        if wrong_edges:
            raise ValueError('Wrong edges data: {}'.format(wrong_edges))

        self.edges = [make_edge(*edge) for edge in edges]

    @property
    def vertices(self):
        return set(
            sum(
                ([edge.start, edge.end] for edge in self.edges), []
            )
        )

    def get_node_pairs(self, n1, n2, both_ends=True):
        if both_ends:
            node_pairs = [[n1, n2], [n2, n1]]
        else:
            node_pairs = [[n1, n2]]
        return node_pairs

    def remove_edge(self, n1, n2, both_ends=True):
        node_pairs = self.get_node_pairs(n1, n2, both_ends)
        edges = self.edges[:]
        for edge in edges:
            if [edge.start, edge.end] in node_pairs:
                self.edges.remove(edge)

    def add_edge(self, n1, n2, cost=1, both_ends=True):
        node_pairs = self.get_node_pairs(n1, n2, both_ends)
        for edge in self.edges:
            if [edge.start, edge.end] in node_pairs:
                return ValueError('Edge {} {} already exists'.format(n1, n2))

        self.edges.append(Edge(start=n1, end=n2, cost=cost))
        if both_ends:
            self.edges.append(Edge(start=n2, end=n1, cost=cost))

    @property
    def neighbours(self):
        neighbours = {vertex: set() for vertex in self.vertices}
        for edge in self.edges:
            neighbours[edge.start].add((edge.end, edge.cost))

        return neighbours

    def search(self, source, dest):
        assert source in self.vertices, 'Such source node doesn\'t exist'
        distances = {vertex: inf for vertex in self.vertices}
        previous_vertices = {
            vertex: None for vertex in self.vertices
        }
        distances[source] = 0
        vertices = self.vertices.copy()

        while vertices:
            current_vertex = min(
                vertices, key=lambda vertex: distances[vertex])
            vertices.remove(current_vertex)
            if distances[current_vertex] == inf:
                break
            for neighbour, cost in self.neighbours[current_vertex]:
                alternative_route = distances[current_vertex] + cost
                if alternative_route < distances[neighbour]:
                    distances[neighbour] = alternative_route
                    previous_vertices[neighbour] = current_vertex

        path, current_vertex = deque(), dest
        while previous_vertices[current_vertex] is not None:
            path.appendleft(current_vertex)
            current_vertex = previous_vertices[current_vertex]
        if path:
            path.appendleft(current_vertex)
        return path

room2D = []


room2D.append(( "00","10",1))
room2D.append(( "00","01",1))


for x in range(0,10):
    for y in range (0,10):
        if(x == 0 and y!=0 and y < 9 ):
            firstCoordinate = str(x) + str(y)
            coordinateRight = str(x+1) + str(y)
            coordinateDown = str(x) + str(y + 1)
            coordinateUp = str(x) + str(y - 1)
            room2D.append((firstCoordinate,coordinateRight,1))
            room2D.append((firstCoordinate,coordinateDown,1))
            room2D.append((firstCoordinate,coordinateUp,1)) 
        if(x == 9 and y != 0 and y < 9 ):
            firstCoordinate = str(x) + str(y)
            coordinateLeft = str(x-1) + str(y)
            coordinateDown = str(x) + str(y + 1)
            coordinateUp = str(x) + str(y - 1)
            room2D.append((firstCoordinate,coordinateLeft,1))
            room2D.append((firstCoordinate,coordinateDown,1))
            room2D.append((firstCoordinate,coordinateUp,1))
        if(y == 0 and x != 0 and x < 9 ):
            firstCoordinate = str(x) + str(y)
            coordinateLeft = str(x-1) + str(y)
            coordinateRight = str(x+1) + str(y)
            coordinateDown = str(x) + str(y + 1)
            room2D.append((firstCoordinate,coordinateLeft,1))
            room2D.append((firstCoordinate,coordinateRight,1))
            room2D.append((firstCoordinate,coordinateDown,1)) 
        if(y == 9 and x != 0 and x < 9 ):
            firstCoordinate = str(x) + str(y)
            coordinateLeft = str(x-1) + str(y)
            coordinateRight = str(x+1) + str(y)
            coordinateUp = str(x) + str(y - 1)
            room2D.append((firstCoordinate,coordinateLeft,1))
            room2D.append((firstCoordinate,coordinateRight,1))
            room2D.append((firstCoordinate,coordinateUp,1))  
        if(x > 0 and x < 9): # para x,y que conectan a otros 4 porque no están en orillas
            #Añadiendo un obstaculo en 1,3
            if(x == 1 and y == 3 ):
                firstCoordinate = str(x) + str(y)
                coordinateLeft = str(x-1) + str(y)
                coordinateRight = str(x+1) + str(y)
                coordinateUp = str(x) + str(y - 1)
                coordinateDown = str(x) + str(y + 1)
                room2D.append((firstCoordinate,coordinateLeft,100))
                room2D.append((firstCoordinate,coordinateRight,100))
                room2D.append((firstCoordinate,coordinateUp,100))
                room2D.append((firstCoordinate,coordinateDown,100))
            elif(y > 0 and y < 9):
                firstCoordinate = str(x) + str(y)
                coordinateLeft = str(x-1) + str(y)
                coordinateRight = str(x+1) + str(y)
                coordinateUp = str(x) + str(y - 1)
                coordinateDown = str(x) + str(y + 1)
                room2D.append((firstCoordinate,coordinateLeft,1))
                room2D.append((firstCoordinate,coordinateRight,1))
                room2D.append((firstCoordinate,coordinateUp,1))
                room2D.append((firstCoordinate,coordinateDown,1))

            
        
room2D.append(( "99","89",1))
room2D.append(( "99","98",1))
room2D.append(( "90","80",1))
room2D.append(( "90","91",1))
room2D.append(( "09","19",1))
room2D.append(( "09","08",1))

room2DMap = Graph(room2D)
print('Solución de Ruta:')

print('Ejemplo 1')
print('Roomba empieza en 0,0 se mueve de la siguiente forma para limpiar basura en 5,2 y 9,9')
print(room2DMap.search("00","52"))
print(room2DMap.search("52","99"))

print('Ejemplo 2') # Obstaculos dentro de nuestro ejemplo (Vemos que la distancia aumenta a 100 como en el ejemplo del maze)
print('Observamos que no pisa 1,3 porque eso resulta en un obstaculo que tiene que evadir')
print('Roomba empieza en 5,5 se mueve de la siguiente forma para limpiar basura en 0,2 y 7,5')
print(room2DMap.search("55","02"))
print(room2DMap.search("02","75"))
print('10x10 cuarto como Grafo')
print(tabulate(room2D, headers=['CoordinateA', 'CoordinateB','Distance']))<jupyter_output>Solución de Ruta:
Ejemplo 1
Roomba empieza en 0,0 se mueve de la siguiente forma para limpiar basura en 5,2 y 9,9
deque(['00', '10', '20', '21', '22', '32', '42', '52'])
deque(['52', '53', '54', '55', '65', '66', '76', '77', '87', '88', '89', '99'])
Ejemplo 2
Observamos que no pisa 1,3 porque eso resulta en un obstaculo que tiene que evadir
Roomba empieza en 5,5 se mueve de la siguiente forma para limpiar basura en 0,2 y 7,5
deque(['55', '45', '44', '43', '33', '32', '22', '12', '02'])
deque(['02', '12', '22', '32', '33', '43', '44', '45', '55', '65', '75'])
10x10 cuarto como Grafo
  CoordinateA    CoordinateB    Distance
-------------  -------------  ----------
           00             10           1
           00             01           1
           01             11           1
           01             02           1
           01             00           1
           02             12           1
           02             03           1
           02             01           1
 [...]<jupyter_text>Ejemplo 1 Vacuum with search algorithm and GUI<jupyter_code>#EJEMPLO
import os.path
from tkinter import *

from agents import *

#sys.path.append(os.path.join(os.path.dirname(__file__), '..'))

def transferGraphMatrixToRealValues(matrix2D):
    print(matrix2D)


class Gui(VacuumEnvironment):
    """This is a two-dimensional GUI environment. Each location may be
    dirty, clean or can have a wall. The user can change these at each step.
    """
    xi, yi = (0, 0)
    perceptible_distance = 1
    coordinatesList = []
    listIndex = 0
    def __init__(self, root, width=12, height=12, elements=None):
        super().__init__(width, height)
        if elements is None:
            elements = ['D', 'W']
        print('ejemplo 1: Abierto en TKinter')
        #print('ejemplo 2')
        self.generateMatrix()
        self.root = root
        self.listIndex = 0
        self.create_frames()
        self.create_buttons()
        self.create_walls()
        self.elements = elements
    class Coordinates():
        x = 0
        y = 0
        def __init__(self,x,y):
            self.x = x
            self.y = y
            
    def generateMatrix(self):
        matrix = room2D
        matrixGraph = Graph(room2D)
        pathToFollow = matrixGraph.search("00","15") # CAMBIAR COORDENADAS DESTINO 
        index = 0
        print("Following path:" )       
        for x in pathToFollow:
            if (index < len(pathToFollow)):
                coordsStr = list(x)
                coordinate = self.Coordinates(int(coordsStr[0]) + 1,int(coordsStr[1]) + 1)
                self.coordinatesList.append(coordinate)
                print('' + str(coordinate.y) + ',' + str(coordinate.x))
            index = index + 1
       

    def create_frames(self):
        """Adds frames to the GUI environment."""
        self.frames = []
        for _ in range(12):
            frame = Frame(self.root, bg='grey')
            frame.pack(side='bottom')
            self.frames.append(frame)

    def create_buttons(self):
        """Adds buttons to the respective frames in the GUI."""
        self.buttons = []
        for frame in self.frames:
            button_row = []
            for _ in range(12):
                button = Button(frame, height=3, width=5, padx=2, pady=2)
                button.config(
                    command=lambda btn=button: self.display_element(btn))
                button.pack(side='left')
                button_row.append(button)
            self.buttons.append(button_row)

    def create_walls(self):
        """Creates the outer boundary walls which do not move."""
        for row, button_row in enumerate(self.buttons):
            if row == 0 or row == len(self.buttons) - 1:
                for button in button_row:
                    button.config(text='W', state='disabled',
                                  disabledforeground='black')
            else:
                button_row[0].config(
                    text='W', state='disabled', disabledforeground='black')
                button_row[len(button_row) - 1].config(text='W',
                                                       state='disabled', disabledforeground='black')
        # Place the agent in the centre of the grid.
        self.buttons[1][1].config(
            text='A', state='disabled', disabledforeground='black')
        self.buttons[2][6].config(
            text='Trash', state='disabled', disabledforeground='black') #CAMBIAR TRASH
     
        
    def display_element(self, button):
        """Show the things on the GUI."""
        txt = button['text']
        if txt != 'A':
            if txt == 'W':
                button.config(text='D')
            elif txt == 'D':
                button.config(text='')
            elif txt == '':
                button.config(text='W')

    def execute_action(self, agent, action):
        """Determines the action the agent performs."""
        xi, yi = (self.xi, self.yi)
        if action == 'Suck':
            dirt_list = self.list_things_at(agent.location, Dirt)
            if dirt_list:
                dirt = dirt_list[0]
                agent.performance += 100
                self.delete_thing(dirt)
                self.buttons[xi][yi].config(text='', state='normal')
                xf, yf = agent.location
                self.buttons[xf][yf].config(
                    text='A', state='disabled', disabledforeground='black')

        else:
            agent.bump = False
            if action == 'TurnRight':
                agent.direction += Direction.R
            elif action == 'TurnLeft':
                agent.direction += Direction.L
            elif action == 'Forward':
                agent.bump = self.move_to(agent, agent.direction.move_forward(agent.location))
                if not agent.bump:
                    self.buttons[xi][yi].config(text='', state='normal')
                    xf, yf = agent.location
                    self.buttons[xf][yf].config(
                        text='A', state='disabled', disabledforeground='black')

        if action != 'NoOp':
            agent.performance -= 1

    def read_env(self):
        """Reads the current state of the GUI environment."""
        for i, btn_row in enumerate(self.buttons):
            for j, btn in enumerate(btn_row):
                if (i != 0 and i != len(self.buttons) - 1) and (j != 0 and j != len(btn_row) - 1):
                    agt_loc = self.agents[0].location
                    if self.some_things_at((i, j)) and (i, j) != agt_loc:
                        for thing in self.list_things_at((i, j)):
                            self.delete_thing(thing)
                    if btn['text'] == self.elements[0]:
                        self.add_thing(Dirt(), (i, j))
                    elif btn['text'] == self.elements[1]:
                        self.add_thing(Wall(), (i, j))

    def update_env(self):
        """Updates the GUI environment according to the current state."""
        self.read_env()
        agt = self.agents[0]
        previous_agent_location = agt.location
        self.xi, self.yi = previous_agent_location
        self.step()
        xf, yf = agt.location
        
    def Example1SearchAlgorithm(self):
        self.read_env()
        agt = self.agents[0]
        previous_agent_location = agt.location
        self.xi,self.yi = previous_agent_location
        if(self.listIndex >= len(self.coordinatesList)):
            print("Everything has been cleaned")
            self.reset_env(agt)
            root.quit()
            root.destroy()
        else:
            agt.location = (self.coordinatesList[self.listIndex].x,self.coordinatesList[self.listIndex].y)
            print('Current Agent location')
            print(agt.location)
            self.step()
            xf,yf = (self.coordinatesList[self.listIndex].x,self.coordinatesList[self.listIndex].y)
            self.listIndex += 1

    def reset_env(self, agt):
        """Resets the GUI environment to the initial state."""
        self.read_env()
        for i, btn_row in enumerate(self.buttons):
            for j, btn in enumerate(btn_row):
                if (i != 0 and i != len(self.buttons) - 1) and (j != 0 and j != len(btn_row) - 1):
                    if self.some_things_at((i, j)):
                        for thing in self.list_things_at((i, j)):
                            self.delete_thing(thing)
                            btn.config(text='', state='normal')
        self.add_thing(agt, location=(1, 1))
        self.buttons[1][1].config(
            text='A', state='disabled', disabledforeground='black')


def XYReflexAgentProgram(percept):
    """The modified SimpleReflexAgentProgram for the GUI environment."""
    status, bump = percept
    if status == 'Dirty':
        return 'Suck'

    if bump == 'Bump':
        value = random.choice((0,-1)) #
    else:
        value = random.choice((3,4,5,6))  # 1-right, 2-left, others-forward
    if value == 1:
        return 'TurnRight'
    elif value == 2:
        return 'TurnLeft'
    else:
        return 'Forward'


class XYReflexAgent(Agent):
    """The modified SimpleReflexAgent for the GUI environment."""
    def __init__(self, program=None):
        super().__init__(program)
        self.location = (1, 1)
        self.direction = Direction("up")


# TODO: Check the coordinate system.
# TODO: Give manual choice for agent's location.
if __name__ == "__main__":
    #transferGraphMatrixToRealValues(room2D)
    root = Tk()
    root.title("Vacuum Environment")
    root.geometry("800x800")
    root.resizable(0, 0)
    frame = Frame(root, bg='black')
    ''' 
    reset_button = Button(frame, text='Reset', height=2,
                          #width=6, padx=2, pady=2)
    reset_button.pack(side='left')
    '''
    next_button = Button(frame, text='Next', height=2,
                         width=6, padx=2, pady=2)
    next_button.pack(side='left')
    frame.pack(side='bottom')
    env = Gui(root)
    agt = XYReflexAgent(program=XYReflexAgentProgram)
    env.add_thing(agt, location=(1, 1)) # 0,0
    
    #next_button.config(command=env.update_env)
    next_button.config(command=env.Example1SearchAlgorithm)

    #reset_button.config(command=lambda: env.reset_env(agt))
    root.mainloop()<jupyter_output>ejemplo 1: Abierto en TKinter
Following path:
1,1
2,1
3,1
4,1
5,1
6,1
6,2
Current Agent location
(1, 1)
Current Agent location
(1, 2)
Current Agent location
(1, 3)
Current Agent location
(1, 4)
Current Agent location
(1, 5)
Current Agent location
(1, 6)
Current Agent location
(2, 6)
Everything has been cleaned<jupyter_text>Ejemplo 2 Vacuum with search algorithm and obstacles<jupyter_code>room2D = []
room2D.append(( "00","10",1))
room2D.append(( "00","01",1))
for x in range(0,10):
    for y in range (0,10):
        if(x == 0 and y!=0 and y < 9 ):
            firstCoordinate = str(x) + str(y)
            coordinateRight = str(x+1) + str(y)
            coordinateDown = str(x) + str(y + 1)
            coordinateUp = str(x) + str(y - 1)
            room2D.append((firstCoordinate,coordinateRight,1))
            room2D.append((firstCoordinate,coordinateDown,1))
            room2D.append((firstCoordinate,coordinateUp,1)) 
        if(x == 9 and y != 0 and y < 9 ):
            firstCoordinate = str(x) + str(y)
            coordinateLeft = str(x-1) + str(y)
            coordinateDown = str(x) + str(y + 1)
            coordinateUp = str(x) + str(y - 1)
            room2D.append((firstCoordinate,coordinateLeft,1))
            room2D.append((firstCoordinate,coordinateDown,1))
            room2D.append((firstCoordinate,coordinateUp,1))
        if(y == 0 and x != 0 and x < 9 ):
            if(x == 1):
                firstCoordinate = str(x) + str(y)
                coordinateLeft = str(x-1) + str(y)
                coordinateRight = str(x+1) + str(y)
                coordinateUp = str(x) + str(y - 1)
                coordinateDown = str(x) + str(y + 1)
                room2D.append((firstCoordinate,coordinateLeft,100))
                room2D.append((firstCoordinate,coordinateRight,100))
                room2D.append((firstCoordinate,coordinateUp,100))
                room2D.append((firstCoordinate,coordinateDown,100))
            else:
                firstCoordinate = str(x) + str(y)
                coordinateLeft = str(x-1) + str(y)
                coordinateRight = str(x+1) + str(y)
                coordinateDown = str(x) + str(y + 1)
                room2D.append((firstCoordinate,coordinateLeft,1))
                room2D.append((firstCoordinate,coordinateRight,1))
                room2D.append((firstCoordinate,coordinateDown,1)) 
        if(y == 9 and x != 0 and x < 9 ):
            firstCoordinate = str(x) + str(y)
            coordinateLeft = str(x-1) + str(y)
            coordinateRight = str(x+1) + str(y)
            coordinateUp = str(x) + str(y - 1)
            room2D.append((firstCoordinate,coordinateLeft,1))
            room2D.append((firstCoordinate,coordinateRight,1))
            room2D.append((firstCoordinate,coordinateUp,1))  
        if(x > 0 and x < 9): # para x,y que conectan a otros 4 porque no están en orillas
            #Añadiendo un obstaculo en 1,3
            if(x == 1 and y == 1 ):
                firstCoordinate = str(x) + str(y)
                coordinateLeft = str(x-1) + str(y)
                coordinateRight = str(x+1) + str(y)
                coordinateUp = str(x) + str(y - 1)
                coordinateDown = str(x) + str(y + 1)
                room2D.append((firstCoordinate,coordinateLeft,100))
                room2D.append((firstCoordinate,coordinateRight,100))
                room2D.append((firstCoordinate,coordinateUp,100))
                room2D.append((firstCoordinate,coordinateDown,100))
            elif(x == 1 and y == 2 ):
                firstCoordinate = str(x) + str(y)
                coordinateLeft = str(x-1) + str(y)
                coordinateRight = str(x+1) + str(y)
                coordinateUp = str(x) + str(y - 1)
                coordinateDown = str(x) + str(y + 1)
                room2D.append((firstCoordinate,coordinateLeft,100))
                room2D.append((firstCoordinate,coordinateRight,100))
                room2D.append((firstCoordinate,coordinateUp,100))
                room2D.append((firstCoordinate,coordinateDown,100))
            elif(x == 1 and y == 3 ):
                firstCoordinate = str(x) + str(y)
                coordinateLeft = str(x-1) + str(y)
                coordinateRight = str(x+1) + str(y)
                coordinateUp = str(x) + str(y - 1)
                coordinateDown = str(x) + str(y + 1)
                room2D.append((firstCoordinate,coordinateLeft,100))
                room2D.append((firstCoordinate,coordinateRight,100))
                room2D.append((firstCoordinate,coordinateUp,100))
                room2D.append((firstCoordinate,coordinateDown,100))
            elif(y > 0 and y < 9):
                firstCoordinate = str(x) + str(y)
                coordinateLeft = str(x-1) + str(y)
                coordinateRight = str(x+1) + str(y)
                coordinateUp = str(x) + str(y - 1)
                coordinateDown = str(x) + str(y + 1)
                room2D.append((firstCoordinate,coordinateLeft,1))
                room2D.append((firstCoordinate,coordinateRight,1))
                room2D.append((firstCoordinate,coordinateUp,1))
                room2D.append((firstCoordinate,coordinateDown,1))
room2D.append(( "99","89",1))
room2D.append(( "99","98",1))
room2D.append(( "90","80",1))
room2D.append(( "90","91",1))
room2D.append(( "09","19",1))
room2D.append(( "09","08",1))

room2DMap = Graph(room2D)

#EJEMPLO
import os.path
from tkinter import *

from agents import *

#sys.path.append(os.path.join(os.path.dirname(__file__), '..'))

def transferGraphMatrixToRealValues(matrix2D):
    print(matrix2D)


class Gui(VacuumEnvironment):
    """This is a two-dimensional GUI environment. Each location may be
    dirty, clean or can have a wall. The user can change these at each step.
    """
    xi, yi = (0, 0)
    perceptible_distance = 1
    coordinatesList = []
    listIndex = 0
    def __init__(self, root, width=12, height=12, elements=None):
        super().__init__(width, height)
        if elements is None:
            elements = ['D', 'W']
        print('ejemplo 1: Abierto en TKinter')
        #print('ejemplo 2')
        self.generateMatrix()
        self.root = root
        self.listIndex = 0
        self.create_frames()
        self.create_buttons()
        self.create_walls()
        self.elements = elements
    class Coordinates():
        x = 0
        y = 0
        def __init__(self,x,y):
            self.x = x
            self.y = y
            
    def generateMatrix(self):
        matrix = room2D
        matrixGraph = Graph(room2D)
        pathToFollow = matrixGraph.search("00","22") # CAMBIAR COORDENADAS DESTINO 
        index = 0
        print("Following path:" )    
        print(pathToFollow)
        for x in pathToFollow:
            if (index < len(pathToFollow)):
                coordsStr = list(x)
                coordinate = self.Coordinates(int(coordsStr[0]) + 1,int(coordsStr[1]) + 1)
                self.coordinatesList.append(coordinate)
                print('' + str(coordinate.y) + ',' + str(coordinate.x))
            index = index + 1
       

    def create_frames(self):
        """Adds frames to the GUI environment."""
        self.frames = []
        for _ in range(12):
            frame = Frame(self.root, bg='grey')
            frame.pack(side='bottom')
            self.frames.append(frame)

    def create_buttons(self):
        """Adds buttons to the respective frames in the GUI."""
        self.buttons = []
        for frame in self.frames:
            button_row = []
            for _ in range(12):
                button = Button(frame, height=3, width=5, padx=2, pady=2)
                button.config(
                    command=lambda btn=button: self.display_element(btn))
                button.pack(side='left')
                button_row.append(button)
            self.buttons.append(button_row)

    def create_walls(self):
        """Creates the outer boundary walls which do not move."""
        for row, button_row in enumerate(self.buttons):
            if row == 0 or row == len(self.buttons) - 1:
                for button in button_row:
                    button.config(text='W', state='disabled',
                                  disabledforeground='black')
            else:
                button_row[0].config(
                    text='W', state='disabled', disabledforeground='black')
                button_row[len(button_row) - 1].config(text='W',
                                                       state='disabled', disabledforeground='black')
        # Place the agent in the centre of the grid.
        self.buttons[1][1].config(
            text='A', state='disabled', disabledforeground='black')
        self.buttons[3][3].config(
            text='Trash', state='disabled', disabledforeground='black')
        self.buttons[2][2].config(
            text='Obstacle', state='disabled', disabledforeground='black')
        self.buttons[3][2].config(
            text='Obstacle', state='disabled', disabledforeground='black')
        self.buttons[4][2].config(
            text='Obstacle', state='disabled', disabledforeground='black')
     
        
    def display_element(self, button):
        """Show the things on the GUI."""
        txt = button['text']
        if txt != 'A':
            if txt == 'W':
                button.config(text='D')
            elif txt == 'D':
                button.config(text='')
            elif txt == '':
                button.config(text='W')

    def execute_action(self, agent, action):
        """Determines the action the agent performs."""
        xi, yi = (self.xi, self.yi)
        if action == 'Suck':
            dirt_list = self.list_things_at(agent.location, Dirt)
            if dirt_list:
                dirt = dirt_list[0]
                agent.performance += 100
                self.delete_thing(dirt)
                self.buttons[xi][yi].config(text='', state='normal')
                xf, yf = agent.location
                self.buttons[xf][yf].config(
                    text='A', state='disabled', disabledforeground='black')

        else:
            agent.bump = False
            if action == 'TurnRight':
                agent.direction += Direction.R
            elif action == 'TurnLeft':
                agent.direction += Direction.L
            elif action == 'Forward':
                agent.bump = self.move_to(agent, agent.direction.move_forward(agent.location))
                if not agent.bump:
                    self.buttons[xi][yi].config(text='', state='normal')
                    xf, yf = agent.location
                    self.buttons[xf][yf].config(
                        text='A', state='disabled', disabledforeground='black')

        if action != 'NoOp':
            agent.performance -= 1

    def read_env(self):
        """Reads the current state of the GUI environment."""
        for i, btn_row in enumerate(self.buttons):
            for j, btn in enumerate(btn_row):
                if (i != 0 and i != len(self.buttons) - 1) and (j != 0 and j != len(btn_row) - 1):
                    agt_loc = self.agents[0].location
                    if self.some_things_at((i, j)) and (i, j) != agt_loc:
                        for thing in self.list_things_at((i, j)):
                            self.delete_thing(thing)
                    if btn['text'] == self.elements[0]:
                        self.add_thing(Dirt(), (i, j))
                    elif btn['text'] == self.elements[1]:
                        self.add_thing(Wall(), (i, j))

    def update_env(self):
        """Updates the GUI environment according to the current state."""
        self.read_env()
        agt = self.agents[0]
        previous_agent_location = agt.location
        self.xi, self.yi = previous_agent_location
        self.step()
        xf, yf = agt.location
        
    def Example1SearchAlgorithm(self):
        self.read_env()
        agt = self.agents[0]
        previous_agent_location = agt.location
        self.xi,self.yi = previous_agent_location
        if(self.listIndex >= len(self.coordinatesList) - 1):
            print("Everything has been cleaned")
            self.reset_env(agt)
            root.quit()
            root.destroy()
        else:
            #print("x:" + str(self.coordinatesList[self.listIndex].x) + "y:" +str(self.coordinatesList[self.listIndex].y))
            agt.location = (self.coordinatesList[self.listIndex].x,self.coordinatesList[self.listIndex].y)
            self.step()
            xf,yf = (self.coordinatesList[self.listIndex].x,self.coordinatesList[self.listIndex].y)
            self.listIndex += 1

    def reset_env(self, agt):
        """Resets the GUI environment to the initial state."""
        self.read_env()
        for i, btn_row in enumerate(self.buttons):
            for j, btn in enumerate(btn_row):
                if (i != 0 and i != len(self.buttons) - 1) and (j != 0 and j != len(btn_row) - 1):
                    if self.some_things_at((i, j)):
                        for thing in self.list_things_at((i, j)):
                            self.delete_thing(thing)
                            btn.config(text='', state='normal')
        self.add_thing(agt, location=(1, 1))
        self.buttons[1][1].config(
            text='A', state='disabled', disabledforeground='black')


def XYReflexAgentProgram(percept):
    """The modified SimpleReflexAgentProgram for the GUI environment."""
    status, bump = percept
    if status == 'Dirty':
        return 'Suck'

    if bump == 'Bump':
        value = random.choice((0,-1)) #
    else:
        value = random.choice((3,4,5,6))  # 1-right, 2-left, others-forward
    if value == 1:
        return 'TurnRight'
    elif value == 2:
        return 'TurnLeft'
    else:
        return 'Forward'


class XYReflexAgent(Agent):
    """The modified SimpleReflexAgent for the GUI environment."""
    def __init__(self, program=None):
        super().__init__(program)
        self.location = (1, 1)
        self.direction = Direction("up")


# TODO: Check the coordinate system.
# TODO: Give manual choice for agent's location.
if __name__ == "__main__":
    #transferGraphMatrixToRealValues(room2D)
    root = Tk()
    root.title("Vacuum Environment")
    root.geometry("800x800")
    root.resizable(0, 0)
    frame = Frame(root, bg='black')
    ''' 
    reset_button = Button(frame, text='Reset', height=2,
                          #width=6, padx=2, pady=2)
    reset_button.pack(side='left')
    '''
    next_button = Button(frame, text='Next', height=2,
                         width=6, padx=2, pady=2)
    next_button.pack(side='left')
    frame.pack(side='bottom')
    env = Gui(root)
    agt = XYReflexAgent(program=XYReflexAgentProgram)
    env.add_thing(agt, location=(1, 1)) # 0,0
    
    #next_button.config(command=env.update_env)
    next_button.config(command=env.Example1SearchAlgorithm)

    #reset_button.config(command=lambda: env.reset_env(agt))
    root.mainloop()<jupyter_output>ejemplo 1: Abierto en TKinter
Following path:
deque(['00', '01', '02', '03', '04', '14', '24', '23', '22'])
1,1
2,1
3,1
4,1
5,1
5,2
5,3
4,3
3,3
{'fraction_non_alphanumeric': 0.12737183646982478, 'fraction_numerical': 0.024944841012329657, 'mean_word_length': 2.061263408820024, 'pattern_counts': {'":': 4, '<': 36, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '583824', 'license': 'MIT', 'n_tokens_mistral': 12208, 'n_tokens_neox': 11371, 'n_words': 2787, 'path': 'Modulo_2/Tarea3Roomba.ipynb', 'repo_name': 'JulianHerreraH/Sistemas_Inteligentes', 'size': '38548'}