Ejemplo n.º 1
0
 def establece_mochila(self, cantidad):
     """Establece los zumbadores en la mochila de karel a cierta cantidad"""
     if cantidad == 'inf' or cantidad == '-1' or cantidad == -1:
         self.mundo['karel']['mochila'] = -1
     elif type(cantidad) == int:
         if cantidad >= 0:
             self.mundo['karel']['mochila'] = cantidad
         else:
             raise KarelException(
                 'Esta no es una cantidad apropiada de zumbadores')
     else:
         raise KarelException('Deberías consultar a un psiquiatra')
Ejemplo n.º 2
0
 def carga_archivo(self, archivo):
     """ Carga el contenido de un archivo con la configuración del
     mundo. Archivo debe ser una instancia de 'file' o de un objeto
     con metodo 'read()'"""
     mundo = json.load(archivo)
     #Lo cargamos al interior
     self.mundo_backup = self.mundo
     try:
         self.mundo = {
             'karel': {
                 'posicion': tuple(mundo['karel']['posicion']),
                 'orientacion': mundo['karel']['orientacion'],
                 'mochila':
                 mundo['karel']['mochila']  #Zumbadores en la mochila
             },
             'dimensiones': {
                 'filas': mundo['dimensiones']['filas'],
                 'columnas': mundo['dimensiones']['columnas']
             },
             'casillas': dict()
         }
         if not self.carga_casillas(mundo['casillas']):
             raise KarelException("Se mando un mundo deformado")
     except KeyError:
         self.mundo = self.mundo_backup
         del (self.mundo_backup)
         return False
     else:
         del (self.mundo_backup)
         return True
Ejemplo n.º 3
0
    def __init__(self,
                 filas=100,
                 columnas=100,
                 karel_pos=(1, 1),
                 orientacion='norte',
                 mochila=0,
                 casillas=dict(),
                 archivo=None):
        """ Inicializa el mundo, con Karel en la esquina 1,1 del mundo
        orientado al norte.

        El mundo es un diccionario con dos llaves:

        * karel indica mediante una tupla la fila y la columna en la que
        se encuentra el robot
        * casillas indica cómo está construido el mundo mediante un
        diccionario, que tiene por llaves las tuplas con la posicion que
        representan: (fila, columna) """
        self.mundo = {
            'karel': {
                'posicion': karel_pos,
                'orientacion': orientacion,
                'mochila': mochila  #Zumbadores en la mochila
            },
            'dimensiones': {
                'filas': filas,
                'columnas': columnas
            },
            'casillas': casillas
        }
        if archivo is not None and isinstance(archivo, file):
            if not self.carga_archivo(archivo):
                raise KarelException(
                    "El archivo de mundo que me diste esta dañado!")
