Вы находитесь на странице: 1из 11

FACULTAD DE CIENCIAS QUIMICAS FISICAS Y MATEMATICAS

CARRERA PROFESIONAL DE INGENIERIA INFORMATICA Y DE SISTEMAS

TEMA:

CURSO:

DOCENTE:

MICHI CON PODA Y MINIMAX

Inteligencia Artificial.

Lic. Juan Cruz.

PRESENTADO POR:
Cereceda Lopez, Mariela
Rozas Llamacponcca, Ramiro

CUSCO PERU
2014

040978
091965

INTRODUCCIN

Un tema interesante a tratar a lo que concierne a la Inteligencia Artificial son


los juegos. As por ejemplo, el juego de Michi (3 en raya) para dos
contrincantes y es uno de los juegos ms mencionados dentro de la teora de
juegos en la Inteligencia Artificial.
Inteligencia Artificial, por lo que tiene bien definida su meta (Hacer 3 en raya
en el juego) y sus acciones (conjunto de movimientos de cada uno de los
jugadores en caso sea x o o), las cuales hacen del juego complicado de
programar.
Existen varias tcnicas de bsqueda para el desarrollo de este juego. Dentro de
las tcnicas de bsqueda que hemos estudiado, hemos considerado utilizar la
bsqueda de Poda Alfa-Beta, la cual es muy eficiente en la bsqueda de una
solucin comparada con la bsqueda del algoritmo MiniMax. Sin embargo la
eleccin de una heurstica apropiada es lo que define mejor la solucin del
juego. Para este trabajo empezaremos definiendo algo de la teora del MiniMax,
para luego explicar las heursticas que hemos utilizado para obtener la utilidad,
elemento necesario para definir una adecuada jugada.

MICHI CON PODA Y MINIMAX


1. FUNDAMENTO TERICO.
1.1.
Michi (3 en raya)
En un tablero 3x3, un jugador posee el smbolo X y otro O. En cada
turno el jugador coloca un smbolo en el tablero. Gana el que consigue
colocar tres de sus fichas en lnea (ya sea en diagonal, vertical u
horizontal).

Elementos del juego en el 3 en raya


Estados: tablero + simbolo que se pondr a continuacin.
Estado inicial: tablero vaco + smbolo de salida.
Estados finales: tableros completos o con lnea ganadora
Estados ganadores para un jugador: estados finales con lnea
ganadora en los que no le toca poner.
Movimientos:
9 movimientos posibles, uno por casilla
Colocar ficha en i (i = 0, . . . , 8)
Aplicacin de movimientos:
Aplicable si la casilla no est ocupada
Estado resultante: colocar la ficha que toca en la casilla especificada
Funcin de utilidad:
1 si es ganador para MAX
0 si es tablas
-1 si es ganador para MIN
1.2.
Algoritmo MiniMax
Definicin:

El algoritmo MiniMax es el algoritmo ms conocido para juegos de 2


adversarios, con movimientos alternos. No se puede utilizar en juegos
donde hay azar, sino perfectamente definido como las tres en raya
y el ajedrez.

En teora de juegos, Minimax es un mtodo de decisin para


minimizar la prdida mxima esperada en juegos con adversario.
Este clculo se hace de forma recursiva.

El funcionamiento de Minimax puede resumirse como elegir el mejor


movimiento para ti mismo suponiendo que tu contrincante escoger
el peor para ti.

Se utilizar una estrategia de profundidad limitada para explorar el


conjunto de jugadas. Como es imposible hacer una exploracin
exhaustiva de todas las jugadas, se hace una bsqueda limitada en
profundidad. Significa que en lugar de estudiar todas las posibles
situaciones hasta el fin de la partida, se buscaran por ejemplo todas
las situaciones de aqu 3 turnos (un modo de poda).

Funcionamiento:
Identificaremos a cada jugador como el jugador MAX y el jugador
MIN. MAX ser el jugador que inicia el juego, el cual supondremos que
somos nosotros, y nos marcaremos como objetivo encontrar el conjunto
de movimientos que proporcionen la victoria a MAX (nosotros).
Deber existir una funcin de evaluacin heurstica que devuelva valores
elevados para indicar buenas situaciones, y valores negativos para
indicar situaciones favorables al oponente.
La calidad de nuestras jugadas vendr determinada por la profundidad a
la que lleguemos en cada exploracin. Cuanto mas profunda sea, mejor
jugaremos, pero mayor coste tendr el algoritmo.
En este juego de las tres en raya se puede llegar a la profundidad
mxima puesto que se trata de 9 movimientos fijos, en otros como el
ajedrez o las damas es muy necesario limitar la profundidad y aplicar
medidas que aumenten la eficiencia.

