Juego Oca

FUNDAMENTOS DE INTELIGENCIA ARTIFICIAL FUNDAMENTOS DE INTELIGENCIA ARTIFICIAL - AO2 Construcción en Prolog de un Sistem

Views 133 Downloads 4 File size 2MB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

FUNDAMENTOS DE INTELIGENCIA ARTIFICIAL

FUNDAMENTOS DE INTELIGENCIA ARTIFICIAL - AO2 Construcción en Prolog de un Sistema Basado en Reglas: El juego de la Prolog-Oca. Curso 2016-2017 Nombre: Apellidos:

Javier Gago Romero

Centro Asociado:

Campo de Gibraltar-Algeciras

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

Índice 1.- Introducción ............................................................................................................................. 3 2.- Descripción del conocimiento del dominio ............................................................................. 4 3.- Descripción del programa ...................................................................................................... 12 4.- Descripción breve de la metodología de desarrollo simplificada .......................................... 20 5.- Descripción de la estructura de base de reglas y de las consideraciones de eficiencia realizadas..................................................................................................................................... 22 bhPrologOca.pl ........................................................................................................................ 22 juegoPrologOca.pl ................................................................................................................... 23 Consideraciones de eficiencia ................................................................................................. 27 6.- Código comentado en Prolog................................................................................................. 29 bhPrologOca.pl ........................................................................................................................ 29 juegoPrologOca.pl ................................................................................................................... 41 7.- Descripción de casos de pruebas necesarios ......................................................................... 74 Requisitos del sistema ............................................................................................................. 74 Pruebas para mostrar que se cumplen los requisitos ............................................................. 74 Pruebas necesarias .................................................................................................................. 83 8.- Dificultades encontradas ....................................................................................................... 85 Apéndice A: Temas propuestos para el proyecto ....................................................................... 86 Apéndice B: Versos relacionados con la historia ........................................................................ 88 Soneto a mi mente .............................................................................................................. 88 Soneto a mi rival la IA .......................................................................................................... 88 Apéndice C: Versión del software empleado .............................................................................. 90 Apéndice D: Ficheros entregados ............................................................................................... 91

Javier Gago Romero

Página 2

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

1.- Introducción El presente documento constituye mi memoria a la Actividad Obligatoria 2, de la asignatura “Fundamentos de Inteligencia Artificial”, correspondiente al curso académico 20162017. La actividad consiste en la construcción en Prolog de un SBR (Sistema Basado en Reglas) básico. El lenguaje Prolog se basa en la lógica de predicados de primer orden restringida a cláusulas de Horn para representar datos y conocimiento, y utiliza encadenamiento hacia atrás y una estrategia de reversibilidad sin información heurística conocida como backtracking. En el enunciado de la actividad, se propone al alumno que el SBR represente los hechos y reglas de un mundo virtual que podrá elegirse de un listado que podemos consultar en el Apéndice A de este mismo documento. El tema elegido, ha sido el quincuagésimo séptimo del listado, que se corresponde con “Juegos de mesa”. En particular, se ha implementado en Prolog un SBR que permite jugar partidas del clásico juego de mesa “El juego de la Oca” frente a una IA muy básica, al tratarse de un juego dominado por el azar, y de bajo componente estratégico. El juego de la Prolog-Oca, que es el nombre del proyecto, presenta el tradicional juego de la oca bajo un tablero con temática relacionada con la IA. Así, las casillas especiales han sido sustituidas por otras casillas relacionadas de alguna manera con la IA (por citar algún ejemplo, la figura de la oca, es en el juego la figura del búho naranja que caracteriza al logotipo del intérprete SWI-PROLOG, y la típica frase de “de oca a oca y tiro porque me toca…”, ha sido sustituida por “de buhito a buhito, y tiro otro poquito…”). Las casillas normales, que en diversos tableros contienen imágenes de diverso tipo, han sido sustituidas por casillas dedicadas a personas que han contribuido de algún modo en el avance de la IA (ya sea como ciencia o como ingeniería del conocimiento), escritores de ciencia ficción y personajes de ciencia ficción que aparecen en relatos, novelas, y/o cine. Con esto, se intenta rendir un pequeño homenaje a todos ellos y aportar un componente educativo al juego, ya que al jugar y caer en una de estas casillas podemos leer una breve descripción acerca del personaje, escritor o persona que ha contribuido de un modo u otro en el campo de la IA, lo que nos puede permitir llegar a aprender ciertos datos sobre quienes eran y qué los relaciona con la IA. Por otra parte, se ha intentado ir un paso más allá, presentando el juego de la oca bajo una historia que intente atrapar al usuario mediante pinceladas de poesía e intriga. Para ello, se han incluido ciertos aspectos de otro tipo de juegos de mesa: los juegos de rol. En la mayoría de los juegos de rol de mesa, básicamente hay un narrador que introduce una historia, bajo la cual los participantes en el juego asumen el rol de un personaje ficticio y participan de forma activa en el transcurso de la historia, a veces lanzando dados para determinar por azar que sucederá al aplicar una serie de reglas. En nuestro proyecto, la historia será narrada a medida que el jugador juega nuevas partidas, asumiendo el papel del protagonista de la historia, y decidiendo a veces por azar, y otras por propia iniciativa, el transcurso de la historia: puede decidir si rendirse en una partida, o tirar los dados y ver qué pasa, o consultar el tablero, o leer su diario, etcétera… Javier Gago Romero

Página 3

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

2.- Descripción del conocimiento del dominio Probablemente todos hemos jugado al juego de la oca en alguna ocasión. Es un juego sencillo, dominado fundamentalmente por el azar, donde basta con saber contar para mover la ficha por el tablero y conocer las reglas de unas cuantas figuras que aparecen en sus casillas. Con 4 años de edad ya se puede jugar a este juego, quizás como uno de los primeros juegos de mesa. La siguiente tabla, que puede consultarse en Wikipedia, ilustra algunas características generales del juego:

También puede que los más jugadores más experimentados en juegos de mesa, hayan participado alguna vez en un juego de rol de mesa. Si al jugador le ha gustado la experiencia, probablemente aprecie la diversión de una buena partida, y el contenido narrativo que transcurre en la misma. Ambos tipos de juego, aunque bastante diferentes, tienen cosas en común: se utilizan dados para determinar qué sucede, a menudo se aplican reglas diferentes o “reglas caseras” que modifican el juego en las cuales la mayoría o todos los participantes están de acuerdo, y son juegos que, de un modo u otro, se caracterizan por la emoción de qué sucederá. La siguiente imagen, muestra algunos dados, de diverso número de caras, que suelen ser usados en juegos de rol de mesa:

Javier Gago Romero

Página 4

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

He usado varias fuentes de conocimiento para realizar este SBR: 1. Mi propia experiencia como jugador en este tipo de juegos. 2. La experiencia de otros jugadores, consultándoles sobre su experiencia en diferentes juegos de mesa. 3. Recursos e información encontrados en diferentes páginas Web sobre las reglas de estos juegos, y también sobre los datos de los personajes de ficción, escritores, científicos e ingenieros a los cuales se les dedica ciertas casillas del tablero. Conviene analizar el dominio del problema en dos partes: 1. Las características propias del juego de la oca: para la aplicación de las reglas del juego en el SBR. 2. Las características propias del juego de rol de mesa: que incluye la narración de una historia y cómo interactúa el jugador en ella, mediante el lanzamiento de dados o no. El juego de la oca El juego de la oca, es un juego de reglas sencillas con un bajo nivel estratégico y un alto contenido de azar. El tablero, se compone de 63 casillas dibujando una espiral, de tal manera que la primera casilla se sitúa en la esquina inferior izquierda, y la última casilla lo hace en el centro del tablero. Cada participante tiene una ficha, un dado y un cubilete, y el objetivo es ser el primero en alcanzar la casilla de la victoria, o casilla final para ganar así la partida. Hay diversas variantes en el juego, que van desde el tipo de tablero (existen tableros muy diferentes y variados), hasta la aplicación de reglas diferentes (por ejemplo, algunas personas aplican la regla de que al caer en una casilla de laberinto retroceden hasta la casilla 30, y otras aplican la regla de que al caer en la casilla de laberinto no se puede salir de ella hasta obtener una determinada puntuación en los dados, por ejemplo 6). Cada casilla, posee una imagen, junto con la numeración de la misma. Las imágenes suelen ser de lo más variadas, y hay multitud de tableros diferentes, tanto a lo largo de la historia del juego, como coexistiendo simultáneamente. Las imágenes particulares que se emplean para las casillas no influyen en las reglas del juego en sí mismas, siempre y cuando se respete la semántica de las casillas y su ubicación. Las siguientes imágenes, muestran dos tableros de la oca reales:

Javier Gago Romero

Página 5

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

Puede observarse que ni siquiera las ocas están dibujadas de la misma forma, pero se respeta que haya una misma figura que simbolice las reglas de una oca del tablero clásico, en las mismas posiciones, y lo mismo para el resto de figuras que representan las otras casillas especiales del juego (puente, posada, pozo…). La mayoría de estas casillas especiales tienen asociada una frase popular, de tal manera que el jugador al caer en la casilla dice la frase, conocida por el resto de jugadores, y ejecuta la acción de esa casilla. El ejemplo más típico, es caer en una casilla de oca, decir "de oca a oca y tiro porque me toca", desplazar la ficha hasta la siguiente oca y volver a lanzar los dados sin ceder el turno aún a otro jugador. A veces es común encontrar el clásico juego de la oca bajo la perspectiva de otra temática, por ejemplo, en juegos de la oca orientados a los niños, se suele utilizar la figura de alguno de sus personajes de dibujos animados preferido en sustitución de la figura de la oca, pero manteniendo las mismas reglas. Las siguientes imágenes, muestran dos tableros reales en los cuales se da esta situación:

Javier Gago Romero

Página 6

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

En nuestro proyecto, la temática del tablero es la IA, por lo que se ha procedido a sustituir las figuras clásicas, como ocurre en los dos últimos tableros que hemos visto, por figuras relacionadas con el lenguaje de programación Prolog. Así, en nuestro juego, la correspondencia es: Figura juego clásico Oca Puente

Posada Dados

Pozo Laberinto Cárcel Calavera Oca de la victoria

Frase típica Figura Prolog-Oca “de oca a oca y tiro Buhito porque me toca”. “de puente a puente, Predicado y tiro porque me lleva la corriente”. Error Lógico "de dado a dado y tiro Corte (!) porque me ha tocado" o bien "de dados a dados y tiro porque son cuadrados". Rama Infinita "del laberinto al 30". Recursión

Frase típica “de buhito a buhito, y tiro otro poquito...”. “de predicado a predicado, y tiro según se ha determinado...”. "de corte en corte y tiro como un resorte...".

"de la recursión al 30".

Error Sintáctico Retract Buhito de la victoria

En las siguientes imágenes, de izquierda a derecha, podemos ver una oca en el juego tradicional, el icono del búho naranja del intérprete SWI-PROLOG y nuestro buhito representado en ASCII. Se ha elegido el búho naranja del intérprete en sustitución de la oca, por ser un símbolo relacionado comúnmente con el lenguaje de programación Prolog y a la vez, al igual que la oca, un ave.

Las casillas especiales llevan aparejadas las siguientes reglas:

La oca: se encuentran normalmente ubicadas cada nueve casillas desde las casillas 5 y 9. Cuando se cae en una de estas casillas, se avanza hasta la siguiente oca y se vuelve a tirar. Tradicionalmente se dice "de oca a oca y tiro porque me toca" (o "de oca en oca y tiro porque me toca"). Es la figura principal, la que más se repite, y la que da nombre al juego. En ciertas versiones también hay que fijarse en los picos de las ocas, si están hacia delante, hay que seguir hacia adelante, pero si el pico está hacia atrás, hay que retroceder. O puedes quedarte en el sitio que estás si la casilla tiene un número impar. Dependiendo de la versión, la casilla 1, es a veces considerada una oca, y en otras no. En el juego de la Prolog-Oca, no hemos considera la casilla número 1 como una oca, ya que en Javier Gago Romero

Página 7

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

el tablero están distribuidas siguiendo una secuencia de distancias entre ocas de 5-4-5-4-5-4..., y así sucesivamente hasta llegar al final del tablero. Para mantener esta secuencia también desde el principio del tablero, la primera oca debería estar a distancia 5, y no 4 (como ocurriría del 1 al 5), por lo que hemos decidido no considerar finalmente la casilla 1 como una casilla de oca. Respecto a la casilla inicial, en algunas variantes se parte de que los jugadores están ubicados en la casilla 1, y en otros, se sitúan a la izquierda de la casilla 1 (que puede considerarse como una casilla 0), de tal manera que con un 1 en la primera tirada, nos situamos en la casilla 1. En el juego de la Prolog-Oca, hemos considerado esta segunda opción.

El puente: se encuentran normalmente ubicados en las casillas 6 y 12. Cuando se cae en una de estas casillas, se avanza o retrocede hasta el otro puente y se vuelve a tirar. Tradicionalmente se dice "de puente a puente y tiro porque me lleva la corriente". Existen variantes del juego donde desde el puente se desplaza a la posada, y el participante pierde algunos turnos siguientes. En nuestro proyecto hemos considerado la primera opción.

La posada: se encuentra normalmente ubicada en la casilla 19. Cuando se cae en esta casilla, suelen perderse 2 turnos. En algunas ocasiones dependiendo de cuántos días aparezcan escritos en el dibujo. En nuestro proyecto, el número de turnos que se pierden es 2.

El pozo: Se encuentra normalmente ubicado en la casilla 31. Cuando se cae en esta casilla, suelen o bien perderse 2 turnos o bien permanecer el jugador sin jugar hasta que otro caiga en su lugar. Y si están jugando sólo dos personas y el otro jugador cae en la calavera y empieza del principio, el castigo de estar sin jugar se invalida y se sigue jugando normal, saliendo del pozo en cuanto te toque tirar. En nuestro proyecto, hemos considerado que al caer en esta casilla se pierden 2 turnos.

Los dados: Se encuentran normalmente ubicados en las casillas 26 y 53. Cuando se cae en una de estas dos casillas, se suman las cifras que aparezcan en la casilla y se avanza ese número de casillas. Existen otras versiones en las que se avanza o se retrocede a la otra con el mismo dibujo y se vuelve a tirar diciendo "De dado a dado y tiro porque me ha tocado", "De dados a dados y tiro porque son cuadrados" o "De dados a dados y tiro por los soldados" en las que simplemente se vuelve a tirar. También existe la regla de que cayendo en los dados de la casilla 26, si en la siguiente tirada saca un 3 en el dado, pasa el jugador a la 53, "en los dados, con un tres, paso a la cincuenta y tres". Como puede verse, hay distintas y muy variadas reglas para esta casilla. En nuestro juego, al caer en una casilla de dados, nos desplazamos hasta la otra, y volvemos a tirar.