Ejemplo n.º 4
0
 def bloque(self, cola, diccionario_variables):
     """ Ejecuta una cola de instrucciones dentro de una estructura
     mayor """
     for instruccion in cola:
         if type(instruccion) == dict:
             #Se trata de una estructura de control o una funcion definida
             if instruccion['estructura'] == 'si':
                 if self.termino_logico(instruccion['argumento']['o'],
                                        diccionario_variables):
                     self.bloque(instruccion['cola'], diccionario_variables)
                 elif instruccion.has_key('sino-cola'):
                     self.bloque(instruccion['sino-cola'],
                                 diccionario_variables)
                 if not self.corriendo or self.sal_de_instruccion or self.sal_de_bucle:
                     return
             elif instruccion['estructura'] == 'repite':
                 contador = 0
                 for i in xrange(
                         self.expresion_entera(instruccion['argumento'],
                                               diccionario_variables)):
                     self.bloque(instruccion['cola'], diccionario_variables)
                     if not self.corriendo or self.sal_de_instruccion or self.sal_de_bucle:
                         self.sal_de_bucle = False
                         return
                     contador += 1
                     if not contador < self.limite_iteracion:
                         raise KarelException(
                             u"LongIteration! algun bucle se ha ciclado")
             elif instruccion['estructura'] == 'mientras':
                 contador = 0
                 while self.termino_logico(instruccion['argumento']['o'],
                                           diccionario_variables):
                     self.bloque(instruccion['cola'], diccionario_variables)
                     if not self.corriendo or self.sal_de_instruccion or self.sal_de_bucle:
                         self.sal_de_bucle = False
                         return
                     contador += 1
                     if not contador < self.limite_iteracion:
                         raise KarelException(
                             u"LongIteration! algun bucle se ha ciclado")
             else:  #Se trata de una función
                 if self.profundidad == self.limite_recursion:
                     raise KarelException(
                         u"StackOverflow! Se ha alcanzado el límite de una recursion"
                     )
                 self.profundidad += 1
                 self.bloque(
                     self.arbol['funciones'][instruccion['nombre']]['cola'],
                     merge(
                         self.arbol['funciones'][instruccion['nombre']]
                         ['params'], instruccion['argumento']))
                 self.profundidad -= 1
                 if self.sal_de_instruccion:
                     self.sal_de_instruccion = False
         else:
             #Es una instruccion predefinida de Karel
             if instruccion == 'avanza':
                 if not self.mundo.avanza():
                     raise KarelException(
                         'Karel se ha estrellado con una pared!')
             elif instruccion == 'gira-izquierda':
                 self.mundo.gira_izquierda()
             elif instruccion == 'coge-zumbador':
                 if not self.mundo.coge_zumbador():
                     raise KarelException(
                         'Karel quizo coger un zumbador pero no habia en su posicion'
                     )
             elif instruccion == 'deja-zumbador':
                 if not self.mundo.deja_zumbador():
                     raise KarelException(
                         'Karel quizo dejar un zumbador pero su mochila estaba vacia'
                     )
             elif instruccion == 'apagate':
                 self.corriendo = False
                 return
             elif instruccion == 'sal-de-instruccion':
                 self.sal_de_instruccion = True
                 return
             elif instruccion == 'sal-de-bucle':
                 self.sal_de_bucle = True
                 return