Funcionamiento del Algoritmo:

Generacin del rbol de juego. Se generarn todos los nodos hasta llegar
a un estado terminal o determinando una profundidad concreta (poda o
corte). Se considera el nodo raz como la situacin actual del juego.

Vamos aplicando el algoritmo por un nmero fijo de iteraciones hasta


alcanzar una determinada profundidad. En estas aplicaciones la
profundidad suele ser el nmero de movimientos o los incluso el
resultado de aplicar diversos pasos de planificacin en un juego de
estrategia. En este caso el nmero mximo es 9.
Clculo de los valores de la funcin de utilidad para cada nodo terminal.
Para cada resultado final, cmo de beneficioso me resulta si estamos en
MAX o cuanto me perjudicar si estamos en MIN.
Calcular el valor de los nodos superiores a partir del valor de los
inferiores. Alternativamente se elegirn los valores mnimos y mximos
representando los movimientos del jugador y del oponente, de ah el
nombre de Minimax.
Elegir la jugada valorando los valores que han llegado al nivel superior.

El algoritmo explorar los nodos del rbol asignndoles un valor numrico


mediante una funcin de utilidad, empezando por los nodos terminales y
subiendo hacia la raz.
La funcin de utilidad como se ha comentado, definir lo buena que es la
posicin para un jugador cuando la alcanza.
Versiones ms avanzadas como el minimax con poda alfa-beta hacen que se
reduzca considerablemente el nmero de nodos a visitar por lo que el tiempo
de clculo se reduce ampliamente.
Al aplicar el algoritmo, se suceden una serie de estados que se resumen en la
fotografa. Un estado -1 significa que MAX gana, 0 empate -1 pierde.

En el tres en raya:

Gana el 1, pierde el -1 y empate 0

La profundidad mxima es de 9, como el nmero de jugadas posible

No hay restricciones sobre la validez de un movimiento, simplemente que


no se haya hecho antes, por lo que el coste del clculo es bajo (no hay que
aplicar reglas complejas).

Almacenar las soluciones intermedias no es excesivamente complejo

Generar los diferentes tableros con las soluciones intermedias a explorar


no es costoso pero podra ser un problema en otros juegos y limitar la
profundidad por memoria

La mquina nunca pierde, el juego est completado

Las partidas entre jugadores mquina siempre quedan en tablas.

Ventajas del Algoritmo MiniMax

Capacidad de aprender de acuerdo a una base de datos histrica de


movimientos realizados.
Algoritmo casi infalible

Desventajas del Algoritmo MiniMax

Algoritmo de complejidad elevada a la hora de implementar.

Es de aprendizaje lento

Solo vale para enfrentarse a un oponente a la vez.

1.3.

Mejoras del Algoritmo MiniMax (Poda Alfa-Beta)

Este algoritmo es el ms utilizado en las aplicaciones referidas a juegos,


dada su excepcional utilidad en el aumento de la velocidad de la bsqueda
sin producir prdida de la informacin. Es una extensin en particular del
algoritmo de Bsqueda MiniMax en juegos de dos contrincantes.
Cada vez que se evala un nodo u hoja, el algoritmo determina los nuevos
hijos generados pueden generar una mejor utilidad de la que ya posee el
nodo estudiado y si afecta al nodo padre. De no ser as, eso significa que
seguir analizando esa rama se desperdiciara recursos como tiempo y

espacio, por lo cual no se sigue generando y simplemente se le poda, de all


el nombre.
Para ingresar al algoritmo, se necesita ingresar el nodo a ser evaluado, del
que se obtendr su utilidad, as como la utilidad del padre para evaluar si es
que la nueva utilidad afecta o no al nodo padre. De no ser as, se proceder
a podar la rama.
Una vez podada la rama, la nueva utilidad ser la ltima en ser registrada o
actualizada. Esto se da mediante una variable funcin Nodo, que contiene la
funcin de utilidad del nodo ingresado.
Mejora del Algoritmo Minimax; aplicado en juegos de adversarios por
turnos.
Se aplica en espacios de estados demasiado grandes como para
analizar todos los nodos.
La informacin es imperfecta; es decir, no se conoce el estado del
contrincante. Ejm: En juegos donde no se ve el tablero del adversario
Caractersticas de la Poda Alfa- Beta