Javier Gago Romero

Página 8

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

El laberinto: ubicado en la casilla 42, cuando se cae en el laberinto, se está obligado a retroceder a la casilla 30. Se suele decir: "Del laberinto al 30". En otras versiones, se queda atrapado y no se puede seguir avanzando hasta sacar un determinado número con los dados. En nuestro proyecto, se ha optado por la primera opción.

La cárcel: ubicada en la casilla 52, cuando se cae en la cárcel, suelen perderse 3 turnos. Otra opción es que si se cae en la cárcel, la ficha queda inmovilizada hasta que otro jugador caiga y te rescate, quedando éste atrapado. En nuestro proyecto, se ha optado por la primera opción. La calavera o la muerte: ubicada en la casilla 58, cuando se cae en la calavera o muerte, se vuelve a empezar desde la casilla de inicio. En nuestro proyecto ocurre exactamente eso cuando caemos en esta casilla.

Última casilla: usualmente el juego tiene 63 casillas y se debe llegar a la última con el puntaje exacto, de lo contrario se retrocede tantas casillas como puntos sobren. En nuestro proyecto, esa es la misma regla que se aplica. Las casillas normales, han sido dedicadas a personajes y escritores de ciencia ficción, así como a científicos e ingenieros que guardan relación con la IA. Por un lado pretende rendir un pequeño homenaje, y por otro aportar valor educativo a las partidas que se jueguen. Una breve descripción al caer en una de estas casillas, permite leer datos básicos sobre ellos y a veces, de qué manera han contribuido o se relacionan con la IA. Un ejemplo, es el de la casilla 1, dedicada a Isaac Asimov:

La emoción del juego, ha intentado trasladarse al juego de la Prolog-Oca mediante una buena cantidad de descripciones de los lanzamientos de dados, para añadir mayor dramatismo a la partida, y reflejar la espiral de emociones en la que pueden llegar a verse inmersos los participantes durante la partida. Un ejemplo de estas descripciones es el siguiente:

El juego de la oca transcurre básicamente de la siguiente forma:

Javier Gago Romero

Página 9

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

Al inicio de una partida, cada participante lanza un dado de seis caras para decidir quién comienza. En caso de igualdad, repiten esta operación, hasta que se produce un desempate.

Tras esto, partiendo desde la casilla inicial, cada jugador lanza un dado en su turno (comenzando por el jugador que se determinó saliera en primer lugar) y avanza con su ficha las casillas indicadas en la puntuación obtenida hasta caer en una casilla (en algunas versiones del juego de la oca, incluso se lanzan dos dados en lugar de uno, con excepción de las tiradas que están cercanas al final del tablero, donde el jugador sólo lanza un dado). Dependiendo de la casilla en la que caiga el jugador, se producirá una determinada acción. En casillas normales, simplemente el jugador cede su turno al siguiente jugador, sin que ocurra nada más trascendente. En casillas especiales, se aplican determinadas reglas, como hemos detallado anteriormente, por ejemplo no poder tirar en los siguientes turnos, o avanzar o retroceder hasta otras casillas. La casilla de victoria, que es la última casilla, es una casilla muy especial, ya que el jugador que caiga en ella gana la partida, pero además contiene la peculiaridad de que hay que caer en ella con la puntuación exacta. De no ser así, se produce un efecto de rebote, y al desplazarse, el jugador retrocede. Por ejemplo, si el jugador está en la casilla 62 y obtiene un tres en los dados, contaría así: 63, 62, 61 y acabaría en la casilla 61 debido al rebote. Juego de rol de mesa En los juegos de rol de mesa a los que hacemos referencia en este documento, podemos encontrar la figura de un narrador o director del juego que narra una historia en la que se ven involucrados los jugadores. Cada jugador, asume el rol de un personaje ficticio, y a veces, es necesario lanzar los dados y aplicar una serie de reglas para decidir qué sucederá. El juego de la Prolog-Oca incluye características que permiten también enfocarlo desde la perspectiva de un básico juego de rol de mesa. El jugador, asume el rol de un estudiante de la UNED, en el curso 2016-2017, que está intentando realizar la actividad obligatoria 2, y por extrañas razones, cae dormido y al despertar sufre amnesia global y no recuerda ni siquiera su propio nombre. A partir de ese contexto, el jugador participa en la historia jugando partidas al juego de la oca, y decidiendo si desea abandonar el juego, consultar su diario, jugar una partida más, etcétera… Se ha procurado dar importancia al hecho de que el jugador se sienta verdaderamente como el alumno protagonista de la historia, por encima incluso de la relevancia de las decisiones que el jugador tome.

Javier Gago Romero

Página 10

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

Al iniciar el programa, se introduce la historia mediante la narración de los hechos que tienen lugar en la misma, y se ofrecen diferentes representaciones ASCII para intentar que el jugador se interese por la historia, y se muestre intrigado por el desenlace de la misma. En la siguiente imagen, se muestra en ASCII cómo el alumno consulta en el curso virtual, el foro de la asignatura Fundamentos de Inteligencia Artificial, para poder hacer la actividad obligatoria 2:

El jugador también decide qué sucede mediante la tirada de dados, en este caso, a través de las tiradas que tienen lugar en el juego de la oca, y también, de manera transparente para el jugador, se realizan tiradas para otros sucesos, como el azar que determina si el jugador se va recuperando de la amnesia o no. Ésta última tirada de dados, puede corresponderse en un juego de rol de mesa, con las tiradas que realiza el narrador o director de juego, sin que el jugador pueda verlas (tras la pantalla de director de juego). En el menú principal del programa, se ha incluido la posibilidad de volver a leer de nuevo el inicio de la historia, así como un diario, donde el alumno apunta ideas y sucesos que ocurren durante el juego. El objetivo del diario, es simplemente acercar más al jugador al papel del alumno, dar mayor riqueza a la historia y aportar sentido poético al desarrollo del programa. Incluso, en algunas ocasiones, es posible que el alumno incluya algunos versos como entrada a su diario.

Javier Gago Romero

Página 11

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

3.- Descripción del programa Para jugar al juego de la Prolog-Oca, hemos de cargar el fichero "juegoPrologOca.pl" en nuestro intérprete de Prolog. El fichero, consulta automáticamente la base de hechos implementada en el fichero "bhPrologOca.pl", siendo necesario que los dos ficheros estén ubicados en el mismo directorio. Una vez cargado el fichero, se muestra un mensaje en pantalla al usuario, indicándole como puede iniciar el programa.

Esto es útil, principalmente para la primera vez que se ejecuta el programa, ya que el usuario puede saber cómo iniciarlo sin necesidad de tener que consultar el código fuente o un manual. Para iniciar el programa, como hemos podido ver, hay que consultar en Prolog el predicado inicio. Hecho esto, el programa se inicia con una introducción que nos pone en el contexto de nuestro personaje:

Javier Gago Romero

Página 12

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

Tras la introducción, el programa nos muestra el menú principal:

Javier Gago Romero

Página 13

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

La opción 1, permite iniciar una nueva partida al juego de la oca, y será la última que analicemos, ya que requiere de una mayor explicación. La opción 2, permite consultar estadísticas sobre las partidas jugadas, y ganadas por el usuario o por la IA:

La opción 3, nos muestra las reglas del juego de la Prolog-Oca:

La opción 4, muestra la historia y algunas curiosidades del juego de la oca tradicional:

La opción 5, leer diario, nos lleva hasta otro menú, el menú del diario: Javier Gago Romero

Página 14

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

Desde ahí, podemos consultar las diferentes entradas del diario del jugador. Este diario es redactado por el jugador para intentar recuperarse de la amnesia:

Desde la opción 6 del menú principal, podemos leer de nuevo la introducción del juego, que ya vimos al iniciar el programa. La opción 7, simplemente nos muestra información acerca del programa:

Desde la opción 0, salimos del programa. Al salir del programa, se vuelven a poner a cero el número de partidas ganadas por los diferentes participantes, se restablece la amnesia del jugador, los nombres de los participantes, el estado del diario, etcétera... es decir, se deja el juego en el mismo estado que antes de iniciar el programa. Una frase de salida se muestra al usuario como despedida, siendo esta distinta en función de los objetivos que haya logrado en el juego:

Javier Gago Romero

Página 15

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

Cuando hacemos uso de la opción 1, para iniciar una nueva partida, comenzamos el juego de la oca en sí mismo:

En primer lugar, se decide el participante que comenzará jugando:

En caso de empate en la tirada, como se muestra en la captura anterior, se procede a repetir el lanzamiento:

Cada participante interactúa durante su turno. La IA, es muy básica, por tratarse de un juego sin apenas componente estratégico. En este caso, simplemente si la IA puede lanzar el dado porque no esté penalizada por una regla anterior, entonces lanza el dado. En ningún caso, decide rendirse. Si el juego hubiera requerido plantear algún tipo de estrategia para alcanzar la victoria, habría que realizar un análisis de la estrategia ganadora que la IA debe plantear. Sin embargo, el hecho de esta simplificación, es perfecto para la implementación completa de un Javier Gago Romero

Página 16

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

juego de mesa real, sin complicar en exceso el desarrollo de un SBR básico, como se pretende según el enunciado de la práctica. Cuando es el turno del jugador humano, éste puede interactuar en el juego mediante el siguiente menú:

Si se elige la opción 1, se procede con el lanzamiento del dado:

Como se ve en la imagen, se muestra antes de la tirada, una descripción del lanzamiento, y la casilla en la cual el jugador está actualmente. Una vez pulsa INTRO, la tirada sucede, dibujándose el dado en pantalla, y mostrando la nueva casilla alcanzada. A continuación, se aplican las reglas de la nueva casilla en la que el jugador se ha posicionado. En el ejemplo, la casilla 2 es una casilla normal, y está dedicada al escritor y novelista Philip K. Dick, como puede verse por la descripción de la misma. Si se elige la opción 2, ver tablero, podemos visualizar el tablero en el momento actual, ver donde están las casillas especiales, y las fichas de los jugadores. Las siguientes imágenes comparan un tablero de la oca real, con el tablero representado en modo texto en nuestro proyecto:

Javier Gago Romero

Página 17

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

La opción de rendirse del menú, simplemente finaliza la partida dando la victoria al contrincante:

Otro aspecto interesante, es como el jugador puede recuperarse de su amnesia. Este punto, es una característica de la perspectiva como juego de rol de mesa. Para recuperarse de la amnesia, el jugador debe ganar una partida al juego de la oca, y obtener un 5 o un 6 en una tirada de dados que no se visualiza, para determinar si en esta ocasión se produce o no la circunstancia de recuperar parte de la memoria. Es decir, hay 2/6 = 1/3 de probabilidad de que se recupere parte de la memoria tras ganar una partida. Si el jugador tiene amnesia global y recupera parte de la memoria, pasará a tener amnesia retrógrada. En este punto, el jugador es capaz de recordar su nombre:

Javier Gago Romero

Página 18

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

A partir de ese momento, se identificará al jugador humano por su propio nombre. Si el jugador tiene amnesia retrógrada y recupera parte de la memoria, pasará a tener amnesia curada, y recordará todo lo sucedido desde ese momento. Aún así, cumplido este objetivo, el jugador puede plantearse ser capaz de ganar más partidas que la IA antes de abandonar el programa:

Se entiende, que el jugador ha completado completamente el juego de la Prolog-Oca si abandona el juego con más victorias que la IA, y curando completamente su amnesia:

Javier Gago Romero

Página 19

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

4.- Descripción breve de la metodología de desarrollo simplificada El trabajo se ha realizado de manera individual. Para ello, tras leer el enunciado de la práctica, se ha procedido con una lectura detenida del capítulo 19 del texto base de la asignatura, titulado "Ingeniería del Conocimiento". Podemos distinguir las siguientes fases durante el desarrollo, acorde a las indicadas en dicho capítulo: Identificación del problema: El primer paso ha sido elegir un tema sobre el que realizar el trabajo. Tras elegir el tema "juegos de mesa", principalmente porque me gustan estos juegos, he intentado imaginar una situación en que un juego de mesa pueda relacionarse con la IA y pueda ser divertido y a la vez tener alguna característica educativa. El juego de la oca es lo suficientemente básico como para permitir implementar un juego de mesa real en su totalidad en un SBR básico, como es el que se pretende con el proyecto, y con una IA que pueda jugar como un buen jugador humano. El problema es adecuado para ser tratado como SBC, no sólo por ofrecer al usuario la posibilidad de jugar muchas partidas al juego de manera sencilla y virtual, sino también por las posibilidades que se ofrecen al tener modeladas las reglas de un juego de mesa real. Podríamos extender el SBR en un futuro y hacernos preguntas del tipo, ¿qué sucedería si añadiéramos una nueva “regla casera” de ciertas características o cambiáramos la distribución de algunas casillas especiales? ¿se incrementaría o disminuiría el tiempo medio de las partidas? ¿y si jugáramos con dados donde la cara de una determinada puntuación como por ejemplo la del número 3, estuviera cargada? Quizás estemos interesados en comercializar una nueva y original variante del juego de la oca, tras encuestar a diferentes jugadores experimentados, que ven algunas carencias en el juego tradicional, como por ejemplo, que las partidas suelen durar poco, o que el juego puede llegar a hacerse repetitivo y monótono. ¿Tendrá aceptación la variante? El SBR podría ayudarnos a tener ideas para responder a la pregunta anterior. Tener las reglas implementadas, permitiría simular rápidamente cientos de miles de partidas y analizar cómo afectan nuestras nuevas reglas en el transcurso de las mismas. Incluso puede hacerse que los jugadores expertos prueben a usar el juego con las nuevas reglas antes de que comercialicemos el juego, con el ahorro que esto supone. O quizás estamos interesados en las apuestas, y estamos interesados en saber qué posibilidades en términos probabilísticos tenemos de obtener beneficio apostando por ciertas condiciones que sucederán en la partida: que el jugador que gana el juego no cae en el pozo nunca, o que el jugador que gana la partida, no lo hace en menos de 16 turnos. Hay muchas posibilidades que imaginar y que pueden explotarse. La simulación de esos cientos de miles de partidas permite extraer conclusiones que pueden ser muy útiles en muchísimo menos tiempo que jugando realmente al juego en un tablero real, y automatizando la obtención de todos esos datos de nuestro interés, sin más que añadir las reglas apropiadas al SBR. Adquisición de conocimientos: partiendo de la base de mi propia experiencia en este tipo de juegos, se ha buscado información detallada en la Web (Wikipedia y blogs dedicados al juego de la oca), especialmente sobre la historia, detalles de las reglas y diferentes variantes del juego. También información sobre ingenieros, científicos,