Ejemplo n.º 5
0
 def lee_token(self):
     """Lee un token del archivo"""
     while True:
         self.columna += 1
         if not self.caracter_actual:
             break
         if self.estado == self.ESTADO_COMENTARIO:
             if self.debug:
                 print "Encontré", repr(
                     self.caracter_actual), "en estado comentario"
             if self.caracter_actual in self.simbolos:  #Lo que puede pasar es que sea basura o termine el comentario
                 if self.caracter_actual == ')' and self.abrir_comentario == '(*' and self.ultimo_caracter == '*':
                     self.estado = self.ESTADO_ESPACIO
                 if self.caracter_actual == '}' and self.abrir_comentario == '{':
                     self.estado = self.ESTADO_ESPACIO
                 if self.caracter_actual == '/' and self.abrir_comentario == '/*' and self.ultimo_caracter == '*':
                     self.estado = self.ESTADO_ESPACIO
             if self.caracter_actual == '\n':  #LINEA
                 self.cambio_de_linea()
         elif self.estado == self.ESTADO_ESPACIO:
             if self.debug:
                 print "Encontré", repr(
                     self.caracter_actual), "en estado espacio"
             if self.caracter_actual not in self.caracteres:
                 raise KarelException(
                     "Caracter desconocido en la linea %d columna %d" %
                     (self.linea, self.columna))
             if self.caracter_actual in self.numeros:
                 self.token += self.caracter_actual
                 self.estado = self.ESTADO_NUMERO
             elif self.caracter_actual in self.palabras:
                 self.token += self.caracter_actual
                 self.estado = self.ESTADO_PALABRA
             elif self.caracter_actual in self.simbolos:
                 self.estado = self.ESTADO_SIMBOLO
                 continue
             elif self.caracter_actual == '\n':  #LINEA
                 self.cambio_de_linea()
         elif self.estado == self.ESTADO_NUMERO:
             if self.debug:
                 print "Encontré", repr(
                     self.caracter_actual), "en estado número"
             if self.caracter_actual not in self.caracteres:
                 raise KarelException(
                     "Caracter desconocido en la linea %d columna %d" %
                     (self.linea, self.columna))
             if self.caracter_actual in self.numeros:
                 self.token += self.caracter_actual
             elif self.caracter_actual in self.palabras:  #Encontramos una letra en el estado numero, incorrecto
                 raise KarelException(
                     "Este token no parece valido, linea %d columna %d" %
                     (self.linea, self.columna))
             elif self.caracter_actual in self.simbolos:
                 self.estado = self.ESTADO_SIMBOLO
                 break
             elif self.caracter_actual in self.espacios:
                 self.estado = self.ESTADO_ESPACIO
                 break  #Terminamos este token
         elif self.estado == self.ESTADO_PALABRA:
             if self.debug:
                 print "Encontré", repr(
                     self.caracter_actual), "en estado palabra"
             if self.caracter_actual not in self.caracteres:
                 raise KarelException(
                     "Caracter desconocido en la linea %d columna %d" %
                     (self.linea, self.columna))
             if self.caracter_actual in self.palabras + self.numeros:
                 self.token += self.caracter_actual
             elif self.caracter_actual in self.simbolos:
                 self.estado = self.ESTADO_SIMBOLO
                 break
             elif self.caracter_actual in self.espacios:
                 self.estado = self.ESTADO_ESPACIO
                 break  #Terminamos este token
         elif self.estado == self.ESTADO_SIMBOLO:
             if self.debug:
                 print "Encontré", repr(
                     self.caracter_actual), "en estado símbolo"
             if self.caracter_actual not in self.caracteres:
                 raise KarelException(
                     "Caracter desconocido en la linea %d columna %d" %
                     (self.linea, self.columna))
             if self.caracter_actual == '{' and self.sintaxis == 'pascal':
                 self.abrir_comentario = '{'
                 self.estado = self.ESTADO_COMENTARIO
                 if self.token:
                     break
             elif self.caracter_actual == '#':
                 self.estado = self.ESTADO_ESPACIO
                 self.archivo.readline()  #LINEA
                 self.cambio_de_linea()
                 if self.token:
                     break
             elif self.caracter_actual in self.numeros:
                 self.estado = self.ESTADO_NUMERO
                 if self.token:
                     break
             elif self.caracter_actual in self.palabras:
                 self.estado = self.ESTADO_PALABRA
                 if self.token:
                     break
             elif self.caracter_actual in self.simbolos:  #Encontramos un símbolo en estado símbolo
                 if self.caracter_actual == '/' and self.ultimo_caracter == '/':
                     self.archivo.readline()  #LINEA
                     self.cambio_de_linea()
                     self.estado = self.ESTADO_ESPACIO
                     if self.token.endswith('/'):
                         self.token = self.token[:-1]
                     if self.token:
                         self.caracter_actual = self.lee_caracter()
                         break
                 elif self.caracter_actual == '*' and self.ultimo_caracter == '/' and self.sintaxis == 'java':
                     self.estado = self.ESTADO_COMENTARIO
                     self.abrir_comentario = '/*'
                     if self.token.endswith('/'):
                         self.token = self.token[:-1]
                     if self.token:
                         self.caracter_actual = self.lee_caracter()
                         break
                 elif self.caracter_actual == '*' and self.ultimo_caracter == '(' and self.sintaxis == 'pascal':
                     self.estado = self.ESTADO_COMENTARIO
                     self.abrir_comentario = '(*'
                     if self.token.endswith('('):
                         self.token = self.token[:-1]
                     if self.token:
                         self.caracter_actual = self.lee_caracter()
                         break
                 elif self.caracter_actual in self.lonely_chars:  #Caracteres que viven solos
                     self.estado = self.ESTADO_ESPACIO
                     if self.token:
                         break
                     self.token += self.caracter_actual
                     self.caracter_actual = self.lee_caracter()
                     break
                 else:
                     self.token += self.caracter_actual
             elif self.caracter_actual in self.espacios:
                 self.estado = self.ESTADO_ESPACIO
                 if self.token:
                     break
             else:
                 raise KarelException(
                     "Caracter desconocido en la linea %d columna %d" %
                     (self.linea, self.columna))
         self.caracter_actual = self.lee_caracter()
     token = self.token
     self.token = ''
     obj_token = ktoken(token, self.es_primer_token)
     self.es_primer_token = False
     return obj_token