Omitir la expansin de nodos que por sus valores no pueden ser los
mejores (peores).
Interrumpe la bsqueda en algn nivel y aplica evaluaciones
heursticas a las hojas (profundidad limitada).
Si el valor del nodo MAX (alfa) es menor que el ms alto hasta este
momento, entonces omitir nodo.
SI el valor del nodo MIN (beta) es mayor que el nodo ms bajo hasta
el momento, entonces omitir nodo.

Alfa-Beta permite bsqueda dos veces ms profunda.

La poda no afecta al resultado final.

Algoritmo de bsqueda Alfa-Beta


Corresponde a la combinacin de tres aportes:
Ejecutar Minimax.
Mantener recordados Alfa y Beta.
Podar.
Comportamiento de los nuevos algoritmos de bsqueda en juegos
Alfa-Beta busca solamente 3/4b de los b movimientos posibles desde una
posicin dada de juego.
Esto significa que la profundidad de bsqueda se puede incrementar por un
factor = log b / log b ~= 4/3 por encima de una bsqueda exhaustiva Minimax.
B es aqu el factor de ramificacin efectivo.
Si los sucesores se ordenan a la perfeccin (definido como que al usar AlfaBeta la bsqueda es mnima), Alfa-Beta examina 2bd/2 1 posiciones de
juego.

As tenemos

2. PROGRAMA MICHI CON MINIMAX EN PROLOG

% Implementacin del juego Tres en Raya con Algoritmo Mini-Max


% Grupo N 1
% Universidad Nacional de San Antonio Abad del Cusco
%%%%%%%%%%%%%%%%%%%%%%%%% Funciones de Utilidad Bsicas %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%
getMayor(A,B,A):- A > B, !. getMayor(_,B,B):- !.
getMenor(A,B,A):- A < B, !. getMenor(_,B,B):- !.
concatenar([],Y,Y).
concatenar([X|Xs],Y,[X|Z]):-concatenar(Xs,Y,Z).
iguales([],_):-!. iguales([X],X):-!.
iguales([X,X|Xs],X):-iguales([X|Xs],X).
genLista(0,_,[]):-!.
genLista(T,V,[V|L]):-T1 is T-1, genLista(T1,V,L).
genTablero(NF,NC,V,T):-genLista(NC,V,L1), genLista(NF,L1,T).
genSgteJugador(1,-1):-!. genSgteJugador(-1,1). % luego de jugar MAX(1), juega MIN(-1)
genEstadoIniMax(estado(T,1)):-genTablero(3,3,0,T). % 1 empieza MAX, -1 empieza MIN
genEstadoIniMin(estado(T,-1)):-genTablero(3,3,0,T).
getElemenLista([L|_],P,L):-P=1,!.
getElemenLista([_|Ls],P,R):-P1 is P-1, getElemenLista(Ls,P1,R).
getElemenMatriz(M,F,C,E):- getElemenLista(M,F,L), getElemenLista(L,C,E), !.
%%%%%%%%%%%%%%%%%%%%%% Generar la Lista de Estados Siguientes %%%
%%%%%%%%%%%%%%%%%%%%%%%%%
marcarLista([_|Ls],1,V,[V|Ls]):-!.
marcarLista([L|Ls],P,V,[L|R]):-P1 is P-1, marcarLista(Ls,P1,V,R).

