Trabajo Práctico de Inteligencia Artificial ”Juego TA-TE-TI” Integrantes del grupo: Nombre y Apellido Padrón Alonso, Gabriel 80895 Giorcelli, Leonardo 80126 Docente: Cabrera, José Luis Cuatrimestre/Año: 1er. Cuatrimestre/2003 Consigna del TP Partiendo de un estado inicial, determinar la secuencia de movidas que resulte óptima para llegar a la solución (es decir, que alguien gane el juego). Implementar el programa en el lenguaje Prolog. Código Fuente en Prolog (comentado) domains estado=f(char,char,char,char,char,char,char,char,char) /*El estado es un functor de 9 posiciones cada una de las cuales representa una posicion (fila, columna) del tablero de TA-TE-TI. Se expresa por filas, es decir las posiciones 1,2,3 del fuctor corresponde a las posiciones (fila 1, columna 1), (fila 1, columna 2) y (fila 1, columna 3) del tablero. Lo mismo sucede con las filas 2 y 3.*/ estadolis=estado* /*Lista de estado donde se guardara la secuencia de estados que resulte optima.*/ predicates ingresardatos /*Permite ingresar los datos del estado inicial.*/ inicio(estadolis,char,integer) /*Busca soluciones para distintos niveles de profundidad, comenzando por el nivel 1, siguiendo por el 2 y asi sucesivamente. En cuanto encuentra una solucion para un determinado nivel de profundidad termina la busqueda.*/ sol(estadolis,estadolis,integer,char) /*Busca una solucion para un determinado nivel de profundidad.*/ mem(estado,estadolis) /*Chequea que el nuevo estado no este en la lista de estados, es decir que no haya repeticion de estados.*/ condterm(estado) /*Evalua si se cumple o no la condicion de terminacion del juego TA-TE-TI.*/ ponerficha(estado,estado,integer,char) /*Coloca una ficha en el tablero y a partir de ello se obtiene un nuevo estado.*/ deterturno(char,char) /*Determina el turno, es decir la ficha ("X" o "O") que se debe colocar en el tablero en la correspondiente movida.*/ imprilis(estadolis) /*Imprime por pantalla la secuencia de estados para llegar a la solucion optima.*/ clauses ingresardatos:write("JUEGO TA-TE-TI \n"), write("----- -- -- -- \n\n"), write("Ingrese el Estado Inicial","\n\n"), write("Fila 1 Columna 1 (ingrese 'X' o 'O' o '_'): "), readchar(POS1), write("\n"), write("Fila 1 Columna 2 (ingrese 'X' o 'O' o '_'): "), readchar(POS2), write("\n"), write("Fila 1 Columna 3 (ingrese 'X' o 'O' o '_'): "), readchar(POS3), write("\n"), write("Fila 2 Columna 1 (ingrese 'X' o 'O' o '_'): "), readchar(POS4), write("\n"), write("Fila 2 Columna 2 (ingrese 'X' o 'O' o '_'): "), readchar(POS5), write("\n"), write("Fila 2 Columna 3 (ingrese 'X' o 'O' o '_'): "), readchar(POS6), write("\n"), write("Fila 3 Columna 1 (ingrese 'X' o 'O' o '_'): "), readchar(POS7), write("\n"), write("Fila 3 Columna 2 (ingrese 'X' o 'O' o '_'): "), readchar(POS8), write("\n"), write("Fila 3 Columna 3 (ingrese 'X' o 'O' o '_'): "), readchar(POS9), write("\n\n"), write("Seleccione quien comienza ('X' o 'O'): "), readchar(TURNOINI), write("\n\n"), write("Presione una tecla para obtener la solucion optima"), readchar(_), inicio([f(POS1,POS2,POS3,POS4,POS5,POS6,POS7,POS8,POS9)],TURNOINI,1). inicio(LISTAINI,INI,PROF):sol(LISTAINI,_,PROF,INI),!. inicio(LISTAINI,INI,PROF):PROFN=PROF+1, inicio(LISTAINI,INI,PROFN). sol([X|L],[X|L],_,_):condterm(X), clearwindow, write("La solucion optima es: ","\n","\n"), imprilis([X|L]),!. sol([X|L],LS,N,TURNO):N1=N-1,N1>0,ponerficha(X,Y,_,TURNO), deterturno(TURNO,TURNONUEVO), not(mem(Y,[X|L])),sol([Y,X|L],LS,N1,TURNONUEVO). ponerficha(X,Y,1,TURNO):X=f(POS1,POS2,POS3,POS4,POS5,POS6,POS7,POS8,POS9), POS1='_', Y=f(TURNO,POS2,POS3,POS4,POS5,POS6,POS7,POS8,POS9). ponerficha(X,Y,2,TURNO):X=f(POS1,POS2,POS3,POS4,POS5,POS6,POS7,POS8,POS9), POS2='_', Y=f(POS1,TURNO,POS3,POS4,POS5,POS6,POS7,POS8,POS9). ponerficha(X,Y,3,TURNO):X=f(POS1,POS2,POS3,POS4,POS5,POS6,POS7,POS8,POS9), POS3='_', Y=f(POS1,POS2,TURNO,POS4,POS5,POS6,POS7,POS8,POS9). ponerficha(X,Y,4,TURNO):X=f(POS1,POS2,POS3,POS4,POS5,POS6,POS7,POS8,POS9), POS4='_', Y=f(POS1,POS2,POS3,TURNO,POS5,POS6,POS7,POS8,POS9). ponerficha(X,Y,5,TURNO):X=f(POS1,POS2,POS3,POS4,POS5,POS6,POS7,POS8,POS9), POS5='_', Y=f(POS1,POS2,POS3,POS4,TURNO,POS6,POS7,POS8,POS9). ponerficha(X,Y,6,TURNO):X=f(POS1,POS2,POS3,POS4,POS5,POS6,POS7,POS8,POS9), POS6='_', Y=f(POS1,POS2,POS3,POS4,POS5,TURNO,POS7,POS8,POS9). ponerficha(X,Y,7,TURNO):X=f(POS1,POS2,POS3,POS4,POS5,POS6,POS7,POS8,POS9), POS7='_', Y=f(POS1,POS2,POS3,POS4,POS5,POS6,TURNO,POS8,POS9). ponerficha(X,Y,8,TURNO):X=f(POS1,POS2,POS3,POS4,POS5,POS6,POS7,POS8,POS9), POS8='_', Y=f(POS1,POS2,POS3,POS4,POS5,POS6,POS7,TURNO,POS9). ponerficha(X,Y,9,TURNO):X=f(POS1,POS2,POS3,POS4,POS5,POS6,POS7,POS8,POS9), POS9='_', Y=f(POS1,POS2,POS3,POS4,POS5,POS6,POS7,POS8,TURNO). condterm(f(FICHA,FICHA,FICHA,_,_,_,_,_,_)):FICHA<>'_'. condterm(f(_,_,_,FICHA,FICHA,FICHA,_,_,_)):FICHA<>'_'. condterm(f(_,_,_,_,_,_,FICHA,FICHA,FICHA)):FICHA<>'_'. condterm(f(FICHA,_,_,FICHA,_,_,FICHA,_,_)):FICHA<>'_'. condterm(f(_,FICHA,_,_,FICHA,_,_,FICHA,_)):FICHA<>'_'. condterm(f(_,_,FICHA,_,_,FICHA,_,_,FICHA)):FICHA<>'_'. condterm(f(FICHA,_,_,_,FICHA,_,_,_,FICHA)):FICHA<>'_'. condterm(f(_,_,FICHA,_,FICHA,_,FICHA,_,_)):FICHA<>'_'. deterturno('X','O'). deterturno('O','X'). mem(X,[X|_]). mem(X,[_|L]):-mem(X,L). imprilis([]). imprilis([X|L]):imprilis(L), X=f(POS1,POS2,POS3,POS4,POS5,POS6,POS7,POS8,POS9), write(POS1," ",POS2," ",POS3,"\n"), write(POS4," ",POS5," ",POS6,"\n"), write(POS7," ",POS8," ",POS9,"\n","\n"), write("Presione un tecla para ir al siguiente estado"), readchar(_), write("\n\n\n"). goal clearwindow, /*Limpia la pantalla.*/ ingresardatos. /*Llama a la clausula para ingresar los datos.*/ Informe Final El programa en Prolog funciona de la siguiente manera: Para comenzar, se pide al usuario que ingrese el estado inicial del tablero. A partir de este estado, se busca la secuencia de movidas óptima (que será la que requiera de menor cantidad de pasos o secuencias). Para ello, el lenguaje utiliza el método de backtracking. Una vez ingresado el estado inicial, el compilador busca soluciones para un nivel de profundidad igual a 1. Primero se chequea la condición de terminación, sino se cumple se aplica una regla y se chequea la condición de terminación sobre el nuevo estado obtenido. Esto se realiza de manera recursiva hasta que se cumpla la condición de terminación o no se pueda profundizar más. Si se cumple la condición, se llega a la solución y esta secuencia de estados se imprime por pantalla. En caso contrario, se aumenta el nivel de profundidad en 1 y se repite el proceso para este nuevo nivel de profundidad. Esto también se reitera de manera recursiva hasta que se llega a la solución (para algún nivel de profundidad mayor o igual a 1). Como se comienza por un nivel de profundidad 1, esto asegura que la solución hallada será la que requiera de menor cantidad de secuencias de estado (sino encuentra con nivel 1 prueba con nivel 2 y así sucesivamente). Nota 1: No se encuentran validados los datos que debe ingresar el usuario. Nota 2: Se adjunta un diskette con el archivo ejecutable y con el archivo fuente.