Javier Gago Romero

Página 20

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

personajes ficticios y escritores que se relacionan de algún modo con la IA o la ciencia ficción, para poder dedicarle a modo de homenaje alguna casilla del tablero. Conceptualización: en esta fase, la idea se fue desarrollando, esbozándola en papel, hasta tener claro qué es lo que se pretende representar, con independencia de la implementación. Básicamente, fueron ideas anotadas en papel, que describían mediante lenguaje natural estructurado en qué consiste el juego de la Prolog-Oca. Formalización: se escribió un breve pseudocódigo, que expresara las reglas del juego de la oca antes de proceder a implementarlo. Implementación del sistema: se ha procedido a intentar separar lo máximo posible la base de hechos de la base de conocimiento. Pese a que en el lenguaje de programación Prolog, la base de conocimiento se compone de hechos y reglas, la separación se ha realizado pasando a codificar los hechos (predicados sin reglas) en un fichero (bhPrologOca.pl), y los predicados con reglas en otro fichero (juegoPrologOca.pl), de tal manera que la base de conocimiento carga el fichero con los hechos en primer lugar, y actualizará esta base de hechos en los casos necesarios, como se verá para los predicados que son dinámicos. Se ha construido en primer lugar los hechos del juego, como pueden ser la lista de casillas que son una oca, y el orden en el que aparecen en el tablero, lo que se ha representado mediante un predicado con una lista donde cada elemento es el número de casilla. Así, se han incluido los hechos relevantes sobre el juego. Posteriormente, he desarrollado las reglas del juego: tirada de dados, cambios de turnos entre jugadores, acciones de las diferentes casillas, etcétera… en este punto ha sido necesario construir los primeros menús para que el usuario pueda interactuar con el juego. Una vez dispuse de una versión rudimentaria del juego de la oca tradicional, pero que tras probarse en diferentes partidas, respetaba las reglas del juego, se ha procedido a añadir un mayor grado de detalle mediante el desarrollo de nuevas reglas para mejorar el programa, como por ejemplo una representación gráfica para consultar el tablero, una representación gráfica de la tirada obtenida en los dados de tal manera que se dibuje el dado con la puntuación obtenida, etcétera… Luego, se ha desarrollado la parte poética del programa, que ha consistido en crear listas en la base de hechos con muchas opciones posibles que pueden tener lugar para diversos sucesos, introducir el programa narrando la historia, incluir la idea de disponer de un diario donde el jugador pueda ir consultando las ideas y sucesos del personaje para el cual asume el rol, así como las descripciones y frases asociadas a todas las casillas que componen nuestro tablero de juego. Para que el programa estuviera lo más completo posible, se decidió incluir una opción para consultar historias y curiosidades sobre el juego de la oca, y una opción de Acerca De, para mostrar información del programa. Evaluación: finalmente, se ha sometido el programa a diversas pruebas, tanto de consultas de predicados concretos, como a jugar muchas partidas, para comprobar que no se producen errores y el programa se comporta como se espera.

Javier Gago Romero

Página 21

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

5.- Descripción de la estructura de base de reglas y de las consideraciones de eficiencia realizadas El programa se estructura en reglas que han sido escritas cercanas unas a otras en el código en base a su funcionalidad. Cuando nos desplazamos a través del código, podemos ver que se ha incluido una cabecera de comentario para diferenciar los predicados y reglas dedicados a funcionalidades que guardan cierta relación: por ejemplo, predicados dedicados al diario están cerca entre sí, por otra parte están los que se dedican a representaciones gráficas (en ASCII), etcétera… También están separados los hechos de las reglas en dos ficheros separados. Cada predicado individual va acompañado de un comentario que indica su funcionalidad. Vamos a analizar la estructura de los dos ficheros que componen el código, y finalmente haremos mención de las consideraciones de eficiencia realizadas.

bhPrologOca.pl Contiene los hechos que componen la base de hechos. Podemos establecer en él la siguiente estructura. • •



Participantes del juego o participante/1: define los participantes del juego. Casillas especiales o tipo_casilla_especial/1: define los tipos de casillas especiales del juego. o puentes/1: define la lista de casillas que simbolizan un puente. Dada la característica de esta casilla en la cual la acción es avanzar o retroceder hasta el siguiente puente, es importante el orden en el cual las casillas aparecen en la lista. o posadas/1: define la lista de casillas que simbolizan una posada. o dadoss/1: define la lista de casillas que simbolizan dados. Dada la característica de esta casilla en la cual la acción es avanzar o retroceder hasta la siguiente casilla de dados, es importante el orden en el cual las casillas aparecen en la lista. o pozos/1: define la lista de casillas que simbolizan pozos. o laberintos/1: define la lista de casillas que simbolizan laberintos. o carceles/1: define la lista de casillas que simbolizan cárceles. o calaveras/1: define la lista de casillas que simbolizan calaveras. o ocas/1: define la lista de casillas que simbolizan ocas. Dada la característica de esta casilla en la cual la acción es avanzar o retroceder hasta la siguiente oca, es importante el orden en el cual las casillas aparecen en la lista. o victorias/1: define la lista de casillas que simbolizan una casilla de victoria. Estado del juego o posición/2: define la posición en la cual se encuentra un participante. El participante se especifica en el primer argumento, y la posición en el segundo. Este predicado es dinámico.

Javier Gago Romero

Página 22

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

sin_tirar/2: define el número de turnos que un participante no puede tirar los dados. El participante se especifica en el primer argumento, y el número de turnos que debe seguir sin tirar dados en el segundo. Este predicado es dinámico. o victorias/2: define el número de victorias que un participante lleva desde que inició el juego. El participante se especifica en el primer argumento, y el número de victorias en el segundo. Este predicado es dinámico. o amnesia/2: define el tipo de amnesia que sufre un participante en el juego. El participante se especifica en el primer argumento, y el tipo de amnesia en el segundo. Este predicado es dinámico. o nombre/2: define el nombre por el que se conoce a un participante en el juego. El participante se especifica en el primer argumento, y su nombre en el segundo. Este predicado es dinámico o diario/2: define el diario de un participante. El participante se especifica en el primer argumento, y la lista que compone su diario, en el segundo. Este predicado es dinámico. Amnesia o amnesia/1: define los tipos de amnesia que hay presentes en el juego. Listas con descripciones y mensajes posibles o descripciones_lanzamientos_dado/1: define una lista que contiene todas las descripciones posibles para un lanzamiento de dado. o nombres_proyecto/1: define una lista que contiene todos los nombres posibles que pueden haberse dado al proyecto IA. o entradas/2: define la lista de entradas que pueden añadirse al diario cuando un participante gana una partida. El participante que ganó la partida y motivó la entrada en el diario se especifica en el primer argumento, y la lista con las entradas posibles, en el segundo. o

• •

juegoPrologOca.pl Contiene la base de conocimientos con las reglas del programa. Podemos establecer en él la siguiente estructura: •

• • •

Predicados dinámicos o Reglas del tipo :- dynamic para declarar qué predicados son dinámicos (posición/2, sin_tirar/2, victorias/2, amnesia/2, nombre/2, diario/2). Carga del programa o Contiene reglas que son ejecutadas siempre, y al inicio de la carga del fichero. Inicio del programa o inicio /0: predicado que inicia el programa. Salir del programa o salir/0: predicado que sale del programa. Al salir del programa, todos los predicados dinámicos vuelven al valor que tenían por defecto antes de la ejecución, es decir, se borran sus entradas actuales en la base de hechos y se vuelven a añadir con los valores iniciales. o escribir_frase_salida/0: escribe en pantalla una frase de salida del programa, en función de lo que se ha conseguido durante el juego.

Javier Gago Romero

Página 23

FIA

Fundamentos de Inteligencia Artificial - AO2

• •







Curso 2016-2017

Esperar a que el usuario pulse intro o esperar_intro/0: permite esperar a que el usuario pulse INTRO. Nombres de participantes o escribir_nombre/1: escribe en pantalla el nombre de un participante. El participante se especifica en el primer argumento. o nombre_proyecto/1: elige un nombre aleatorio para el proyecto, y es devuelto en el primer argumento. Casillas o casilla/1: especifica si un número está en el intervalo de casilla (entre 0 y 63 incluidos). La casilla cero, se considera como la situación en la que el jugador está “fuera de tablero”, a la espera de iniciar su recorrido por el mismo. o puente/1: especifica si el número indicado se corresponde con la numeración de una casilla que simbolice un puente. o posada/1: especifica si el número indicado se corresponde con la numeración de una casilla que simbolice una posada. o dados/1: especifica si el número indicado se corresponde con la numeración de una casilla que simbolicen dados. o pozo/1: especifica si el número indicado se corresponde con la numeración de una casilla que simbolice un pozo. o laberinto/1: especifica si el número indicado se corresponde con la numeración de una casilla que simbolice un laberinto. o carcel/1: especifica si el número indicado se corresponde con la numeración de una casilla que simbolice una cárcel. o calavera/1: especifica si el número indicado se corresponde con la numeración de una casilla que simbolice una calavera. o oca/1: especifica si el número indicado se corresponde con la numeración de una casilla que simbolice una oca. o victoria/1: especifica si el número indicado se corresponde con la numeración de una casilla de victoria. o casilla_especial/1: especifica si el número indicado es una casilla especial. o casila_normal/1: especifica si el número indicado es una casilla normal, esto es, es una casilla, y no es una casilla especial. Predicados relacionados con una nueva partida o nueva_partida/0: inicia una nueva partida al juego de la oca. o comenzar_partida/1: comienza una nueva partida al juego de la oca, comenzando por el participante que se especifica mediante argumento. o determinar_participante_inicial/0: predicado encargado de disparar el proceso de determinar un participante inicial. Una vez es determinado, la partida comienza. o comparar_tiradas_iniciales/3: se compara las tiradas iniciales de los dos participantes y el participante que debe comenzar la partida en base a dicha comparación, se especifica en el tercer argumento. Si en la comparación no puede determinarse que participante debe comenzar la partida, por existir igualdad, entonces el predicado devuelve falso. Predicados relacionados con turnos, tiradas de dados, y finalizar una partida o turno/1: inicia el turno del participante especificado mediante argumento.

Javier Gago Romero

Página 24

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

cambio_turno/1: cambia el turno de un participante a otro. El participante que se indica en el primer argumento es el que debe ceder el turno al otro. o tirada/1: simula una tirada de un dado de seis caras equilibrado. El valor de la tirada es especificado en el primer argumento. o descripcion_lanzamiento_dado/1: selecciona al azar la descripción de un lanzamiento y es especificada en el primer argumento. o lanzar_dado/1: realiza el lanzamiento de un dado por el participante especificado como primer argumento. o interactuar/1: permite que el participante indicado mediante el primer argumento pueda interactuar en su turno (decidir si lanzar el dado, ver el tablero o rendirse). o gana/1: hace que el participante especificado en el primer argumento gane la partida. o rendirse/1: hace que el participante especificado en el primer argumento se rinda, haciendo así que el rival gane. o finalizar_partida/1: finaliza una partida, teniendo en cuenta que el participante que ha ganado se especifica en el primer argumento. Finalizar una partida implica restablecer una serie de hechos dinámicos, como por ejemplo la posición de los participantes en el tablero, y contabilizar la victoria para el participante que ganó la partida. Posición de un participante en el tablero o mover_a_posicion/2: mueve al participante especificado en el primer argumento, a la casilla especificada en el segundo. o actualizar_posicion/2: actualiza la posición del participante especificado en el primer argumento en base al valor de la tirada especificado en el segundo argumento. o correccion_rebote/2: en caso de que no se produzca rebote para la casilla especificada en el primer argumento, entonces se devuelve en el segundo argumento la misma casilla. Si se produce rebote, entonces en la segunda casilla se ofrece el valor corregido de la casilla donde debe situarse el participante tras tener en cuenta el rebote. Por ejemplo, ?- corrección(64, X). debe devolver X=62, ya que se sobrepasó en 1 el valor 63 de la última casilla y se cuenta una casilla hacia atrás en el rebote. Acciones de un participante en función de la casilla en la que cae o accion/2: para el participante especificado en el primer argumento, da lugar a la acción que debe tener lugar si cae en la casilla especificada en el segundo argumento. o accion_oca/2: para el participante especificado en el primer argumento, da lugar a la acción que debe tener lugar si cae en la casilla especificada en el segundo argumento. o accion_laberinto/1: para el participante especificado en el primer argumento, da lugar a la acción que debe tener lugar si cae en una casilla de laberinto. o accion_posada/1: para el participante especificado en el primer argumento, da lugar a la acción que debe tener lugar si cae en una casilla de posada. o accion_pozo/1: para el participante especificado en el primer argumento, da lugar a la acción que debe tener lugar si cae en una casilla de pozo. o accion_carcel/1: para el participante especificado en el primer argumento, da lugar a la acción que debe tener lugar si cae en una casilla de cárcel. o





Javier Gago Romero

Página 25

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

accion_dados/2: para el participante especificado en el primer argumento, da lugar a la acción que debe tener lugar si cae en la casilla especificada en el segundo argumento. o accion_puente/2: para el participante especificado en el primer argumento, da lugar a la acción que debe tener lugar si cae en la casilla especificada en el segundo argumento. o accion_calavera/1: para el participante especificado en el primer argumento, da lugar a la acción que debe tener lugar si cae en una casilla de calavera. Frases asociadas a las casillas o frase/1: escribe en pantalla la frase o descripción que tiene lugar cuando un participante cae en la casilla indicada como primer argumento. Amnesia del jugador o comprobar_amnesia/1: este predicado siempre es cierto. Sin embargo, dependiendo del participante para el que se compruebe la amnesia y de ciertas condiciones, como por ejemplo del resultado de una tirada aleatoria, el participante especificado en el primer argumento puede recuperar parte de su amnesia o no. Diario del jugador o insertar_entrada_diario/3: inserta el elemento especificado en el primer argumento en la lista especificada en el segundo argumento. El resultado es indicado en el tercer argumento. El objetivo de este predicado es insertar entradas en el diario. o actualizar_diario/2: actualiza el diario del participante indicado como primer argumento, con la entrada indicada en el segundo argumento. o escribir_diario/2: predicado que es siempre cierto. No obstante, dependiendo del tipo de amnesia del participante indicado en el primer argumento, y del participante que ganara la partida, indicado como segundo argumento, procede a escribir en el diario o no. Menús de usuario o menu_turno/1: muestra el menú con acciones en un turno, para el participante indicado como primer argumento. o menu_turno/2: para el participante indicado como primer argumento, lanza la opción indicada en el segundo argumento del menú de acciones en un turno. o menu_diario/2: muestra el menú con las acciones del diario, para el participante indicado como primer argumento, teniendo en cuenta que el diario está abierto por la página indicada como segundo argumento, la acción que tenga lugar, teniendo en cuenta que la numeración es referida como 1 para la última página e incrementa conforme se retrocede a páginas anteriores del diario. o menu_diario/3: lanza del menú con las acciones del diario, para el participante indicado como primer argumento, teniendo en cuenta que el diario está abierto por la página indicada como segundo argumento, la acción que tenga lugar teniendo en cuenta que la numeración es referida como 1 para la última página e incrementa conforme se retrocede a páginas anteriores del diario, y que el usuario eligió la opción de menú indicada en el tercer argumento. o menu_principal/0: muestra el menú principal del programa. o menu_principal/1: lanza del menú principal la opción indicada en el primer argumento. o