marcarTablero([L|Ls],1,C,V,[R|Ls]):-marcarLista(L,C,V,R),!.
marcarTablero([L|Ls],F,C,V,[L|R]):-F1 is F-1, marcarTablero(Ls,F1,C,V,R).
getPuntosLista([],_,_,[]):-!.
getPuntosLista([0|Ls],F,C,[punto(F,C)|R]):-C1 is C+1, getPuntosLista(Ls,F,C1,R),!.
getPuntosLista([_|Ls],F,C,R):-C1 is C+1, getPuntosLista(Ls,F,C1,R).
getPuntosTablero([],_,[]):-!.
getPuntosTablero([L|Ls],F,R):-F1 is F+1, getPuntosLista(L,F,1,R1),
getPuntosTablero(Ls,F1,R2), concatenar(R1,R2,R).
getEstadosMarcados(_,[],_,[]):-!.
getEstadosMarcados(estado(T,J),[punto(F,C)|Ls],NJ,[estado(R,NJ)|Rs]):marcarTablero(T,F,C,J,R),
getEstadosMarcados(estado(T,J),Ls,NJ,Rs).
getListaSucesores(estado(T,J),R):-getPuntosTablero(T,1,LP), genSgteJugador(J,NJ),
getEstadosMarcados(estado(T,J),LP,NJ,R).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Test Terminal %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
getListaVertical([],_,[]):- !.
getListaVertical([L|Ls],P,[E|R]):- getElemenLista(L,P,E), getListaVertical(Ls,P,R),!.
getDiagonalIzq([],_,[]):- !.
getDiagonalIzq([L|Ls],P,[E|R]):- P1 is P+1, getElemenLista(L,P,E),
getDiagonalIzq(Ls,P1,R).
getDiagonalDer([],_,[]):- !.
getDiagonalDer([L|Ls],P,[E|R]):- P1 is P-1, getElemenLista(L,P,E),
getDiagonalDer(Ls,P1,R).
tieneCeroLista([0|_]):- !.
tieneCeroLista([_|Ls]):- tieneCeroLista(Ls), !.
tieneCeroMatriz([L|_]):- tieneCeroLista(L), !.
tieneCeroMatriz([_|Ls]):- tieneCeroMatriz(Ls), !.
% Predicados que determinan si el estado es terminal
tresEnRayaHorizontal(L,J):-getElemenLista(L,1,P), iguales(P,J), !.
tresEnRayaHorizontal(L,J):-getElemenLista(L,2,P), iguales(P,J), !.
tresEnRayaHorizontal(L,J):-getElemenLista(L,3,P), iguales(P,J), !.
tresEnRayaVertical(L,J):- getListaVertical(L,1,P), iguales(P,J), !.
tresEnRayaVertical(L,J):- getListaVertical(L,2,P), iguales(P,J), !.
tresEnRayaVertical(L,J):- getListaVertical(L,3,P), iguales(P,J), !.
tresEnRayaDiagonal(L,J):- getDiagonalIzq(L,1,D), iguales(D,J), !.
tresEnRayaDiagonal(L,J):- getDiagonalDer(L,3,D), iguales(D,J), !.
estadoFinal(estado(T,_),1):- tresEnRayaHorizontal(T,1), !.
estadoFinal(estado(T,_),1):- tresEnRayaVertical(T,1), !.
estadoFinal(estado(T,_),1):- tresEnRayaDiagonal(T,1), !.
estadoFinal(estado(T,_),-1):- tresEnRayaHorizontal(T,-1), !.

