Inteligencia en Redes de Comunicaciones PRÁCTICA FINAL “Solución de un problema con CLIPS: Expert-Juego. Las 7 y media” - Elena A. Álvarez Conde Problema El problema a resolver es la implementación del juego de las 7 y media, siendo uno de los jugadores el PC y el otro el propio usuario. Por lo que se tratará de un problema interactivo. Solución Formalización del problema Reglas Cada carta tiene su valor excepto las figuras que valen un medio. El usuario comienza a jugar, y por tanto está en desventaja ya que la banca es el PC. Cuando existe empate, gana la banca, y si el usuario se pasa también gana la banca. Representación del conocimiento En una arquitectura de lenguaje basado en reglas, representaremos el conocimiento como un sistema de producción. Donde tenemos: - Hechos: conocimiento de tipo estático (información) sobre el mundo real - Reglas: conocimiento de tipo dinámico para la gestión de la base de hechos. - Un motor de inferencias o sistema de control: se encargará de aplicar las reglas a los hechos. Por comparación de patrones se “activarán” un número de reglas. Se “disparará” la más adecuada para la resolución del problema. Comenzaremos modelando el problema en términos de hechos iniciales y de objetivos a conseguir. Los hechos iniciales son las cartas de la baraja. El objetivo es conseguir 7 y media y sobre todo intentar no pasarme. Para la representación de cartas como utilizo hechos estructurados (templates): (deftemplate carta (slot nombre) ; Indica el nombre de la carta (slot palo) ; Si es OROS COPAS ESPADAS O BASTOS (slot valor) ; Valor en el juego de las 7 y media (slot numero) ; Colocación de la carta en la baraja ) Para definir las reglas me valgo de otro hecho extra llamado fase, que me definirá en qué punto del juego estoy. El juego comienza pidiéndole confirmación de comienzo al usuario, y esperando su respuesta. 1 (defrule inicio-programa (fase inicio) => (printout t "¿Empezamos? (ACEPTAR: s (assert (eleccion (read)))) CANCELAR: n) ") A continuación se evalúa si la respuesta es correcta o no, si no lo es, se especifican las posibles opciones. Si lo es, y es que sí se pasa a la siguiente fase del juego “obtener-carta”, si es que no se muestra un mensaje de salida y se cierra el juego. (defrule respuesta-valida ?fase <- (fase inicio) ?eleccion <- (eleccion ?aux&:(or (eq ?aux s) (eq ?aux n))) => (printout t "Respuesta-valida" crlf) (retract ?fase) (if (eq ?aux n) then (retract ?eleccion) (printout t "Hasta otra" crlf) (halt) else (assert (fase obtener-carta)) (retract ?eleccion) ) ) (defrule respuesta-no-valida ?fase <- (or (fase inicio) (fase mostrar-carta)) ?eleccion <- (eleccion ?aux&~s&~n) => (retract ?fase ?eleccion) (assert (fase inicio)) (printout t "Elige s o n." crlf)) En este punto empezamos el juego propiamente dicho. Para ello definiremos tres variables globales que representarán la puntuación obtenida por el usuario, la obtenida por el PC y el punto de la baraja donde nos encontramos. (defglobal ?*puntuacion* = 0 ?*num* = 0 ?*puntuacion-pc* = 0 ) 2 A continuación elegimos una carta al azar de la baraja. (defrule elegir ?fase <- (or (fase obtener-carta) (fase juego-pc)) => (bind ?num (random)) (while (or (> ?*num* 40) (eq ?*num* 0)) (bind ?*num* (random))) (printout t ?*num* crlf) (retract ?fase) (assert (fase mostrar-carta))) Y la mostramos. En esta regla, modificamos la puntuación del usuario y analizamos su puntuación actual para saber si se ha pasado. Si no es así le damos la opción de elegir otra carta o plantarse. (defrule mostrar ?fase <- (fase mostrar-carta) ?x <- (carta (nombre ?n) (palo ?p) (valor ?v) (numero =(?*num*) )) => (printout t ?n crlf) (bind ?puntuacion (+ ?*puntuacion* ?v)) (printout t " Puntuacion = " ?*puntuacion* crlf) (if (> ?*puntuacion* 7.5) then (printout t "Te has pasado, tu puntuacion es " ?*puntuacion* crlf) (printout t "Has perdido" crlf) (retract ?fase) (halt) else (printout t "¿Quieres otra carta? (ACEPTAR: s CANCELAR: n) ") (assert (eleccion (read)) (printout t crlf)) (retract ?x)) Si elige otra carta vuelve a la regla elegir, teniendo en cuenta que las cartas que ya han salido se van sacando de la baraja con retract, y si no, se pasa el turno del juego al PC. (defrule otra-carta ?fase <- (fase mostrar-carta) ?eleccion <- (eleccion ?aux&:(or (eq ?aux s) (eq ?aux n))) => (printout t "Respuesta-valida" crlf) (retract ?fase) (if (eq ?aux n) then (retract ?eleccion) (printout t "Tu puntuacion final es " ?*puntuacion* crlf) (assert (fase juego-pc)) else (assert (fase obtener-carta)) (retract ?eleccion))) 3 Por último el PC, juega hasta que su puntuación es superior a la del jugador, o hasta que se pasa, en cuyo caso pierde. También en esta regla se muestran los mensajes correspondientes por pantalla. Y con ella termina la programación del juego. (defrule inicio-pc ?fase <- (fase juego-pc) (and (< ?*puntuacion-pc* ?*puntuacion*) (< ?*puntuacion* 7.5)) ?x <- (carta (nombre ?n) (palo ?p) (valor ?v) (numero =(?*num*) )) => (printout t ?n crlf) (bind ?puntuacion (+ ?*puntuacion-pc* ?v)) (printout t " Puntuacion PC= " ?*puntuacion-pc* crlf) (if (and (>= ?*puntuacion-pc* ?*puntuacion*) (<= ?*puntuacion-pc* 7.5)) then (printout t "Gana la banca" crlf) (printout t "Tu puntuacion es " ?*puntuacion* crlf) (printout t "La puntuacion de la banca es " ?*puntuacion-pc* crlf) (retract ?fase) (halt) else (if (> ?*puntuacion-pc* 7.5) (printout t "La banca se ha pasado. Has ganado!!" crlf) (retract ?fase)) (retract ?x) ) ) Motor de inferencias Como podemos ver a lo largo de todo el programa he optado por utilizar conocimiento de control, sabiendo en que fase del juego estoy en cada momento. Implementación de la solución Para la implementación de la solución creamos unos hechos iniciales de partida (con “deffacts”) que corresponden a las distintas cartas de la baraja. Además añado el hecho de inicio que indica que estamos en la fase de inicio. Después, basta arrancar el programa con las sentencias (reset) y (run). (deffacts cartas (carta (nombre (carta (nombre (carta (nombre (carta (nombre (carta (nombre (carta (nombre (carta (nombre (carta (nombre "As de Oros") (palo OROS) (valor 1) (numero 1)) "Dos de Oros") (palo OROS) (valor 2) (numero 2)) "Tres de Oros") (palo OROS) (valor 3) (numero 3)) "Cuatro de Oros") (palo OROS) (valor 4) (numero 4)) "Cinco de Oros") (palo OROS) (valor 5) (numero 5)) "Seis de Oros") (palo OROS) (valor 6) (numero 6)) "Siete de Oros") (palo OROS) (valor 7) (numero 7)) "Sota de Oros") (palo OROS) (valor 0.5) (numero 8)) 4 (carta (nombre "Caballo de Oros") (palo OROS) (valor 0.5) (numero 9)) (carta (nombre "Rey de Oros") (palo OROS) (valor 0.5) (numero 10)) (carta (carta (carta (carta (carta (carta (carta (carta (carta (carta (nombre (nombre (nombre (nombre (nombre (nombre (nombre (nombre (nombre (nombre "As de Copas") (palo COPAS) (valor 1) (numero 11)) "Dos de Copas") (palo COPAS) (valor 2) (numero 12)) "Tres de Copas") (palo COPAS) (valor 3) (numero 13)) "Cuatro de Copas") (palo COPAS) (valor 4) (numero 14)) "Cinco de Copas") (palo COPAS) (valor 5) (numero 15)) "Seis de Copas") (palo COPAS) (valor 6) (numero 16)) "Siete de Copas") (palo COPAS) (valor 7) (numero 17)) "Sota de Copas") (palo COPAS) (valor 0.5) (numero 18)) "Caballo de Copas") (palo COPAS) (valor 0.5) (numero 19)) "Rey de Copas") (palo COPAS) (valor 0.5) (numero 20)) (carta (carta (carta (carta (carta (carta (carta (carta (carta (nombre (nombre (nombre (nombre (nombre (nombre (nombre (nombre (nombre "As de Espadas") (palo ESPADAS) (valor 1) (numero 21)) "Dos de Espadas") (palo ESPADAS) (valor 2) (numero 22)) "Tres de Espadas") (palo ESPADAS) (valor 3) (numero 23)) "Cuatro de Espadas") (palo ESPADAS) (valor 4) (numero 24)) "Cinco de Espadas") (palo ESPADAS) (valor 5) (numero 25)) "Seis de Espadas") (palo ESPADAS) (valor 6) (numero 26)) "Siete de Espadas") (palo ESPADAS) (valor 7) (numero 27)) "Sota de Espadas") (palo ESPADAS) (valor 0.5) (numero 28)) "Caballo de Espadas") (palo ESPADAS) (valor 0.5) (numero 29)) (carta (nombre "Rey de Espadas") (palo ESPADAS) (valor 0.5) (numero 30)) (carta (carta (carta (carta (carta (carta (carta (carta (carta (carta (nombre (nombre (nombre (nombre (nombre (nombre (nombre (nombre (nombre (nombre "As de Bastos") (palo BASTOS) (valor 1) (numero 31)) "Dos de Bastos") (palo BASTOS) (valor 2) (numero 32)) "Tres de Bastos") (palo BASTOS) (valor 3) (numero 33)) "Cuatro de Bastos") (palo BASTOS) (valor 4) (numero 34)) "Cinco de Bastos") (palo BASTOS) (valor 5) (numero 35)) "Seis de Bastos") (palo BASTOS) (valor 6) (numero 36)) "Siete de Bastos") (palo BASTOS) (valor 7) (numero 37)) "Sota de Bastos") (palo BASTOS) (valor 0.5) (numero 38)) "Caballo de Bastos") (palo BASTOS) (valor 0.5) (numero 39)) "Rey de Bastos") (palo BASTOS) (valor 0.5) (numero 40)) ) (deffacts inicio (fase inicio)) 5