Javier Gago Romero

Página 26

FIA

Fundamentos de Inteligencia Artificial - AO2









Curso 2016-2017

Información estadística de las partidas jugadas o estadisticas/0: muestra una pantalla con la información estadística de las partidas que se han jugado desde que se inició el juego. o grafica_partidas/0: muestra una gráfica de barras con las partidas que ha ganado cada participante. o dibujar_grafica/1: dibuja en pantalla la gráfica de las partidas ganadas por el participante indicado como primer argumento. En la gráfica, cada victoria se indica con una barra vertical. Tras esto, aparece el porcentaje de partidas que el participante ha ganado respecto al total de partidas jugadas. o dibujar_grafica/2: dibuja una gráfica compuesta de una barra vertical por cada victoria, de tal manera que debe alcanzarse el valor especificado en el primer argumento, y actualmente se ha dibujado hasta el paso indicado en el segundo argumento. Mensajes de inicio del programa o titulo_programa/0: muestra una cabecera con el título del programa. o introducción/0: muestra en pantalla la introducción al juego. Mostrar información en el programa o reglas/0: muestra en pantalla al usuario las reglas del juego de la Prolog-Oca. o historia_y_curiosidades/0: muestra en pantalla información sobre la historia del juego de la oca y curiosidades relacionadas con el juego. o acerca_de/0: muestra en pantalla información acerca del programa. Representaciones gráficas en el juego o dibujar_dado/1: dibuja un dado con la puntuación obtenida indicada como primer argumento. o dibujar_tablero/0: dibuja el tablero del juego en pantalla para que pueda consultarse por el usuario. o dibujar_buhito/0: dibuja el búho que representa el logotipo del intérprete SWIPROLOG. o dibujar_curso_virtual/0: dibuja al alumno en el curso virtual, accediendo al foro de la asignatura Fundamentos de Inteligencia Artificial. o dormir/2: representa en pantalla los ronquidos del alumno, teniendo en cuenta que cada carácter se muestra tras un retardo en segundos especificado en el primer argumento y que la representación debe ser del tamaño indicado en el segundo argumento. o dormir/3: el primer argumento indica el retardo entre cada carácter a la hora de representar los ronquidos del alumno. El segundo argumento es el tamaño de la representación, y el tercer argumento el paso de ese tamaño en el cual se está actualmente en la recursión.

Consideraciones de eficiencia Las consideraciones de eficiencia pasan principalmente por el orden en el que se han escrito las reglas de los diferentes predicados en el fichero, y por el uso del predicado corte (!), en las reglas de algunos predicados concretos. El predicado de corte (!), permite realizar la poda de soluciones, aumentando así la eficiencia en la resolución de algunos predicados, de los que sólo necesitamos una solución, o Javier Gago Romero

Página 27

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

bien sabemos que el problema sólo tendrá una única solución, porque conocemos el problema y podemos así especificar que realmente no hay que continuar explorando soluciones. Desde un punto de vista procedimental, estamos diciendo al intérprete que no continúe con la búsqueda llegado al punto de corte, es decir, le estamos diciendo CÓMO debe proceder. El uso de este operador debe realizarse con cuidado, pues no tiene una interpretación desde el punto de vista lógico, pero sí procedimental. En algunos casos donde hemos empleado el corte, no es necesario verificar de nuevo ciertos objetivos, y hemos aprovechado esto para introducir eficiencia en la implementación, analizando que no introducimos cortes rojos. Por ejemplo:

En la primera regla, se evalúa si VJ > VC. En la segunda regla, estamos en realidad interesados en evaluar si VJ VC, write('Sigues con amnesia global, sin recordar tu nombre ni qué haces en esa habitación cerrada bajo llave.'), nl, nl, write('¿Cómo vas a salir de la habitación? ¿Quién escribió todo ese código Prolog?'), nl, nl, write('Sólo te queda el consuelo de haber ganado más partidas que la IA.'), nl, nl, !. escribir_frase_salida :- amnesia(jugador, global), write('Sigues con amnesia global, sin recordar tu nombre ni qué haces en esa habitación cerrada bajo llave.'), nl, nl, write('¿Cómo vas a salir de la habitación? ¿Quién escribió todo ese código Prolog?'), nl, nl, write('Y ya para rematar, no has podido superar a la IA jugando. ¡Vaya desastre!'), nl, nl, !. escribir_frase_salida :- amnesia(jugador, retrograda), victorias(jugador, VJ), victorias(cpu, VC), VJ > VC, write('Has conseguido recordar tu nombre, pero aún quedan demasiadas incógnitas en el aire.'), nl, nl, write('¿Cómo vas a salir de la habitación cerrada bajo llave? ¿Quién escribió todo ese código Prolog?'), nl, nl, write('Al menos, has conseguido ganar más partidas que la IA.'), nl, nl, !. escribir_frase_salida :- amnesia(jugador, retrograda), write('Has conseguido recordar tu nombre, pero aún quedan demasiadas incógnitas en el aire.'), nl, nl, write('¿Cómo vas a salir de la habitación cerrada bajo llave? ¿Quién escribió todo ese código Prolog?'), nl, nl, write('¡Y para colmo no has ganado más partidas que la IA!'), nl, nl, !. escribir_frase_salida :- amnesia(jugador, curada), victorias(jugador, VJ), victorias(cpu, VC), VJ > VC, write('¡Todo ha salido estupendamente! El golpe finalmente no fue nada grave de lo que preocuparse.'), nl, nl,

Javier Gago Romero

Página 44

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

write('La actividad de Fundamentos de Inteligencia Artificial pudo entregarse a tiempo, apurado, pero a tiempo... a espera de calificación.'), nl, nl, write('Además, finalmente has podido disfrutar venciendo más partidas que la IA. ¡HAS GANADO!'), nl, nl, !. escribir_frase_salida :- amnesia(jugador, curada), write('¡No han salido mal las cosas finalmente! El golpe finalmente no fue nada grave de lo que preocuparse.'), nl, nl, write('La actividad de Fundamentos de Inteligencia Artificial pudo entregarse a tiempo, apurado, pero a tiempo... a espera de calificación.'), nl, nl, write('Sin embargo, no has conseguido vencer más partidas que la IA. Es algo que se te ha resistido.'), nl, nl.

/* ESPERAR A QUE EL USUARIO PULSE INTRO. */ %Predicado que permite espera hasta que el usuario pulse INTRO. esperar_intro :- nl, write(''), skip(10), nl.

/* NOMBRES DE PARTICIPANTES. */ %Mensaje con el que se representa en pantalla el nombre de cada participante. escribir_nombre(jugador) :- nombre(jugador, N), write(N), write(' (HUMANO)'). escribir_nombre(cpu):- nombre(cpu, N), write(N), write(' (IA)').

%Selecciona un nombre, N, para el proyecto. nombre_proyecto(N) :- nombres_proyecto(L), proper_length(L, LONG), I is random(LONG), nth0(I, L, N).

/* CASILLAS. */ %Predicado que especifica si un número está en el rango válido de casillas (entre 0 y 63). casilla(C) :- C >= 0, C =< 63.

%Predicado que comprueba si la casilla C es un puente. puente(C) :- puentes(L), member(C, L).

%Predicado que comprueba si la casilla C es una posada.

Javier Gago Romero

Página 45

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

posada(C) :- posadas(L), member(C, L).

%Predicado que comprueba si la casilla C es de dados. dados(C) :- dadoss(L), member(C, L).

%Predicado que comprueba si la casilla C es un pozo. pozo(C) :- pozos(L), member(C, L).

%Predicado que comprueba si la casilla C es un laberinto. laberinto(C) :- laberintos(L), member(C, L).

%Predicado que comprueba si la casilla C es una cárcel. carcel(C) :- carceles(L), member(C, L).

%Predicado que comprueba si la casilla C es una calavera. calavera(C) :- calaveras(L), member(C, L).

%Predicado que comprueba si la casilla C es una oca. oca(C) :- ocas(L), member(C, L).

%Predicado que comprueba si la casilla C es una casilla de victoria. victoria(C) :- victorias(L), member(C, L).

%Predicado que determina si una casilla es especial. casilla_especial(C) :- casilla(C),(calavera(C); posada(C); pozo(C); carcel(C); laberinto(C); dados(C); puente(C); oca(C); victoria(C)).

%Predicado que determina si una casilla es normal. casilla_normal(C) :- casilla(C), not(casilla_especial(C)).

/* PREDICADOS RELACIONADOS CON UNA NUEVA PARTIDA. */ %Comienzo de una nueva partida. nueva_partida :- write('¡Estupendo! Vamos a comenzar una nueva partida. ¡Mucha suerte!'), nl, nl,

Javier Gago Romero

Página 46

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

write('A continuación, habrá que decidir quién comenzará el juego.'), nl, esperar_intro, determinar_participante_inicial.

%Hace que el participante X comience el juego. comenzar_partida(X) :- write('¡'), escribir_nombre(X), write(' comenzará el juego!'), nl, turno(X).

%Determina el participante que comenzará la partida, mediante una tirada de dados. %El participante que obtenga la mayor puntuación en una tirada de dados, es el que comenzará la partida. %Si ambos participantes obtienen la misma puntuación, entonces el lanzamiento debe repetirse hasta eliminar la igualdad. %Este predicado se resuelve recursivamente. %Cabe señalar que el caso base se produce cuando los dos lanzamientos sean distintos, independientemente del participante que comience la partida. %Cuando hay igualdad en la tirada, entonces se produce una llamada recursiva. El progreso hacia el caso base tiene lugar en el sentido de que, %por probabilidad, en algún momento se terminará llegando al caso base, que es, de hecho, más probable que el hecho de que tenga lugar una %llamada recursiva. %Si los dados están equilibrados, entonces la probabilidad de que las dos tiradas sean iguales es de 6 posibilidades entre 36, es decir, 1/6. %Por tanto, suponiendo que los dados están equilibrados, hay 5/6 de probabilidad de alcanzar el caso base y 1/6 de que se produzca una llamada %recursiva. determinar_participante_inicial :- write('Los participantes van a lanzar los dados para ver quién inicia el juego.'), nl, write('El participante que obtenga la puntuación más alta en la tirada de dados comenzará la partida.'), nl, esperar_intro, tirada(T1), dibujar_dado(T1), escribir_nombre(jugador), write(' obtiene un '), write(T1), write('.'), nl, tirada(T2), dibujar_dado(T2), escribir_nombre(cpu), write(' obtiene un '), write(T2), write('.'), nl, nl, comparar_tiradas_iniciales(T1, T2, X), comenzar_partida(X), !. determinar_participante_inicial :- write('¡Vaya, los participantes han obtenido la misma puntuación! Habrá que repetir el lanzamiento.'), nl, esperar_intro, determinar_participante_inicial.

%Compara las tiradas iniciales T1 y T2. %Si T1 es mayor que T2, entonces el participante que debe comenzar la partida es jugador, como se indica en el tercer argumento. %Si T2 es mayor que T1, entonces el participante que debe comenzar la partida es cpu, como se indica en el tercer argumento.

Javier Gago Romero

Página 47

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

%Si T1 es igual que T2, entonces el predicado devuelve falso. comparar_tiradas_iniciales(T1, T2, jugador) :- T1 > T2. comparar_tiradas_iniciales(T1, T2, cpu) :- T1 < T2.

/* PREDICADOS RELACIONADOS CON TURNOS, TIRADAS DE DADOS, Y FINALIZAR UNA PARTIDA. */ %Turno de un participante. El participante se indica mediante X. turno(X):- participante(X), esperar_intro, nl, write('**********'), nl, write('TURNO DE '), escribir_nombre(X), nl, nl, write('**********'), nl , nl, interactuar(X).

%Cambio de turno entre participantes. cambio_turno(jugador) :- turno(cpu). cambio_turno(cpu) :- turno(jugador).

%Tirada de un dado. El valor obtenido tras la tirada, es T. tirada(T):- T is random(6) + 1.

%Descripción al azar de un lanzamiento de dado. descripcion_lanzamiento_dado(F) :- descripciones_lanzamientos_dado(L), proper_length(L, LONG), I is random(LONG), nth0(I, L, F).

%Lanzamiento de un dado. El participante que lanza el dado se indica mediante X. lanzar_dado(X) :- participante(X), escribir_nombre(X), write(' '), descripcion_lanzamiento_dado(F), write(F), nl, write('(Actualmente se encuentra en la casilla '), posicion(X, CA), write(CA), write(').'), nl, esperar_intro, tirada(T), dibujar_dado(T), write('¡Ha salido un '), write(T), write('!'), nl, actualizar_posicion(X, T),

Javier Gago Romero

Página 48

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

posicion(X, C), escribir_nombre(X), write(' alcanza así la casilla número '), write(C), write('.'), nl, nl, frase(C), nl, accion(X, C).

%Determina como un participante puede interactuar en un turno. %Si el participante tiene prohibido tirar el dado en ese turno, entonces no podrá interactuar. %La CPU, siempre y cuando no tenga prohibido tirar el dado, siempre interactúa lanzando su dado. interactuar(jugador) :- sin_tirar(jugador, N), N > 0, M is N - 1, escribir_nombre(jugador), write(' no puede lanzar el dado este turno.'), nl, retract(sin_tirar(jugador, _)), assert(sin_tirar(jugador, M)), turno(cpu), !. interactuar(jugador) :- menu_turno(jugador). interactuar(cpu) :- sin_tirar(cpu, N), N > 0, M is N - 1, escribir_nombre(cpu), write(' no puede lanzar el dado este turno.'), nl, retract(sin_tirar(cpu, _)), assert(sin_tirar(cpu, M)), turno(jugador), !. interactuar(cpu) :- menu_turno(cpu, 1).

%Determina que ocurre cuando un participante gana el juego. gana(jugador) :- nl, write('¡¡¡'), escribir_nombre(jugador), write(' alcanza la victoria!!!'), nl, comprobar_amnesia(jugador), finalizar_partida(jugador). gana(cpu) :- nl, write('... '), escribir_nombre(cpu), write(' se alza con la victoria ...'), nl, finalizar_partida(cpu).