estadoFinal(estado(T,_),-1):- tresEnRayaVertical(T,-1), !.
estadoFinal(estado(T,_),-1):- tresEnRayaDiagonal(T,-1), !.
estadoFinal(estado(T,_),0):- not(tieneCeroMatriz(T)), !.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Algoritmo Minimax%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%
% Max-Valor
% MaxValor recibe un estado, alfa, beta,retorna un nuevo estado y un valor de utilidad
maxValor(S, _, _, S, U) :- estadoFinal(S, U), !.
maxValor(S, A, B, NS, U):- getListaSucesores(S, LS),
genEstadoIniMin(IS), V = (-10),
maxLista(LS, A, B, IS, V, NS, U).
maxLista([], _, _, IS, V, IS, V):- !.
maxLista([L|Ls], A, B, IS, V, NS2, U2):- maxElemento(L, A, B, IS, V, NS, U),
getMaxLista(Ls, A, B, NS, U, NS2, U2).
maxElemento(S, A, B, IS, V, NIS, NV):- minValor(S, A, B, _, UM),
getMaxValor(S, UM, IS, V, NIS, NV).
getMaxValor(S, UM, _, V, S, UM):- UM > V, !.
getMaxValor(_, UM, IS, V, IS, V):- UM =< V.
getMaxLista(_, _, B, NS, U, NS, U):- U >= B, !.
getMaxLista(Ls, A, B, NS, U, NS2, U2):- U < B, getMayor(A, U, NA),
maxLista(Ls, NA, B, NS, U, NS2, U2).
% Min-Valor
% MinValor recibe un estado, alfa, beta,retorna un nuevo estado y un valor de utilidad
minValor(S, _, _, S, U) :- estadoFinal(S, U), !.
minValor(S, A, B, NS, U):- getListaSucesores(S, LS),
genEstadoIniMax(IS), V = 10,
minLista(LS, A, B, IS, V, NS, U).
minLista([], _, _, IS, V, IS, V):- !.
minLista([L|Ls], A, B, IS, V, NS2, U2):- minElemento(L, A, B, IS, V, NS, U),
getMinLista(Ls, A, B, NS, U, NS2, U2).
minElemento(S, A, B, IS, V, NIS, NV):- maxValor(S, A, B, _, UM),
getMinValor(S, UM, IS, V, NIS, NV).
getMinValor(S, UM, _, V, S, UM):- UM < V, !.
getMinValor(_, UM, IS, V, IS, V):- UM >= V.
getMinLista(_, A, _, NS, U, NS, U):- U =< A, !.
getMinLista(Ls, A, B, NS, U, NS2, U2):- U > A, getMenor(B, U, NB),
minLista(Ls, A, NB, NS, U, NS2, U2).
% tomaremos como -inf a -10 y como +inf a +10
busquedaAlfaBetaIniMax(S,NS,U):- maxValor(S, -10, 10, NS, U).
busquedaAlfaBetaIniMin(S,NS,U):- minValor(S, -10, 10, NS, U).
%%%%%%%%%%%%%%%%%%%%%%%%%%%% Imprimir el estado actual en
Pantalla %%%%%%%%%%%%%%%%%%%%%

imprimirEstado(estado(T,J)):- J=1, write('MAX'),nl, imprimirTablero(T).


imprimirEstado(estado(T,J)):- J=(-1), write('MIN'),nl, imprimirTablero(T).
imprimirFila([]):- nl,!.
imprimirFila([L|Ls]):- L=1, write('x'),write(' '),imprimirFila(Ls),!.
imprimirFila([L|Ls]):- L=(-1), write('o'),write(' '),imprimirFila(Ls),!.
imprimirFila([L|Ls]):- L=0, write('-'),write(' '),imprimirFila(Ls).
imprimirTablero([]):- nl,!.
imprimirTablero([L|Ls]):- imprimirFila(L), imprimirTablero(Ls).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Inicio del Juego %%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%
jugar:- write(' * ...MICHI (3 EN RAYA)...*'), nl,
write(' **********GRUPO N 1***********'), nl,
write(' -------------------------------'), nl,
write(' * Quien empieza? *'), nl,
write(' (1) la PC '), nl,
write(' (2) t '), nl,
write(' -------------------------------'), nl,
write(' Elige una opcin: '), read(X), iniciarJuego(X),!.
iniciarJuego(1):- genEstadoIniMax(S), imprimirEstado(S), juego(S),!.
iniciarJuego(2):- genEstadoIniMin(S), imprimirEstado(S),
juegaPersona(S,NS,_) , juego(NS),!.
juego(S):- juegaMaquina(S,NS,Fin), accion(NS,Fin),!.
juegaMaquina(S,NS,Fin):- busquedaAlfaBetaIniMax(S,NS,_), imprimirEstado(NS),
continuarJuego(NS,Fin), !.
continuarJuego(NS,'emp'):- estadoFinal(NS,0), !.
continuarJuego(NS,'fin'):- estadoFinal(NS,_), !.
continuarJuego(_,'cont'):- !.
accion(_,'emp'):- write('Empate!'), !.
accion(_,'fin'):- write('Te gan!'), !.
accion(S,'cont'):- juegaPersona(S,NS,'cont'), juego(NS), !.
accion(S,'cont'):- juegaPersona(S,_,'emp'), write(' Empate!'), !.
accion(S,'cont'):- juegaPersona(S,_,'fin'), write(' Ganaste!'), !.
juegaPersona(estado(T,-1),estado(NT,1),Fin):write('-Ingrese fila: '), read(F),
write('-Ingrese columna: '), read(C), nl,
marcarTablero(T,F,C,-1,NT),
imprimirEstado(estado(NT,1)), continuarJuego(estado(NT,1),Fin),!.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Вам также может понравиться