Ejemplo n.º 6
0
 def step(self):
     """Da un paso en la cinta de ejecución de Karel"""
     try:
         if self.corriendo:
             if self.ejecucion >= self.limite_ejecucion:
                 raise KarelException(
                     u"HanoiTowerException: Tu programa nunca termina ¿Usaste 'apagate'?"
                 )
             #Hay que ejecutar la función en turno en el índice actual
             instruccion = self.ejecutable['lista'][self.indice]
             if type(instruccion) == dict:
                 #Se trata de una estructura de control o una funcion definida
                 if instruccion.has_key('si'):
                     if self.debug:
                         print 'si'
                     if self.termino_logico(
                             instruccion['si']['argumento']['o'],
                             self.diccionario_variables):
                         self.indice += 1  #Avanzamos a la siguiente posicion en la cinta
                     else:  #nos saltamos el si, vamos a la siguiente casilla, que debe ser un sino o la siguiente instruccion
                         self.indice = instruccion['si']['fin'] + 1
                     self.ejecucion += 1
                 elif instruccion.has_key(
                         'sino'
                 ):  #Llegamos a un sino, procedemos, no hay de otra
                     if self.debug:
                         print 'sino'
                     self.indice += 1
                     self.ejecucion += 1
                 elif instruccion.has_key('repite'):
                     if self.debug:
                         print 'repite', instruccion['repite']['argumento']
                     if not self.pila.en_tope(instruccion['repite']['id']):
                         argumento = self.expresion_entera(
                             instruccion['repite']['argumento'],
                             self.diccionario_variables)
                         if argumento < 0:
                             raise KarelException(
                                 u"WeirdNumberException: Estás intentando que karel repita un número negativo de veces"
                             )
                         self.pila.append({
                             'id':
                             instruccion['repite']['id'],
                             'cuenta':
                             0,
                             'argumento':
                             argumento,
                             'fin':
                             instruccion['repite']['fin']
                         })  #Cuenta las ejecuciones para este bucle
                     if self.pila.top()['argumento'] > 0:
                         if self.pila.top(
                         )['cuenta'] == self.limite_iteracion:
                             raise KarelException(
                                 'LoopLimitExceded: hay un bucle que se cicla'
                             )
                         self.indice += 1
                         self.pila.top()['argumento'] -= 1
                         self.pila.top()['cuenta'] += 1
                     else:  #nos vamos al final y extraemos el repite de la pila
                         self.indice = instruccion['repite']['fin'] + 1
                         self.pila.pop()
                     self.ejecucion += 1
                 elif instruccion.has_key('mientras'):
                     if self.debug:
                         print 'mientras'
                     if not self.pila.en_tope(
                             instruccion['mientras']['id']):
                         self.pila.append({
                             'id':
                             instruccion['mientras']['id'],
                             'cuenta':
                             0,
                             'fin':
                             instruccion['mientras']['fin']
                         })  #Cuenta las ejecuciones para este bucle
                     if self.termino_logico(
                             instruccion['mientras']['argumento']['o'],
                             self.diccionario_variables
                     ):  #Se cumple la condición del mientras
                         if self.pila.top(
                         )['cuenta'] == self.limite_iteracion:
                             raise KarelException(
                                 'LoopLimitExceded: hay un bucle que se cicla'
                             )
                         self.indice += 1
                         self.pila.top()['cuenta'] += 1
                     else:  #nos vamos al final
                         self.indice = instruccion['mientras']['fin'] + 1
                         self.pila.pop()
                     self.ejecucion += 1
                 elif instruccion.has_key('fin'):  #Algo termina aqui
                     if self.debug:
                         print 'fin', instruccion['fin']['estructura']
                     if instruccion['fin']['estructura'] in [
                             'mientras', 'repite'
                     ]:
                         self.indice = instruccion['fin']['inicio']
                     elif instruccion['fin']['estructura'] == 'si':
                         self.indice = instruccion['fin']['fin']
                     elif instruccion['fin']['estructura'] == 'sino':
                         self.indice += 1
                     else:  #fin de una funcion
                         nota = self.pila.pop(
                         )  #Obtenemos la nota de donde nos hemos quedado
                         self.indice = nota['posicion'] + 1
                         self.diccionario_variables = nota[
                             'diccionario_variables']
                         self.profundidad -= 1
                 else:  #Se trata la llamada a una función
                     if self.debug:
                         print instruccion['instruccion']['nombre']
                     if self.profundidad == self.limite_recursion:
                         raise KarelException(
                             'StackOverflow: Karel ha excedido el límite de recursión'
                         )
                     #Hay que guardar la posición actual y el diccionario de variables en uso
                     self.pila.append({
                         'posicion':
                         self.indice,
                         'diccionario_variables':
                         self.diccionario_variables
                     })
                     self.profundidad += 1
                     # Lo que prosigue es ir a la definición de la función
                     self.indice = self.ejecutable['indice_funciones'][
                         instruccion['instruccion']['nombre']] + 1
                     # recalcular el diccionario de variables
                     valores = []
                     for i in instruccion['instruccion']['argumento']:
                         valores.append(
                             self.expresion_entera(
                                 i, self.diccionario_variables))
                     self.diccionario_variables = merge(
                         self.ejecutable['lista'][self.indice - 1]
                         [instruccion['instruccion']['nombre']]['params'],
                         valores)
                     self.ejecucion += 1
             else:
                 #Es una instruccion predefinida de Karel
                 if self.debug:
                     print instruccion
                 if instruccion == 'avanza':
                     if not self.mundo.avanza():
                         raise KarelException(
                             'Karel se ha estrellado con una pared!')
                     self.indice += 1
                 elif instruccion == 'gira-izquierda':
                     self.mundo.gira_izquierda()
                     self.indice += 1
                 elif instruccion == 'coge-zumbador':
                     if not self.mundo.coge_zumbador():
                         raise KarelException(
                             'Karel quizo coger un zumbador pero no habia en su posicion'
                         )
                     self.indice += 1
                 elif instruccion == 'deja-zumbador':
                     if not self.mundo.deja_zumbador():
                         raise KarelException(
                             'Karel quizo dejar un zumbador pero su mochila estaba vacia'
                         )
                     self.indice += 1
                 elif instruccion == 'apagate':
                     self.corriendo = False  #Fin de la ejecución
                     self.estado = 'OK'
                     self.mensaje = 'Ejecucion terminada'
                     return 'TERMINADO'
                 elif instruccion == 'sal-de-instruccion':
                     while self.pila.top().has_key('id'):
                         self.pila.pop()  #Sacamos todos los bucles
                     nota = self.pila.pop(
                     )  #Obtenemos la nota de donde nos hemos quedado
                     self.indice = nota['posicion'] + 1
                     self.diccionario_variables = nota[
                         'diccionario_variables']
                 elif instruccion == 'sal-de-bucle':
                     bucle = self.pila.pop()
                     self.indice = bucle['fin'] + 1
                 elif instruccion == 'continua-bucle':
                     bucle = self.pila.top()
                     self.indice = bucle['fin']
                 else:  #FIN
                     raise KarelException(
                         u"HanoiTowerException: Tu programa excede el límite de ejecución ¿Usaste 'apagate'?"
                     )
                 self.ejecucion += 1
         else:
             self.estado = 'OK'
             self.mensaje = 'Ejecucion terminada'
             self.corriendo = False
             return 'TERMINADO'
     except KarelException, kre:
         self.estado = 'ERROR'
         self.mensaje = kre.args[0]
         self.corriendo = False
         return 'ERROR'