%Determina que ocurre cuando un participante se rinde. rendirse(jugador) :- write('¡¡Ohhhh!!, has decidido tirar la toalla y rendirte.'), nl, gana(cpu). rendirse(cpu) :- write('¡Tu rival se ha rendido!'), nl, gana(jugador).

%Finaliza una partida, donde el ganador ha sido el participante X. finalizar_partida(X):- victorias(X, V), retract(victorias(X, _)),

Javier Gago Romero

Página 49

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

VN is V + 1, assert(victorias(X, VN)), retract(posicion(jugador, _)), retract(posicion(cpu, _)), assert(posicion(jugador, 0)), assert(posicion(cpu, 0)), retract(sin_tirar(jugador, _)), retract(sin_tirar(cpu, _)), assert(sin_tirar(jugador, 0)), assert(sin_tirar(cpu, 0)), escribir_diario(jugador, X), nl, nl.

/* POSICIÓN DE UN PARTICIPANTE EN EL TABLERO. */ %Mueve al participante X a la casilla número C. mover_a_posicion(X, C) :- casilla(C), retract(posicion(X, _)), assert(posicion(X, C)).

%Actualiza la posición del participante X, en T casillas. %El valor de T puede ser positivo o negativo. Si es positivo avanzará en el tablero, y si %es negativo, entonces el participante retrocederá. %Uno de los objetivos de este predicado es correccion_rebote, que se encargará de realizar %el efecto de rebote, que tiene lugar en el juego de la oca cuando un participante debería %ir más allá de la casilla final. actualizar_posicion(X, T) :- posicion(X, C), CN is C + T, correccion_rebote(CN, CNR), retract(posicion(X, C)), assert(posicion(X, CNR)).

%Corrige la posición del participante, cuya posición nueva, de seguir el tablero, sería X, %en base al rebote que se produce en el juego de la oca cuando un participante debería ir %más allá de la casilla final. La corrección se calcula en Y. %Para ello, se comprueba si X es mayor que 63, en cuyo caso, se calcula el exceso, y se resta %a 63, pasando a ser la nueva casilla donde debe posicionarse el participante. %Si X no es mayor que 63, entonces simplemente se da por válida la corrección sin hacer nada más,

Javier Gago Romero

Página 50

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

%y el valor devuelto en el segundo argumento es la propia X. correccion_rebote(X, Y) :- X > 63, R is X - 63, Y is 63 - R, !. correccion_rebote(X, X).

/* ACCIONES DE UN PARTICIPANTE EN FUNCIÓN DE LA CASILLA EN LA QUE CAE. */ %Determina la acción que debe realizar el participante X, en la casilla indicada por el segundo argumento. accion(X, C) :- victoria(C), gana(X), !. accion(X, C) :- oca(C), accion_oca(X, C), !. accion(X, C) :- puente(C), accion_puente(X, C), !. accion(X, C) :- posada(C), accion_posada(X), !. accion(X, C) :- dados(C), accion_dados(X, C), !. accion(X, C) :- pozo(C), accion_pozo(X), !. accion(X, C) :- laberinto(C), accion_laberinto(X), !. accion(X, C) :- carcel(C), accion_carcel(X), !. accion(X, C) :- calavera(C), accion_calavera(X), !. accion(X, C) :- casilla(C), cambio_turno(X).

%Determina la acción de una casilla de oca, para el participante X, en la casilla indicada por el segundo argumento. %Se asume, que si la partida no terminara en victoria en la última oca, el participante se desplazaría de nuevo, por ser oca, a la %primera de las ocas, al igual que sucede esto en las casillas de dados y de puentes. %Si el participante no está en la última oca, entonces se desplaza hasta la siguiente oca. %La partida finaliza si el jugador llegó a la penúltima oca, pues de ésta se desplaza hasta la casilla de la victoria y gana, o bien %si ha caído en la última oca, puesto que es una casilla de victoria. %Si el jugador ha caído en una oca, que no es ni la penúltima ni la última de las ocas, entonces continúa su turno. accion_oca(X, C) :- ocas(L), last(L, C), ocas([CN | _]), mover_a_posicion(X, CN), !. accion_oca(X, C) :- ocas(L), nextto(C, CN, L), last(L, CN), mover_a_posicion(X, CN), accion(X, CN), !. accion_oca(X, C) :- ocas(L), nextto(C, CN, L), mover_a_posicion(X, CN), turno(X).

%Determina la acción de una casilla de laberinto, para el participante X, en la casilla indicada por el segundo argumento. %El participante debe retroceder hasta la casilla número 30. %Tras esto, el participante cede su turno. accion_laberinto(X) :- mover_a_posicion(X, 30), cambio_turno(X).

Javier Gago Romero

Página 51

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

%Determina la acción de una casilla de posada, para el participante X. %El participante no podrá tirar durante dos turnos. %Tras esto, el participante cede su turno. accion_posada(X) :- retract(sin_tirar(X, _)), assert(sin_tirar(X, 2)), cambio_turno(X).

%Determina la acción de una casilla de pozo, para el participante X. %El participante no podrá tirar durante dos turnos. %Tras esto, el participante cede su turno. accion_pozo(X) :- retract(sin_tirar(X, _)), assert(sin_tirar(X, 2)), cambio_turno(X).

%Determina la acción de una casilla de cárcel, para el participante X. %El participante no podrá tirar durante tres turnos. %Tras esto, el participante cede su turno. accion_carcel(X) :- retract(sin_tirar(X, _)), assert(sin_tirar(X, 3)), cambio_turno(X).

%Determina la acción de una casilla de dados, para el participante X, en la casilla indicada por el segundo argumento. %El participante avanza hasta la siguiente casilla de dados del listado de casillas de dados. %Si el participante ha caído en la última casilla de dados del listado, entonces debe retroceder hasta la primera casilla de dados. %Tras esto, el participante continúa con su turno. accion_dados(X, C) :- dadoss(L), last(L, C), dadoss([CN | _]), mover_a_posicion(X, CN), turno(X), !. accion_dados(X, C) :- dadoss(L), nextto(C, CN, L), mover_a_posicion(X, CN), turno(X).

%Determina la acción de una casilla de puente, para el participante X, en la casilla indicada por el segundo argumento. %El participante avanza hasta el siguiente puente del listado de puentes. %Si el participante ha caído en el último puente del listado, entonces debe retroceder hasta el primer puente. %Tras esto, el participante continúa con su turno. accion_puente(X, C) :- puentes(L), last(L, C), puentes([CN | _]), mover_a_posicion(X, CN), turno(X), !. accion_puente(X, C) :- puentes(L), nextto(C, CN, L), mover_a_posicion(X, CN), turno(X).

%Determina la acción de una casilla de calavera, para el participante X. %El participante debe comenzar el juego de nuevo, desde la posición inicial. %Tras esto, el participante cede su turno. accion_calavera(X) :- mover_a_posicion(X, 0), cambio_turno(X).

Javier Gago Romero

Página 52

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

