Prácticas de Lógica Computacional. Aquí no hay quien estudie…Lógica Curso 2006/07 Las respuestas a las preguntas de la anterior actividad son cruciales para saber cómo debemos continuar la implementación de nuestro juego. Estamos comenzando a implementar la interactividad con el jugador, lo que es el punto clave de cualquier videojuego. A partir de ahora, tendremos que esforzarnos por hacer que el programa siga las órdenes del jugador. Lo primero de todo, será dar la posibilidad de mover al alumno por el edificio. Para poder moverlo, es indispensable que el hecho de la BC que nos dice dónde está el alumno pueda cambiar. A un hecho que puede variar durante la ejecución se le llama dinámico. Por tanto, necesitamos un predicado dinámico que diga cuál es la zona donde está actualmente el alumno y que varíe cada vez que el alumno cambie de zona. Actividad 4.1: Declara como dinámico un nuevo predicado que utilizarás para almacenar en la BC la ubicación actual del alumno. Se trata de un predicado especial para el alumno que será utilizado en lugar del predicado ubicacion, que utilizan todos los demás personajes. Este nuevo predicado debe ser de aridad 1. y ¡Ojo! Los predicados dinámicos no pueden llamarse como otro predicado estático que ya exista. Si intentas declarar como dinámico un predicado que previamente había sido creado de forma estática, obtendrás el mensaje ‹‹No permission to modify static_procedure ‘predicado/aridad’›› Actividad 4.2: Realiza las siguientes pruebas desde el intérprete de PROLOG: Æ Añade dinámicamente (mediante assert/1) la nueva ubicación del alumno, diciendo que éste está en el atico. Æ Pregúntale a PROLOG dónde está el alumno (según su posición dinámica). Æ Añade otra vez dinámicamente la ubicación del alumno, diciendo que ahora está en el ‘2ºA’. Æ Vuelve a preguntarle a PROLOG dónde está el alumno. Æ Escribe listing(Pred), sustituyendo Pred por el nombre del predicado que utilizas para representar la ubicación del alumno. En vista del resultado, explica lo ocurrido anteriormente. Æ Elimina con abolish/1 la ubicación anterior del alumno y ubícalo en el ‘1ºB’ utilizando assert. Æ Ejecuta la regla empieza/0. ¿Funciona como debería? ¿Cómo la corregirías en caso de que no funcione como debería? Actividad 4.3: Ahora que has comprobado como funcionan abolish/1 y assert/1, crea una regla que sirva para cambiar la ubicacion del alumno. La regla que crees deberá ser de aridad 1 y deberá recibir como parámetro la nueva ubicacion del alumno (un átomo indicando la zona en la que hay que ubicarlo). Esta regla debe asegurar que el alumno no esté nunca en dos sitios a la vez (dos hechos del predicado de ubicacion del alumno en la BC). Cuando hayas terminado de implementar la regla y hayas comprobado que funciona, añade el código necesario al principio de la regla empieza/0 para que el alumno sea ubicado en su lugar de salida cada vez que empiece el juego. y Ahora que ya tenemos el predicado dinámico preparado para mover al alumno, tenemos que crear las acciones que permitirán moverlo. Recuerda que hemos definido anteriormente cuáles son las acciones válidas. Ahora, definiremos una regla para cada una de esas acciones Prácticas de Lógica Computacional. Aquí no hay quien estudie…Lógica Curso 2006/07 básicas de forma que, cuando el jugador solicite realizar una de esas acciones, la regla correspondiente sea ejecutada. Actividad 4.4: Implementa una regla que mueva al alumno al sur, si puede. En caso de que no pueda, deberá mostrar un mensaje indicando que no es posible el movimiento solicitado. La cabeza de la regla debe ser el nombre del comando, sin argumentos (en este caso sur/0). Para saber si el alumno puede moverse al sur, y a cuál zona llegará en caso de moverse, puedes ayudarte con el predicado lindes_zona/5 o con el predicado de la actividad 2.op.1, si la hiciste. o Nota: Aunque no es necesario, se recomienda que utilices el operador -> para implementar esta regla. Actividad 4.5: Comprueba que la implementación de la regla sur funciona como es debido con las siguientes preguntas al intérprete de PROLOG: Æ Mueve al alumno a la zona común de la segunda planta. Æ ¿Cuál es la ubicación del alumno después de moverse una vez al sur? Æ Si lo vuelvo a mover al sur, ¿Cuál es la descripción de la zona donde se encuentra? Æ Posiciona al alumno en una zona sin salida al sur, e intenta moverlo en esa dirección, ¿Qué ocurre? Si esto produce un error, ¿Cómo puedo solucionarlo? Actividad 4.6: Basándote en la regla sur/0, añade reglas para mover al personaje en las otras 3 direcciones (norte, este, oeste). Comprueba el funcionamiento de todas las reglas que implementes. Actividad 4.op.1: Añade una nueva acción válida ayuda, que servirá para mostrar la ayuda sobre el funcionamiento del juego. En la ayuda se mostrarán las acciones válidas, su significado y la forma de utilizarlas. Implementa la regla ayuda igual que has implementado las reglas de movimiento, es decir, como ayuda/0. Puedes añadir código a la regla empieza/0, si lo deseas, para que la primera vez que inicias el juego se muestre un mensaje recordándote que puedes usar el comando ayuda en cualquier momento. Prácticas de Lógica Computacional. Aquí no hay quien estudie…Lógica Curso 2006/07 Notas teóricas: Æ El operador -> tiene un funcionamiento muy similar a las estructuras condicionales clásicas de cualquier lenguaje de programación, estilo IF…THEN. Concretamente, la traducción de a->c sería IF a THEN c. Esto nos permite lanzar el objetivo c solamente cuando a se haya cumplido previamente. Además, es posible combinar esto con un disyuntor para obtener la estructura completa IF…THEN…ELSE. Esto sería a->c;e, lo que es lo mismo que (a->c);e, por la mayor prioridad del operador ->. ¡Mucho ojo con esto! Cuando tenemos la estructura completa, si el objetivo a no se cumpliera, pasaríamos directamente a evaluar e. Esto significa que las instanciaciones de variables que pudieran tener lugar en a, quedarían sin efecto al fallar a y llegaríamos a evaluar e, como si a y c no existieran. Æ En PROLOG puedes enlazar objetivos mediante conjuntores y disyuntores para simular una estructura condicional (Por ejemplo así (a,c);e). Sin embargo el operador -> tiene una ligera diferencia. Una vez se evalua a, se cumpla o no, nunca vuelve a ser evaluado. Esto quiere decir que si, por ejemplo, c o e fallasen, no se volvería a buscar ninguna otra alternativa que haga que a se cumpla. Æ ¡Ojo! Si alguna de las partes de la estructura formada con -> y ; tuviera más de 1 objetivo, será necesario utilizar paréntesis. Ejemplo: (a,b)->(c,d);(e,f). Por otra parte, si la estructura condicional está incluida en el interior de una regla y queremos que no afecte a los demás objetivos, podemos introducir toda la estructura entre paréntesis, para que funcione como si de un único objetivo se tratase. Ejemplo: b, (a->c;e),f. Æ Utilizando el operador -> habrá veces que quieras conseguir que tu regla tenga éxito aun cuando no se cumpla alguna condición. Para estos casos vendrá muy bien utilizar el objetivo true/0 tras el disyuntor. true/0 siempre tiene éxito, sin hacer nada más.