Ejemplo n.º 7
0
 def lee_token(self):
     """Lee un token del archivo"""
     while True:
         self.caracter_actual = self.lee_caracter()
         self.columna += 1
         if not self.caracter_actual:
             break
         if self.tiene_cambio_de_linea:
             self.linea += 1
             self.tiene_cambio_de_linea = False
         if self.estado == self.ESTADO_COMENTARIO:
             if self.debug:
                 print "Encontré", repr(
                     self.caracter_actual), "en estado comentario"
             if self.caracter_actual in self.simbolos:  #Lo que puede pasar es que sea basura o termine el comentario
                 if self.caracter_actual == ')' and self.abrir_comentario == '(*' and self.ultimo_caracter == '*':
                     self.estado = self.ESTADO_ESPACIO
                 if self.caracter_actual == '}' and self.abrir_comentario == '{':
                     self.estado = self.ESTADO_ESPACIO
             elif self.caracter_actual == '\n':
                 self.tiene_cambio_de_linea = True
                 self.columna = 0
         elif self.estado == self.ESTADO_ESPACIO:
             if self.debug:
                 print "Encontré", repr(
                     self.caracter_actual), "en estado espacio"
             if self.caracter_actual not in self.caracteres:
                 raise KarelException(
                     "Caracter desconocido en la linea %d columna %d" %
                     (self.linea, self.columna))
             if self.caracter_actual in self.numeros:
                 self.token += self.caracter_actual
                 self.estado = self.ESTADO_NUMERO
             elif self.caracter_actual in self.palabras:
                 self.token += self.caracter_actual
                 self.estado = self.ESTADO_PALABRA
             elif self.caracter_actual in self.simbolos:
                 self.push_char(self.caracter_actual
                                )  #Podria ser algo valido como ();,
                 self.estado = self.ESTADO_SIMBOLO
             elif self.caracter_actual == '\n':
                 self.tiene_cambio_de_linea = True
                 self.columna = 0
         elif self.estado == self.ESTADO_NUMERO:
             if self.debug:
                 print "Encontré", repr(
                     self.caracter_actual), "en estado número"
             if self.caracter_actual not in self.caracteres:
                 raise KarelException(
                     "Caracter desconocido en la linea %d columna %d" %
                     (self.linea, self.columna))
             if self.caracter_actual in self.numeros:
                 self.token += self.caracter_actual
             elif self.caracter_actual in self.palabras:  #Encontramos una letra en el estado numero, incorrecto
                 raise KarelException(
                     "Este token no parece valido, linea %d columna %d" %
                     (self.linea, self.columna))
             elif self.caracter_actual in self.simbolos:
                 self.estado = self.ESTADO_SIMBOLO
                 self.push_char(self.caracter_actual)
                 break
             elif self.caracter_actual in self.espacios:
                 if self.caracter_actual == '\n':
                     self.tiene_cambio_de_linea = True
                     self.columna = 0
                 self.estado = self.ESTADO_ESPACIO
                 break  #Terminamos este token
         elif self.estado == self.ESTADO_PALABRA:
             if self.debug:
                 print "Encontré", repr(
                     self.caracter_actual), "en estado palabra"
             if self.caracter_actual not in self.caracteres:
                 raise KarelException(
                     "Caracter desconocido en la linea %d columna %d" %
                     (self.linea, self.columna))
             if self.caracter_actual in self.palabras + self.numeros:
                 self.token += self.caracter_actual
             elif self.caracter_actual in self.simbolos:
                 self.estado = self.ESTADO_SIMBOLO
                 self.push_char(self.caracter_actual)
                 break
             elif self.caracter_actual in self.espacios:
                 if self.caracter_actual == '\n':
                     self.tiene_cambio_de_linea = True
                     self.columna = 0
                 self.estado = self.ESTADO_ESPACIO
                 break  #Terminamos este token
         elif self.estado == self.ESTADO_SIMBOLO:
             if self.debug:
                 print "Encontré", repr(
                     self.caracter_actual), "en estado símbolo"
             if self.caracter_actual not in self.caracteres:
                 raise KarelException(
                     "Caracter desconocido en la linea %d columna %d" %
                     (self.linea, self.columna))
             if self.caracter_actual == '{':
                 self.abrir_comentario = '{'
                 self.estado = self.ESTADO_COMENTARIO
             elif self.caracter_actual in self.numeros:
                 self.estado = self.ESTADO_NUMERO
                 self.push_char(self.caracter_actual)
                 break
             elif self.caracter_actual in self.palabras:
                 self.estado = self.ESTADO_PALABRA
                 self.push_char(self.caracter_actual)
                 if self.token:
                     break
             elif self.caracter_actual in self.simbolos:
                 if self.ultimo_caracter == "(" and self.caracter_actual == '*':
                     self.token = ''
                     self.estado = self.ESTADO_COMENTARIO
                     self.abrir_comentario = '(*'
                 elif self.caracter_actual != '(':  #el único símbolo con continuación
                     self.token += self.caracter_actual
                     #  self.push_char(self.caracter_actual)
                     break
                 else:
                     self.token += self.caracter_actual
             elif self.caracter_actual in self.espacios:
                 if self.caracter_actual == '\n':
                     self.tiene_cambio_de_linea = True
                     self.columna = 0
                 self.estado = self.ESTADO_ESPACIO
                 #break #Terminamos este token
     token = self.token
     self.token = ''
     return token