/* FRASES ASOCIADAS A LAS CASILLAS. */ %Muestra una frase en pantalla según la casilla indicada. frase(63) :- write('Casilla de la VICTORIA --> "¡¡¡La casilla final ha sido alcanzada....!!!"'), !. frase(1) :- write('Casilla de Isaac Asimov.'), nl, write('Isaac Asimov fue un escritor y profesor de bioquímica en la Facultad de Medicina de la Universidad de Boston de origen ruso, nacionalizado estadounidense, conocido por ser un prolífico autor de obras de ciencia ficción, historia y divulgación científica.'), !. frase(2) :- write('Casilla de Philip K. Dick.'), nl, write('Philip K. Dick, fue un prolífico escritor y novelista estadounidense de ciencia ficción, que influyó notablemente en dicho género.'), !. frase(3) :- write('Casilla de Arthur C. Clarke.'), nl, write('Arthur C. Clarke, fue un escritor y científico británico. Autor de obras de divulgación científica y de ciencia ficción, como la novela 2001: Una odisea del espacio, El centinela o Cita con Rama y coguionista de la película 2001: Una odisea del espacio.'), !. frase(4) :- write('Casilla de Ray Bradbury.'), nl, write('Ray Bradbury fue un escritor estadounidense de misterio del género fantástico, terror y ciencia ficción. Principalmente conocido por su obra Crónicas marcianas (1950) y la novela distópica Fahrenheit 451 (1953).'), !. frase(7) :- write('Casilla de Susan Calvin.'), nl, write('La doctora Susan Calvin es un personaje de ficción protagonista en muchos de los cuentos sobre robots del prolífico escritor Isaac Asimov.'), !. frase(8) :- write('Casilla de Hall 9000.'), nl, write('HAL 9000, cuyo nombre es un acrónimo en inglés de Heuristically Programmed Algorithmic Computer (Computador algorítmico heurísticamente programado), es una supercomputadora o superordenador ficticio de tipo mainframe que aparece en las series de Odisea del espacio, iniciada con la novela 2001 A Space Odyssey escrita por Arthur C. Clarke en 1968.'), !. frase(10) :- write('Casilla de Multivac.'), nl, write('Multivac es una supercomputadora ficticia que aparece en muchas de las historias o cuentos de Isaac Asimov, entre 1955 y 1975.'), !. frase(11) :- write('Casilla de Hari Seldon.'), nl, write('Hari Seldon es el héroe intelectual de la Saga de la Fundación de Isaac Asimov. Durante su estancia en la Universidad de Streeling en Trántor desarrolló la psicohistoria, una serie de ecuaciones que le permitían predecir el futuro en términos probabilísticos. Por sus predicciones sobre la decadencia y el final del Imperio Galáctico le acuñaron el apodo de "Cuervo" Seldon.'), !. frase(13) :- write('Casilla de Alan Turing.'), nl, write('Alan Turing fue un matemático, lógico, científico de la computación, criptógrafo, filósofo, maratoniano y corredor de ultra distancia británico. Es considerado uno de los padres de la ciencia de la computación y precursor de la informática moderna.'), !. frase(15) :- write('Casilla de George Boole.'), nl, write('George Boole fue un matemático y lógico británico. Como inventor del álgebra de Boole, que marca los fundamentos de la aritmética computacional moderna, Boole es considerado como uno de los fundadores del campo de las Ciencias de la

Javier Gago Romero

Página 53

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

Computación. En 1854 publicó An Investigation of the Laws of Thought on Which are Founded the Mathematical Theories of Logic and Probabilities, donde desarrolló un sistema de reglas que le permitían expresar, manipular y simplificar problemas lógicos y filosóficos cuyos argumentos admiten dos estados (verdadero o falso) por procedimientos matemáticos. Se podría decir que es el padre de los operadores lógicos simbólicos y que gracias a su álgebra hoy en día es posible operar simbólicamente para realizar operaciones lógicas.'), !. frase(16) :- write('Casilla de Ramón Llul.'), nl, write('Ramón Llul fue un laico próximo a los franciscanos (pudo haber pertenecido a la Orden Tercera de San Francisco), filósofo, poeta, místico, teólogo y misionero mallorquín. en sus obras filosóficas anticipó la lógica como cálculo mecánico con símbolos en el que se aplicaba un método, los métodos heurísticos de la Inteligencia Artificial, los sistemas generativos, los grafos, las redes semánticas, los diagramas de Venn. Influyó en Montaigne, Pascal, Descartes, Leibnitz, Newton, Pico della Mirandola y Giordano Bruno.'), !. frase(17) :- write('Casilla de Gottlob Frege.'), nl, write('Friedrich Ludwig Gottlob Frege fue un matemático, lógico y filósofo alemán, padre de la lógica matemática y la filosofía analítica.'), !. frase(20) :- write('Casilla de Walter Pitts.'), nl, write('Walter Pitts fue un lógico estadounidense que trabajó en el campo de neurociencia computacional. Propuso teorías de importancia en actividad neuronal y procesos generativos que influyeron en diversos campos como psicología, ciencias cognitivas, filosofía, neurociencias, informática, redes neuronales artificiales, cibernética e inteligencia artificial, junto con lo que ha venido a ser conocido como ciencias generativas. Es recordado para haber escrito, junto con Warren McCulloch, un artículo titulado "Cálculo lógico de Ideas inherentes en la actividad nerviosa" (1943). El mismo propone el primer modelo matemático de una red neuronal artificial. La unidad de este modelo, una neurona sencilla, es todavía el estándar de referencia en el campo de redes neuronales. Es a menudo llamada neurona de McCulloch-Pitts.'), !. frase(21) :- write('Casilla de Warren McCulloch.'), nl, write('Warren McCulloch era un neurólogo y cibernético estadounidense. Recordado por su trabajo con Dusser de Barenne (Yale) y, más tarde, con Walter Pitts (Universidad de Illinois), el cual proveyó los fundamentos para ciertas teorías del cerebro en un número de ensayos clásicos, incluidos Un cálculo lógico de las ideas inmanentes en la actividad nerviosa (1943) y Cómo conocemos los universales: la percepción de las formas visuales y auditivas (1947), ambos en el Boletín de Biofísica Matemática.'), !. frase(22) :- write('Casilla de Martin Fischles.'), nl, write('En 1987 Martin Fischles y Oscar Firschein describieron los atributos de un agente inteligente. Al intentar describir con un mayor ámbito (no sólo la comunicación) los atributos de un agente inteligente, la IA se ha expandido a muchas áreas que han creado ramas de investigación enormes y diferenciadas.'), !. frase(24) :- write('Casilla de Oscar Firschein.'), nl, write('En 1987 Martin Fischles y Oscar Firschein describieron los atributos de un agente inteligente. Al intentar describir con un mayor ámbito (no sólo la comunicación) los atributos de un agente inteligente, la IA se ha expandido a muchas áreas que han creado ramas de investigación enormes y diferenciadas.'), !. frase(25) :- write('Casilla de John Searle.'), nl, write('John Searle es muy conocido por el desarrollo de un experimento mental llamado el argumento de la "habitación china". Lo creó para demostrar que el pensamiento humano no se compone de simples procesos computacionales.'), !. frase(28) :- write('Casilla de John McCarthy.'), nl, write('John McCarthy también conocido como Tío John McCarthy, fue un prominente informático que recibió el Premio Turing en 1971 por sus importantes contribuciones en el campo de la Inteligencia Artificial. De hecho, fue el responsable de introducir el término "inteligencia artificial", concepto que acuñó en la Conferencia de Dartmouth en 1956. También se le atribuye el concepto de cloud computing.'), !. frase(29) :- write('Casilla de Marvin Minsky.'), nl, write('Marvin Minsky fue un científico estadounidense. Es considerado uno de los padres de las ciencias de la computación y cofundador del laboratorio de inteligencia artificial del Instituto Tecnológico de Massachusetts o MIT.'), !. frase(30) :- write('Casilla de Allen Newell.'), nl,

Javier Gago Romero

Página 54

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

write('Allen Newell fue un investigador en informática y psicología cognitiva en la corporación WWE y en la escuela de informática de Carnegie Mellon. Contribuyó al lenguaje de procesamiento de información (IPL) (1956) y a dos de los primeros programas de inteligencia artificial, la máquina de lógica teórica (1956) y el resolutor general de problemas (1957), con Herbert Simon.'), !. frase(33) :- write('Casilla de Herbert Simon.'), nl, write('Herbert Simon fue un economista, politólogo y teórico de las ciencias sociales estadounidense. Recibió el Premio Turing de la ACM en 1975, junto con Allen Newell por hacer "contribuciones básicas a la inteligencia artificial, la psicología cognitiva humana y el procesamiento de listas", y el Award for Distinguished Scientific Contribution de la Asociación Norteamericana de Psicología (APA) en 1969. Además fue designado Miembro Distinguido (Distinguished Fellow) de la Asociación Norteamericana de Economía.'), !. frase(34) :- write('Casilla de William Bradford Shockley.'), nl, write('William Bradford Shockley fue un físico estadounidense. En conjunto con John Bardeen y Walter Houser Brattain, obtuvo el premio Nobel de Física en 1956 "por sus investigaciones sobre semiconductores y el descubrimiento del Transistor."'), !. frase(35) :- write('Casilla de Konrad Zuse.'), nl, write('Konrad Zuse fue un ingeniero alemán y un pionero de la computación. Su logro más destacado fue terminar la primera computadora controlada por programas que funcionaban, la Z3 en 1941.'), !. frase(37) :- write('Casilla de Salvor Hardin.'), nl, write('Salvor Hardin es un personaje ficticio de la novela Fundación del escritor Isaac Asimov. Su frase más célebre es: "La violencia es el último recurso del incompetente".'), !. frase(38) :- write('Casilla de Elijah Baley.'), nl, write('Elijah (Lije) Baley es un personaje ficticio de varias novelas escritas por Isaac Asimov pertenecientes a la serie de los Robots. Es un detective y policía del departamento de Nueva York. Es el personaje principal de Las bóvedas de acero, El sol desnudo y Los robots del amanecer. También es nombrado en Robots e Imperio, que transcurre varios siglos después de su muerte, y en cuentos particulares de Asimov, como Reflejo simétrico.'), !. frase(39) :- write('Casilla de R. Daneel Olivaw.'), nl, write('R. Daneel Olivaw es un robot de ficción creado por Isaac Asimov. Aparece en las series de Robots y Fundación. De forma destacada se puede encontrar en Las bóvedas de acero, El sol desnudo, Los robots del amanecer, Robots e Imperio, Preludio a la Fundación, Hacia la Fundación y Fundación y Tierra. También aparece en todos los libros de la Segunda Trilogía de la Fundación, tales como "El temor de la Fundación" de Gregory Benford, "Fundación y caos" de Greg Bear, y "El triunfo de la Fundación" de David Brin. Daneel es un personaje muy significativo dentro del universo de la Fundación, pues es el personaje unificador de todos los ciclos de la Saga, influyendo sobre el destino de la humanidad en un espacio de tiempo de unos 20.000 años.'), !.

frase(40) :- write('Casilla de Robert Silverberg.'), nl, write('Robert Silverberg es un escritor estadounidense. Muchas son las anécdotas que de él cuenta Isaac Asimov, particularmente en sus recopilaciones de cuentos y en el documento Sobre la ciencia ficción; por ejemplo, dice que tenían la costumbre de llamarse por teléfono cada vez que visitaban una biblioteca, para hacer recuento de los títulos de cada uno que había en dicha biblioteca, y siempre había más de Isaac Asimov. Colaboró en varias revistas del género, como por ejemplo durante el primer ciclo de Venture Science Fiction.'), !. frase(43) :- write('Casilla de Carl Sagan.'), nl, write('Carl Sagan fue un astrónomo, astrofísico, cosmólogo, escritor y divulgador científico estadounidense. Fue un defensor del pensamiento escéptico científico y del método científico, pionero de la exobiología, promotor de la búsqueda de inteligencia extraterrestre a través del Proyecto SETI. Impulsó el envío de mensajes a bordo de sondas espaciales, destinados a informar a posibles civilizaciones extraterrestres acerca de la cultura humana.'), !. frase(44) :- write('Casilla de Robert A. Heinlein.'), nl, write('Robert A. Heinlein fue un escritor estadounidense de ciencia ficción considerado por algunos críticos entre los tres mejores de todos los tiempos, junto con Isaac Asimov y Arthur C. Clarke.'), !. frase(46) :- write('Casilla de Noam Chomsky.'), nl,

Javier Gago Romero

Página 55

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

write('Noam Chomsky es un lingüista, filósofo y activista estadounidense. Es profesor emérito de lingüística en el Instituto Tecnológico de Massachusetts (MIT) y una de las figuras más destacadas de la lingüística del siglo XX, gracias a sus trabajos en teoría lingüística y ciencia cognitiva.'), !. frase(47) :- write('Casilla de Howard Gardner.'), nl, write('Howard Gardner es un psicólogo, investigador y profesor de la Universidad de Harvard, conocido en el ámbito científico por sus investigaciones en el análisis de las capacidades cognitivas y por haber formulado la teoría de las inteligencias múltiples, la que lo hizo acreedor al Premio Príncipe de Asturias de Ciencias Sociales en 2011.'), !. frase(48) :- write('Casilla de Margaret Boden.'), nl, write('Margaret A. Boden es una reconocida experta en Inteligencia Artificial e investigadora en diferentes campos, desde la psicología, a la filosofía y las Ciencias Cognitivas.'), !. frase(49) :- write('Casilla de Verónica Dahl.'), nl, write('Verónica Dahl es una informática teórica argentina-canadiense, reconocida entre los 15 fundadores del campo de la programación lógica.'), !. frase(51) :- write('Casilla de Raúl Rojas.'), nl, write('Raúl Rojas, nacionalizado alemán en 1996, es un profesor de matemáticas e informática de la Universidad Libre de Berlín, en Alemania, y un reconocido experto en redes neuronales artificiales e inteligencia artificial. Los robots de fútbol FUFighters construidos en su equipo de investigación fueron campeones mundiales en 2004 y 2005. En este momento se dedica a un proyecto de automóvil sin piloto llamado Spirit of Berlin.'), !. frase(55) :- write('Casilla de Richard Greenblatt.'), nl, write('Richard D. Greenblatt es un programador informático estadounidense. Junto con Bill Gosper, es considerado como el fundador de la comunidad hacker. Ocupa un lugar de distinción en las comunidades de Lisp y el MIT AI Lab.'), !. frase(56) :- write('Casilla de Joseph Halpern.'), nl, write('Joseph Halpern es un profesor de ciencias de la computación en la Universidad Cornell. La mayoría de su investigación trata de razonamiento sobre conocimiento e incertidumbre.'), !. frase(57) :- write('Casilla de Arthur L. Samuel.'), nl, write('Arthur L. Samuel fue un pionero en el campo de los juegos informáticos y la inteligencia artificial y el creador de uno de los primeros juegos didácticos como demostración muy temprana de el concepto de la inteligencia artificial (AI).'), !. frase(60) :- write('Casilla de William Ross Ashby.'), nl, write('William Ross Ashby fue un médico y neurólogo inglés, que contribuyó decisivamente a la consolidación de la cibernética moderna y creó el primer homeostato (1951), dispositivo electrónico autorregulado por retroalimentación. Desde las especialidades de la neurología y la psiquiatría, ofreció la reproducción de la estructura y mecanismos de funcionamiento del cerebro humano en sus obras Proyecto para un cerebro (1942) e Introducción a la cibernética (1956).'), !. frase(61) :- write('Casilla de Lotfi A. Zadeh.'), nl, write('Lotfi A. Zadeh es un matemático, ingeniero eléctrico, informático y profesor azerbaiyano de la Universidad de Berkeley. Es famoso por introducir en 1965 la teoría de conjuntos difusos o lógica difusa. Se le considera asimismo el padre de la teoría de la posibilidad.'), !. frase(62) :- write('Casilla de Philippe Roussel.'), nl, write('Philippe Roussel es Doctor en Informática, y creador junto con Alain Colmerauer y Robert Kowalski del lenguaje de programación Prolog.'), !. frase(C) :- calavera(C), write('Casilla de Retract --> "Borran una regla del programa que aportaba información sobre tu posición en el tablero. Mala suerte, debes comenzar de nuevo desde la casilla 0".'), !. frase(C) :- oca(C), write('Casilla de Buhito --> "De buhito a buhito, y tiro otro poquito...".'), !. frase(C) :- laberinto(C), write('Casilla de Recursión --> "De la recursión al 30".'), !.

Javier Gago Romero

Página 56

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

frase(C) :- posada(C), write('Casilla de Error Lógico --> "Un error en la lógica de Prolog hace que pierdas dos turnos".'), !. frase(C) :- pozo(C), write('Casilla de Rama Infinita --> "Pierdes dos turnos al caer en una rama infinita".'), !. frase(C) :- carcel(C), write('Casilla de Error Sintáctico --> "Un error sintáctico que debes corregir, te hace perder tres turnos".'), !. frase(C) :- dados(C), write('Casilla de Corte --> "De corte en corte y tiro como un resorte...".'), !. frase(C) :- puente(C), write('Casilla de Predicado --> "De predicado a predicado, y tiro según se ha determinado...".'), !. frase(C) :- casilla(C), write('Casilla Normal --> "Una casilla normal y corriente."').

/* AMNESIA DEL JUGADOR. */ %Comprueba la amnesia del participante, para ver si puede recuperar parte de su memoria. %En el caso de que no pueda recuperar parte de su memoria, la última regla del predicado hace válido el objetivo siempre. %Es decir, es un predicado que siempre será cierto, pero puede o no realizar más acciones al recuperar parte de la amnesia o no. comprobar_amnesia(jugador) :- amnesia(jugador, global), tirada(T), T >= 5, nl, write('¡Wowww, parece que esta victoria me ha abierto la mente....!'), nl, nl, write('Muchos pensamientos me invanden en este momento....'), nl, nl, write('¡¡YA RECUERDO MI NOMBRE!!'), nl, nl, write('(NOTA: A continuación, escriba su nombre en minúsculas y sin espacios, p. e.: javier., o escribalo entre comillas simples o dobles, p. e.: "Javier Gago".)'), nl, write('Mi nombre es: '), read(NOMBRE), skip(10), nl, retract(nombre(jugador, _)), assert(nombre(jugador, NOMBRE)), actualizar_diario(jugador, '"¡Hoy es un gran día! ¡Acabo de recordar mi nombre! Al fin ya sé como me llamo, y sin duda estoy más cerca de recuperar toda mi memoria".'), retract(amnesia(jugador, global)), assert(amnesia(jugador, retrograda)), write('¡Eso es! Mi nombre es: '), escribir_nombre(jugador), nl, nl, !. comprobar_amnesia(jugador) :- amnesia(jugador, retrograda), tirada(T), T >= 5, nl, write('¡Wowww, esta victoria me ha hecho recuperar mis recuerdos....!'), nl, nl, write('¡¡YA RECUERDO QUE HA SUCEDIDO!!'), nl, nombre_proyecto(NOMBRE), retract(nombre(cpu, _)), assert(nombre(cpu, NOMBRE)),

Javier Gago Romero

Página 57

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

actualizar_diario(jugador, '"¡Al fin recuerdo lo sucedido! ¡Y el código lo he desarrollado yo, así que ya puedo entregar la práctica! ¡Genial! Aunque aún tengo tiempo para seguir jugando unas partidas... Ya conseguí también abrir la habitación y ya no es necesario que continúe escribiendo en este diario".'), esperar_intro, retract(amnesia(jugador, retrograda)), assert(amnesia(jugador, curada)), write('¡Yo desarrollé todo ese código Prolog!.'), nl, nl, write('Había pasado muchas horas sin dormir, absorto entre manuales de Prolog y cafeína. ¡No es nada bueno trabajar tanto sin tomar un descanso! Es algo que he de tener muy presente.'), nl, nl, write('Me había obsesionado con la seguridad, pensando que intentaban robarme el código, hasta tal punto de cerrar el cuarto bajo llave.'), nl, nl, write('La llave estaba escondida en el interior del buzo del acuario que hay en la habitación.'), nl, nl, write('Finalmente, el sueño me pudo, y di un fuerte golpe en la mesa que me hizo perder la memoria durante un tiempo. Espero que sólo sea un susto, y no quede en nada grave.'), nl, nl, write('Además, ahora recuerdo el nombre que le había dado a la IA cuando desarrollé el juego de la Prolog-Oca.'), nl, nl, write('¡Su nombre es '), escribir_nombre(cpu), write('!'), nl, esperar_intro, !. comprobar_amnesia(_).

/* DIARIO DEL JUGADOR. */ %Inserta la entrada E a la cabeza de la lista de entradas L. insertar_entrada_diario(E, L, [E|L]).

%Actualizar el diario del participante X con la entrada E. actualizar_diario(X, E) :- diario(X, L), insertar_entrada_diario(E, L, LN), retract(diario(X, _)), assert(diario(X, LN)), nl, write('¡Tienes una nueva entrada en tu diario!'), nl, nl.

%Predicado que determina si hay que escribir en el diario. %Para ello, comprueba si el participante X sigue teniendo algún tipo de amnesia no curada. %En caso afirmativo, procede a seleccionar una entrada posible teniendo en cuenta que la partida la ganó el participante G. %Si no hay que escribir en el diario, entonces se da por cumplido el objetivo sin realizar ninguna acción adicional.

Javier Gago Romero

Página 58

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

escribir_diario(X, _) :- amnesia(X, curada), !. escribir_diario(X, G) :- amnesia(X, _), entradas(G, L), proper_length(L, LONG), I is random(LONG), nth0(I, L, E), actualizar_diario(X, E), !. escribir_diario(_, _).

/* MENÚS DE USUARIO. */ %%%%%%%%%%%%%%%%%%%%%%%%%%%% %MENÚ DE ACCIONES DEL TURNO% %%%%%%%%%%%%%%%%%%%%%%%%%%%%

%Representa en pantalla el menú de las acciones que se pueden realizar durante un turno para el participante X. menu_turno(X) :- write('-----------------------'), nl, write('MENÚ ACCIONES DEL TURNO'), nl, write('-----------------------'), nl, write('1.- Lanzar dado.'), nl, write('2.- Ver tablero.'), nl, write('0.- Rendirse.'), nl, nl, write('Introduzca una opción [0 - 2]: '), nl, read(OPCION), skip(10), nl, menu_turno(X, OPCION).

%Ejecuta para el participante X, la opción indicada en el segundo argumento, del menú de acciones en un turno. menu_turno(X, 1) :- lanzar_dado(X), !. menu_turno(X, 2) :- participante(X), dibujar_tablero, esperar_intro, nl, nl, menu_turno(X), !. menu_turno(X, 0) :- participante(X), rendirse(X), !. menu_turno(X, _) :- participante(X), write('Opción incorrecta. Debe elegir una opción en el rango [0-2].'), nl, nl, menu_turno(X).

%%%%%%%%%%%%%%%%% %MENÚ DEL DIARIO% %%%%%%%%%%%%%%%%%

%Representa en pantalla el menú del diario del participante indicado en el primer argumento, con el diario en la entrada numerada en el segundo argumento.

Javier Gago Romero

Página 59

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

menu_diario(X, P) :- write('---------------'), nl, write('MENÚ DEL DIARIO'), nl, write('---------------'), nl, write('1.- Leer la última entrada escrita del diario.'), nl, write('2.- Pasar página del diario y leerla.'), nl, write('0.- Volver.'), nl, nl, write('Introduzca una opción [0 - 2]: '), nl, read(OPCION), skip(10), nl, menu_diario(X, P, OPCION).

%Ejecuta para el participante X, la opción indicada en el tercer argumento, del menú del diario, teniendo el diario abierto por la página indicada en el segundo argumento. menu_diario(X, _, 1) :- diario(X, L), nth1(1, L, E), proper_length(L, LONG), nl, write('Página '), write(LONG), write(':'), nl, nl, write(E), nl, nl, esperar_intro, menu_diario(X, 1), !. menu_diario(X, _, 1) :- nl, write('No hay entradas en el diario.'), nl, nl, esperar_intro, menu_diario(X, 1), !. menu_diario(X, P, 2) :- diario(X, L), PN is P + 1, proper_length(L, LONG), PN > LONG, nl, write('No hay más entradas en el diario.'), nl, nl, esperar_intro, menu_diario(X, P), !. menu_diario(X, P, 2) :- diario(X, L), PN is P + 1, proper_length(L, LONG), nth1(PN, L, E), nl, N is LONG - P, write('Página '), write(N), write(':'), nl, nl, write(E), nl, nl, esperar_intro, menu_diario(X, PN), !. menu_diario(X, P, 2) :- nl, write('No hay entradas en el diario.'), nl, nl, esperar_intro, menu_diario(X, P), !.

Javier Gago Romero

Página 60

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

menu_diario(_, _, 0) :- !. menu_diario(X, P, _) :- write('Opción incorrecta. Debe elegir una opción en el rango [0-2].'), nl, nl, menu_diario(X, P).

%%%%%%%%%%%%%%%% %MENÚ PRINCIPAL% %%%%%%%%%%%%%%%%

%Representa en pantalla el menú principal del juego. menu_principal :- write('--------------'), nl, write('MENÚ PRINCIPAL'), nl, write('--------------'), nl, write('1.- Jugar nueva partida.'), nl, write('2.- Consultar estadísticas.'), nl, write('3.- Reglas del juego.'), nl, write('4.- Historia y curiosidades sobre el juego de la oca.'), nl, write('5.- Leer diario.'), nl, write('6.- Leer de nuevo la introducción.'), nl, write('7.- Acerca de.'), nl, write('0.- Salir.'), nl, nl, write('Introduzca una opción [0 - 7]: '), nl, read(OPCION), skip(10), nl, menu_principal(OPCION).

%Ejecuta el número de opción indicada del menú principal del juego. menu_principal(1) :- nueva_partida, menu_principal, !. menu_principal(2) :- estadisticas, nl, menu_principal, !. menu_principal(3) :- reglas, nl, menu_principal, !. menu_principal(4) :- historia_y_curiosidades, nl, menu_principal, !. menu_principal(5) :- menu_diario(jugador, 1), menu_principal, !. menu_principal(6) :- introduccion, nl, menu_principal, !. menu_principal(7) :- acerca_de, nl, menu_principal, !. menu_principal(0) :- salir, !. menu_principal(_) :- write('Opción incorrecta. Debe elegir una opción en el rango [0-7].'), nl, nl, menu_principal.

Javier Gago Romero

Página 61

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

/* INFORMACIÓN ESTADÍSTICA DE LAS PARTIDAS JUGADAS. */ %%%%%%%%%%%%% %INFORMACIÓN% %%%%%%%%%%%%%

%Muestra información estadística de las partidas jugadas. estadisticas :- write('-----------------------'), nl, write('INFORMACIÓN ESTADÍSTICA'), nl, write('-----------------------'), nl, escribir_nombre(jugador), write(' VS '), escribir_nombre(cpu), nl, nl, victorias(jugador, VJ), victorias(cpu, VC), PJ is VJ + VC, write('Partidas Jugadas: '), write(PJ), write('.'), nl, write('Partidas Ganadas por '), escribir_nombre(jugador), write(': '), write(VJ), write('.'), nl, write('Partidas Ganadas por '), escribir_nombre(cpu), write(': '), write(VC), write('.'), nl, grafica_partidas.

%%%%%%%%% %GRÁFICA% %%%%%%%%%

%Muestra la gráfica de partidas ganadas por el jugador frente a las ganadas por la CPU. grafica_partidas :- victorias(jugador, VJ), victorias(cpu, VC), PJ is VJ + VC, PJ == 0, write('Aún no se han jugado partidas. No hay gráfica que representar.'), nl, !. grafica_partidas :- victorias(jugador, VJ), victorias(cpu, VC),

Javier Gago Romero

Página 62

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

PJ is VJ + VC, nl, write('*******'), nl, write('GRÁFICA'), nl, write('*******'), nl, write('J: '), dibujar_grafica(jugador), write(' ('), PCJ is VJ / PJ * 100, format('~2f', [PCJ]), write('%).'), nl, write('C: '), dibujar_grafica(cpu), write(' ('), PCC is VC / PJ * 100, format('~2f', [PCC]), write('%).'), nl, nl, write('J -> '), escribir_nombre(jugador), write('; '), write('C -> '), escribir_nombre(cpu), write('.'), nl.

%Dibuja la barra gráfica de victorias del participante X. dibujar_grafica(X) :- victorias(X, V), dibujar_grafica(V, 0).

%Dibuja una barra gráfica de victorias. El valor alcanzado debe ser V, y actualmente está en el valor N. %Si N es mayor o igual que V, se produce el caso base de la recursión, y se finaliza de dibujar la barra. %Si no se está en el caso base, entonces se representa una barra vertical, y se llama de nuevo recursivamente %al predicado dibujar_grafica, incrementando el segundo argumento en uno. dibujar_grafica(V, N) :- N >= V, !. dibujar_grafica(V, N) :- write('|'), M is N + 1, dibujar_grafica(V, M).

/* MENSAJES DE INICIO DEL PROGRAMA. */ %Escribe la cabecera del programa. titulo_programa :- write('---------------------------------------'), nl, write('Fundamentos de Inteligencia Artificial.'), nl, write('Actividad Obligatoria 2.'), nl, write('---------------------------------------'), nl, write('*************************'), nl, write('EL JUEGO DE LA PROLOG-OCA'), nl, write('*************************'), nl, write('Javier Gago Romero, Curso 2016-2017.'), nl.

Javier Gago Romero

Página 63

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

%Escribe en pantalla una breve historia de introducción al juego. introduccion :- write('Nuestra historia comienza en el curso académico 2016-2017. Un estudiante de Fundamentos de Inteligencia Artificial, cuyo nombre es incierto, se disponía a comenzar la actividad obligatoria 2 de la asignatura.'), nl, nl, write('Lo primero que hizo nuestro alumno, fue acceder al curso virtual, leer los mensajes del foro, y acto seguido, proceder a descargar el enunciado de la práctica que estaba ya disponible.'), nl, nl, esperar_intro, dibujar_curso_virtual, esperar_intro, write('La práctica consistía en realizar un sistema basado en reglas, empleando el lenguaje Prolog, creando un mundo virtual que debía cumplir con una serie de requisitos.'), nl, nl, write('El primer paso consistía, en idear ese mundo virtual, tener una idea sobre qué hacer, y para ello, debía elegir un tema de los indicados en el enunciado de la actividad.'), nl, nl, write('¿De qué hacer la práctica? ¿Las vacaciones? ¿La familia? ¿Mascotas tal vez?... había una buena cantidad de temas para ello.'), nl, nl, write('Con mucha ilusión, el alumno comenzó a sumergirse entre manuales de Prolog e instaló el intérprete SWIPROLOG en su equipo.'), nl, esperar_intro, write('El logo del intérprete de Prolog, un búho de color naranja, le llamó la atención y le resultó divertido.'), nl, nl, write('Sin embargo, aunque el estudiante comenzó con mucha ilusión, las primeras horas fueron duras, pues no llegaba la inspiración...'), nl, nl, write('"¿QUÉ TEMA ELEGIR?" - se preguntaba continuamente.'), nl, nl, esperar_intro, write('Pasaron unos días, sin que la inspiración llegara.'), nl, nl, write('El alumno decidió entonces navegar un poco para distraerse, y ver si la idea llegaba sin más.'), nl, nl, write('El logo del búho naranja, volvía a su mente cada vez que intentaba pensar en alguna otra cosa.'), nl, nl, write('"¿Sería buena idea una práctica de mascotas, donde la mascota fuera un búho naranja?" - se preguntaba el alumno.'), nl, esperar_intro, write('Navegando por la red, localizó merchandising sobre el intérprete SWI-PROLOG.'), nl, nl, write('"¡Vaya!, pero si venden de todo, desde tazas de café hasta camisetas." - se sorprendió el alumno.'), nl, nl, write('Entonces, pensó que sería una buena idea tener una taza del búho naranja. Le había gustado mucho, y quién sabe, igual le llegaba la inspiración con ella.'), nl, esperar_intro, write('Al dia siguiente, su pedido llegó... ¡La taza que quería! Y dibujada en ella, por supuesto estaba el búho del SWI.'), nl, dibujar_buhito, nl, esperar_intro, write('El alumno sirvió café en su nueva taza, y retomó el enunciado de la actividad con energías renovadas.'), nl, nl, write('¡Estaba convencido de que ahora SÍ, llegaría por fin la inspiración.....!'), nl, nl,

Javier Gago Romero

Página 64

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

write('Sin embargo, el cansancio se apoderó del alumno, y a pesar de haber bebido buena cantidad de café, cayó finalmente en los brazos de Morfeo...'), nl, nl, esperar_intro, dormir(0.2, 4), esperar_intro, write('Nuestro querido alumno despertó entonces... pero algo era diferente ahora.'), nl, nl, write('¿¿¿QUÉ HABÍA OCURRIDO???'), nl, nl, write('¡NO RECORDABA TAN SIQUIERA SU PROPIO NOMBRE!.'), nl, nl, write('Su equipo estaba encendido, con el intérprete de Prolog en ejecución. El fichero que estaba ejecutándose se denominaba "juegoPrologOca.pl".'), nl, esperar_intro, write('¿Habría escrito él todo ese código? Parecía un extraño juego de la oca, ya implementado.'), nl, nl, write('Sin embargo, en el código aún no había comentarios, ni ningún documento que le permitiera recordar o averigüar algo sobre esto.'), nl, nl, write('Pero peor aún, ¡LA PUERTA DE LA HABITACIÓN ESTABA CERRADA BAJO LLAVE!'), nl, nl, write('¿Le habría encerrado alguien ahí? Y de ser así... ¿con qué propósito?'), nl, nl, write('El alumno registró toda la habitación en busca de alguna llave, o alguna pista que le permitiera recordar algo... pero nada...'), nl, nl, write('¡MENUDA LOCURA!'), nl, nl, write('La única forma de intentar hacer que las cosas vuelvan a su normalidad, es intentar jugar a aquel extraño juego de la oca, y ver si eso despertaba sus recuerdos.'), nl, write('Quizás, mantener un diario hasta recuperar la memoria, podría serle útil para organizar sus pensamientos e ideas. Había muchas incógnitas por resolver.'), nl, nl, write('Con este pensamiento, el alumno teclea "inicio." en el intérprete de Prolog para comenzar la ejecución del programa.'), nl, esperar_intro, write('Bienvenidos al juego de la Prolog-Oca.'), nl, write('Mucha suerte, la necesitarás.'), nl, esperar_intro.

/* MOSTRAR INFORMACIÓN EN EL PROGRAMA. */ %Muestra en pantalla las reglas del juego. reglas :- write('----------------'), nl, write('REGLAS DEL JUEGO'), nl, write('----------------'), nl, nl,

Javier Gago Romero

Página 65

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

write('El juego de la Prolog-Oca es el clásico juego de la oca, pero en un tablero con temática sobre Inteligencia Artificial.'), nl, write('Hay diversas variantes del juego tradicional, y a menudo suelen añadirse "reglas caseras", que añaden ciertas diferencias en la manera de jugar.'), nl, nl, write('Debido a esto, a continuación se detallan todas las reglas del juego de la Prolog-Oca:'), nl, write(' -> Cada participante lanza un dado de 6 caras (d6), durante su turno.'), nl, write(' -> El jugador avanza por el tablero tantas casillas como se indique en el dado lanzado. El tablero tiene 63 casillas.'), nl, write(' -> El objetivo, es ser el primer jugador en llegar a la casilla de la victoria, que es la casilla número 63.'), nl, write(' -> Si un jugador debe desplazarse más allá de la casilla 63, entonces rebota, y cuenta hacia atrás las casillas en exceso. Es decir, debe caer exactamente en la casilla para ganar.'), nl, write(' Por ejemplo, si un jugador se encuentra en la casilla 62, necesita un 1 para caer en la casilla 63. Si obtiene un 3 en los dados, entonces cuenta 63, 62, 61, y pasa a la casilla 61.'), nl, write(' -> Si el jugador cae en una casilla normal, entonces cede su turno al siguiente participante.'), nl, write(' -> Si el jugador cae en una casilla especial, entonces se aplican las reglas de dicha casilla. Dependiendo de la casilla, es posible que el jugador continue volviendo a lanzar el dado, sin ceder su turno.'), nl, nl, esperar_intro, write('A continuación se indican las casillas especiales:'), nl, nl, write('CASILLA DE BUHITO'), nl, write('Se corresponde con la casilla de oca, del juego tradicional. El jugador avanza hasta la siguiente casilla de buhito, y vuelve a lanzar los dados sin ceder el turno.'), nl, nl, write('CASILLA DE PREDICADO'), nl, write('Se corresponde con la casilla de puente, del juego tradicional. El jugador se desplaza hasta otra casilla de predicado. Si no hay más casillas de predicado hacia delante en el tablero, entonces el jugador retrocede a la anterior casilla de predicado. Cuando el jugador cae en estas casilla continua lanzando sus dados, y no cede su turno.'), nl, nl, write('CASILLA DE CORTE'), nl, write('Se corresponde con la casilla de dados, del juego tradicional. El jugador se desplaza hasta otra casilla de corte. Si no hay más casillas de corte hacia delante en el tablero, entonces el jugador retrocede a la anterior casilla de corte. Cuando el jugador cae en estas casilla continua lanzando sus dados, y no cede su turno.'), nl, nl, write('CASILLA DE ERROR LÓGICO'), nl, write('Se corresponde con la casilla de posada, del juego tradicional. El jugador que cae en esta casilla pierde dos turnos, en los cuales no puede lanzar los dados, y debe esperar.'), nl, nl, esperar_intro, write('CASILLA DE RAMA INFINITA'), nl, write('Se corresponde con la casilla del pozo, del juego tradicional. El jugador que cae en esta casilla pierde dos turnos, en los cuales no puede lanzar los dados, y debe esperar.'), nl, nl, write('CASILLA DE ERROR SINTÁCTICO'), nl, write('Se corresponde con la casilla de cárcel, del juego tradicional. El jugador que cae en esta casilla pierde tres turnos, en los cuales no puede lanzar los dados, y debe esperar.'), nl, nl, write('CASILLA DE RECURSIÓN'), nl, write('Se corresponde con la casilla de laberinto, del juego tradicional. El jugador que cae en esta casilla se desplaza inmediatamente hasta la casilla 30.'), nl, nl,

Javier Gago Romero

Página 66

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

write('CASILLA DE RETRACT'), nl, write('Se corresponde con la casilla de calavera, del juego tradicional. El jugador que cae en esta casilla se desplaza inmediatamente hasta la casilla 0, por lo que debe comenzar el recorrido por el tablero de nuevo.'), nl, nl, write('CASILLA DE VICTORIA'), nl, write('Se corresponde con la última casilla, casilla 63, del juego tradicional. El jugador que cae en esta casilla gana la partida.'), nl.

%Muestra en pantalla historia y curiosidades del juego de la oca. historia_y_curiosidades :- write('-------------------------------------------'), nl, write('HISTORIA Y CURIOSIDADES DEL JUEGO DE LA OCA'), nl, write('-------------------------------------------'), nl, nl, write('El juego de la oca es un juego de mesa para dos o más jugadores. Cada jugador avanza su ficha por un tablero en forma de espiral con 63 casillas con dibujos. Dependiendo de la casilla en la que se caiga, se puede avanzar o por el contrario retroceder, y en algunas de ellas está indicado un castigo. En su turno cada jugador tira dos dados (o uno dependiendo de las distintas versiones) que le indican el número de casillas que debe avanzar. Gana el juego el primer jugador que llega a la casilla 63, "el jardín de la oca".'), nl, nl, write('HISTORIA'), nl, write('--------'), nl, write('Las primeras versiones comerciales del juego aparecieron en la década de 1880 y estaban decoradas con motivos alusivos a la época, como por ejemplo niños con vestidos del momento. Se supone que la primera versión fue un juego de mesa regalado por Francisco I de Médici de Florencia a Felipe II de España entre 1574 y 1587. El Ejemplar más antiguo que se conoce de este juego data del 1640 realizado en madera de origen veneciano.'), nl, nl, write('ORIGEN'), nl, write('------'), nl, write('Existen tres versiones sobre su origen:'), nl, write(' -> Podría ser una creación de los griegos durante el asedio a Troya. Esta teoría se basa en el disco de Phaistos, procedente del 2000 a. C., que podría ser un tablero del juego.'), nl, write(' -> Otros piensan que nació en la Florencia de los Médici y que luego se extendió por las cortes de Europa.'), nl, write(' -> La última teoría afirma que lo crearon los templarios en el siglo XII inspirándose en el Camino de Santiago. También se le relaciona con los buenos constructores en la época de Alfonso I el Batallador.'), nl, nl, esperar_intro, write('CASILLAS ESPECIALES'), nl, write('-------------------'), nl, write('LA OCA'), nl, write('Se encuentran normalmente ubicadas cada nueve casillas desde las casillas 5 y 9. Cuando se cae en una de estas casillas, se avanza hasta la siguiente oca y, en ocasiones, se vuelve a tirar. Tradicionalmente se dice "de oca a oca y tiro porque me toca" (o "de oca en oca y tiro porque me toca".'), nl, write('En ciertas versiones también hay que fijarse en los picos de las ocas, si están hacia delante, hay que seguir hacia adelante, pero si el pico está hacia atrás, hay que retroceder. O puedes quedarte en el sitio que estás si la casilla tiene un número impar.'), nl, nl,

Javier Gago Romero

Página 67

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

write('EL PUENTE'), nl, write('Se encuentran normalmente ubicados en las casillas 6 y 12. Cuando se cae en una de estas casillas, se avanza o retrocede hasta el otro puente y, en ocasiones, se vuelve a tirar. Tradicionalmente se dice "de puente a puente y tiro porque me lleva la corriente".'), nl, nl, write('LA POSADA'), nl, write('Se encuentra normalmente ubicada en la casilla 19. Cuando se cae en esta casilla, suelen perderse 2 turnos. En algunas ocasiones dependiendo de cuántos días aparezcan escritos en el dibujo.'), nl, nl, write('EL POZO'), nl, write('Se encuentra normalmente ubicado en la casilla 31. Cuando se cae en esta casilla, suelen o bien perderse 2 turnos o bien permanecer el jugador sin jugar hasta que otro caiga en su lugar. Y si están jugando sólo dos personas y el otro jugador cae en la calavera y empieza del principio, el castigo de estar sin jugar se invalida y se sigue jugando normal, saliendo del pozo en cuanto te toque tirar.'), nl, nl, esperar_intro, write('LOS DADOS'), nl, write('Se encuentran normalmente ubicados en las casillas 26 y 53. Cuando se cae en una de estas dos casillas, se suman las cifras que aparezcan en la casilla y se avanza ese número de casillas. Existen otras versiones en las que se avanza o se retrocede a la otra con el mismo dibujo y se vuelve a tirar diciendo "De dado a dado y tiro porque me ha tocado", "De dados a dados y tiro porque son cuadrados" o "De dados a dados y tiro por los soldados" en las que simplemente se vuelve a tirar. También existe la regla de que cayendo en los dados de la casilla 26, si en la siguiente tirada saca un 3 en el dado, pasa el jugador a la 53, "en los dados, con un tres, paso a la cincuenta y tres".'), nl, nl, write('EL LABERINTO'), nl, write('Ubicado en la casilla 42, cuando se cae en el laberinto, se está obligado a retroceder a la casilla 30. Se suele decir: "Del laberinto al 30". En otras versiones, se queda atrapado y no se puede seguir avanzando hasta sacar un determinado número con los dados.'), nl, nl, write('LA CÁRCEL'), nl, write('Ubicada en la casilla 52, cuando se cae en la cárcel, suelen perderse 3 turnos. Otra opción es que si se cae en la cárcel, la ficha queda inmovilizada hasta que otro jugador caiga y te rescate, quedando éste atrapado.'), nl, nl, write('LA CALAVERA O LA MUERTE'), nl, write('Ubicada en la casilla 58, cuando se cae en la calavera o muerte, se vuelve a empezar desde la casilla de inicio.'), nl, nl, write('ÚLTIMA CASILLA'), nl, write('Usualmente el juego tiene 63 casillas y se debe llegar a la última con el puntaje exacto, de lo contrario se retrocede tantas casillas como puntos sobren.'), nl, nl, esperar_intro, write('JUEGO DE LA OCA EN TELEVISIÓN'), nl, write('-----------------------------'), nl, write('El gran juego de la oca fue también un exitoso programa de juegos de la televisión española.'), nl, nl, write('CAMPEONATO DEL MUNDO DE LA OCA'), nl, write('------------------------------'), nl, write('Se realiza en la localidad de Alpartir, el primer fin de semana de octubre.'), nl, nl, write('VERSIONES'), nl, write('---------'), nl,

Javier Gago Romero

Página 68

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

write('Existe una versión relacionada con los juegos de beber, llamada: Ocalimocho.'), nl.

%Muestra en pantalla el Acerca De del programa. acerca_de :- write('Acerca de ... El juego de la Prolog-Oca. Curso 2016-2017. Javier Gago Romero.'), nl, nl, write('El juego de la Prolog-Oca es el clásico juego de la oca, con un tablero con temática sobre Inteligencia Artificial, e implementado en lenguaje Prolog.'), nl.

/* REPRESENTACIONES GRÁFICAS EN EL JUEGO. */ %Dibuja un dado, visto desde la cara de la puntuación indicada mediante argumento. dibujar_dado(1) :- write(' ----- '), nl, write('|

|'), nl,

write('| . |'), nl, write('|

|'), nl,

write(' ----- '), nl. dibujar_dado(2) :- write(' ----- '), nl, write('| . |'), nl, write('|

|'), nl,

write('| . |'), nl, write(' ----- '), nl. dibujar_dado(3) :- write(' ----- '), nl, write('| . |'), nl, write('| . |'), nl, write('| . |'), nl, write(' ----- '), nl. dibujar_dado(4) :- write(' ----- '), nl, write('| . . |'), nl, write('|

|'), nl,

write('| . . |'), nl, write(' ----- '), nl. dibujar_dado(5) :- write(' ----- '), nl, write('| . . |'), nl,

Javier Gago Romero

Página 69

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

write('| . |'), nl, write('| . . |'), nl, write(' ----- '), nl. dibujar_dado(6) :- write(' ----- '), nl, write('| . . |'), nl, write('| . . |'), nl, write('| . . |'), nl, write(' ----- '), nl.

%Dibuja el tablero del juego. dibujar_tablero :- write('.-------------------------------------------------.'), nl, write('| 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |'), nl, write('| | | B | | | |

| B | | EL |'), nl,

write('|-------------------------------------------------|'), nl, write('| 26 | 51 | 50 | 49 | 48 | 47 | 46 | 45 | 44 | 15 |'), nl, write('| C | | B | | | | | B | | |'), nl, write('|-------------------------------------------------|'), nl, write('| 27 | 52 |

Buhito

| 43 | 14 |'), nl,

write('| B | ES | /\\------------/\\

| | B |'), nl,

write('|---------. | ^O """" O^ |

.---------|'), nl,

write('| 28 | 53 | | \\ write('| | C | | write('|---------. |

\\ /

/ |

63 | 42 | 13 |'), nl,

|

| R | |'), nl,

\\/ ictoria.

write('| 29 | 54 | ^---" -----"---^ write('| | B |

.--------------|'), nl, | 62 | 41 | 12 |'), nl,

| | B | P |'), nl,

write('|-------------------------------------------------|'), nl, write('| 30 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 40 | 11 |'), nl, write('| | | | | RT | B | | | | |'), nl, write('|-------------------------------------------------|'), nl, write('| 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 10 |'), nl, write('| RI | B | | | | B | | | | |'), nl, write('|-------------------------------------------------|'), nl, write('| 1

| 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |'), nl,

write('|

| | | | B | P | | | B |'), nl,

Javier Gago Romero

Página 70

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

write('^-------------------------------------------------^'), nl, nl, posicion(jugador, PJ), posicion(cpu, PC), escribir_nombre(jugador), write(' está en la casilla '), write(PJ), write('.'), nl, escribir_nombre(cpu), write(' está en la casilla '), write(PC), write('.'), nl, nl, write('LEYENDA'), nl, write('-------'), nl, write('B: Buhito; P: Predicado; EL: Error Lógico; C: Corte; RI: Rama Infinita; R: Recursión; ES: Error Sintáctico; RT: Retract.; V: Victoria.'), nl.

%Dibuja el buhíto que representa al logo del intérprete de Prolog, SWI. dibujar_buhito :- write('.___.'), nl, write('(@,@)'), nl, write('( _ )'), nl, write(' " "').

dibujar_curso_virtual :- write('

_________________________________________'), nl,

write(' .\'`

`\'.'), nl,

write(' | _________________________________________ |'), nl, write(' | \'\\.---------------------------------------./\' |'), nl, write(' | || |UNED| uForums

|| |'), nl,

write(' | || ----------------------------------.

|| |'), nl,

write(' | || ||U| https://2017.cursosvirtual.. | write(' | || ----------------------------------¨

|| |'), nl, || |'), nl,

write(' | || Mi curso | Nombre del foro write(' | || -------- |

|| |'), nl,

|| |'), nl,

write(' | || Plan de T..|Consultas generales

|| |'), nl,

write(' | || Novedades |Consultas sobre el bloque I || |'), nl, write(' | || Envío de.. |Consultas sobre el bloque II|| |'), nl, write(' | || Califica.. |Consultas sobre el bloque.. || |'), nl, write(' | || Tutoría write(' | ||

|Consultas sobre el bloque IV|| |'), nl,

|Consultas sobre el bloque V || |'), nl,

write(' | || Mi calend..|Consultas sobre el bloque VI|| |'), nl, write(' | ||

|Consultas sobre la activ.. || |'), nl,

write(' | || Grados

|.......................... || |'), nl,

write(' | || Fundament..|

Javier Gago Romero

|| |'), nl,

Página 71

FIA

Fundamentos de Inteligencia Artificial - AO2

Curso 2016-2017

write(' | \'/\\_______________________________________/\\\' |'), nl, write(' \' `-----------------------------------------\' '), nl, write('

\\

.-.

/'), nl,

write('

\'.__~~~ ____()__()_()()() __________((_))__.\''), nl,

write(' _________________\';========;\'__________________'), nl, write(' / _/__/_//_// _/_/ /_//_// __/__/_// write(' /_/__/_/_/ __/ _/.-\'\'\'\'\'-. /_// write(' / _.-..-..-.

.\'

`.

write('/ /_| || || |-. .\'

_/ _//_/\\'), nl,

.-..-..-./_//_||'), nl,

`. .-| || || | /_/ //'), nl,

write('----\\ \' \' \' / write(' ~~~~\\

\\ ` \' \' /----(('), nl,

//

\\ \\

/~~~~~ ))'), nl,

write('

`\'--\'`-:

write('

\\ |

| / .\'` `\\)'), nl,

write('

`\'-:

:-\'` | `-../|'), nl,

write('

\'

\'

\`-\'`|/'), nl,

write('

\\

/

`\'-\''), nl,

write('

\'.

write(' write('

\\'), nl,

:-`\'--\'` __,