Universidad Cat´olica
“Nuestra Se˜nora de la Asunci´on”
Sede Regional Asunci´on
Facultad de Ciencias y Tecnolog´ıa
Departamento de Ingenier´ıa
Electr´onica e Inform´atica
Carrera de Ingenier´ıa Inform´atica
Lenguajes de Programaci´on II
Ing. Sergio Caceres
Ram´ırez, Pedro <pedroramirez22@gmail.com>
TRABAJO FINAL
CONECTA 4
26 de junio de 2015
´INDICE 2
´Indice
1. Objetivo del Juego 2
2. Reglas 2
3. Algoritmo Minimax 3
4. T´ecnicas para mejorar Minimax 5
4.1. Poda Alfa-Beta . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
5. Funci´on de Utilidad-Heur´ıstica 9
1. Objetivo del Juego
Dado un tablero de 6 filas por 7 columnas, el objetivo es formar una l´ınea
horizontal, vertical o diagonal de 4 fichas iguales. Aquel jugador que primero lo
consiga gana el juego.
Para la descarga del juego implementado en lenguaje C, pulse aqu´ı.
2. Reglas
El conecta 4 es un juego que involucra a un tablero, fichas y dos jugadores,
que se rigen por las siguientes reglas
Casa jugador tiene 21 fichas, que se diferencian entre ellos por el color.
Una vez elegido quien inicia la partida, cada jugador realiza una jugada
por turno, sin posibilidad de saltar o pasar el turno.
Al inicio el tablero se encuentra en forma vertical y totalmente vac´ıo. Las
fichas se depositan siguiendo el sentido que marca la gravedad (de abajo
hacia arriba, conforme se vayan llenando casillas).
En su turno, el jugador deposita su ficha en alg´un lugar disponible del
tablero en forma vertical, buscando distribuir las fichas de manera tal
que pueda formar una l´ınea de 4 fichas iguales, ya sea en forma vertical,
horizontal o diagonal dentro del tablero.
El juego eventualmente puede terminar en un empate, que se da cuando
ya no queden m´as fichas ni espacios en el tablero, y ninguno de ellos ha
conseguido formar una l´ınea.
3 Algoritmo Minimax 3
3. Algoritmo Minimax
El algoritmo MiniMax es el algoritmo m´as conocido (y utilizado) para prob-
lemas con exactamente 2 adversarios, movimientos alternos (ahora t´u ahora
yo), e informaci´on perfecta.
Identificaremos a cada jugador como el jugador MAX y el jugador MIN.
MAX ser´a 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) independientemente de lo que haga
el jugador MIN.
Etiquetar los jugadores como m´aximos y m´ınimos plasma perfectamente la
dualidad de los objetivos de cada uno, adem´as de que as´ı se puede contabilizar
perfectamente c´omo una situaci´on que mejora para un jugador hace que empe-
ore para el otro. Matizar que no importa qu´e jugador deseemos ser, pues bajo
nuestro punto de vista siempre calcularemos jugadas positivas a nuestro favor
y negativas para el oponente.
Y todo ´esto nos lleva a que por convenio una jugada vencedora del jugador
MAX (lo que vendr´ıa a ser un jaque mate) tendr´a valor infinito, y una jugada
del jugador MIN tendr´a valor menos infinito.
Deber´a existir para el juego a resolver una funci´on de evaluaci´on heur´ısti-
ca que devuelva valores elevados para indicar buenas situaciones, y valores neg-
ativos para indicar situaciones favorables al oponente. Ahora ya podemos ver
como para cada movimiento conoceremos su valor num´erico en funci´on de su
grado de bondad, y podremos ser capaces de identificar nuestro mejor movimien-
to.
Adem´as de utilizar la anterior funci´on heur´ıstica, usaremos una estrategia
DFS de profundidad limitada para explorar el conjunto de jugadas. Como es
imposible hacer una exploraci´on exhaustiva de todas las jugadas, se hace una
b´usqueda limitada en profunidad. Significa que en lugar de estudiar todas las
posibles situaciones hasta el fin de la partida, se buscar´an por ejemplo todas
las situaciones hasta de aqu´ı 3 turnos. Aunque ´esto limitar´a lo que veamos del
espacio de b´usqueda, y quiz´as nos incitar´a a realizar unas jugadas que a la
larga sean nefastas. La calidad de nuestras jugadas vendr´a determinada por la
profundidad a la que lleguemos en cada exploraci´on. Cuanto m´as profunda sea,
mejor jugaremos, pero mayor coste tendr´a el algoritmo.
3 Algoritmo Minimax 4
Por lo tanto, situados todos los elementos del algoritmo, veamos c´omo es
MiniMax:
Funci´on MiniMax(estado) retorna movimiento
mejor_mov: movimiento;
max, max_actual: entero;
max = -infinito;
para cada mov en movimientos_posibles(estado) hacer
max_actual = valorMin(aplicar(mov, estado);
si max_actual > max entonces
max = max_actual;
mejor_mov = mov;
fsi
fpara
retorna mejor_mov;
fFunci´on
Funci´on valorMax(estado) retorna entero
valor_max:entero;
si estado_terminal(estado) entonces
retorna evaluaci´on(estado);
sin´o
valor_max := -infinito;
para cada mov en movimientos_posibles(estado) hacer
valor_max := max(valor_max, valorMin(aplicar(mov, estado));
fpara
retorna valor_max;
fsi
fFunci´on
Funci´on valorMin(estado) retorna entero
valor_min:entero;
si estado_terminal(estado) entonces
retorna evaluaci´on(estado);
sin´o
valor_min := +infinito;
para cada mov en movimientos_posibles(estado) hacer
valor_min := min(valor_min, valorMax(aplicar(mov, estado));
fpara
retorna valor_min;
fsi
fFunci´on
El algoritmo tiene una funci´on principal (MiniMax) que ser´a la que se usar´a,
y la que nos devolver´a la mejor realizable, y dos funciones recursivas mutuas
4 T´ecnicas para mejorar Minimax 5
(valorMax y valorMin) que determinan el valor de las jugadas dependiendo de
si es el turno de MAX o de MIN. De este modo cada nivel elegir´a el valor que
propaga a su ascendiente dependiendo de qu´e jugador es. En los niveles de MAX
se elegir´a el valor mayor de todos los descendientes, y en los niveles de MIN se
elegir´a el menor. Tras esto la m´aquina supone que todo jugador elige siempre
su mejor jugada, cosa que no siempre ser´a.
La funci´on estado terminal determina si el estado actual es una soluci´on o
pertenece al nivel m´aximo de exploraci´on. La funci´on evaluaci´on calcula el valor
heur´ıstico del estado.
Pero esta versi´on, aunque sea sencilla, no es la m´as inteligente a la hora de
tratar juegos bipersonales. Por eso al algoritmo MiniMax se le pueden efectuar
una serie de t´ecnicas para mejorarlo, buscando siempre una decisi´on m´as segura
del movimiento, y un tiempo de c´alculo menor.
4. T´ecnicas para mejorar Minimax
Pero MiniMax puede ser mucho m´as inteligente de lo anteriormente expuesto.
Veamos qu´e tipo de mejoras pueden aplic´arsele.
4.1. Poda Alfa-Beta
Un punto clave que hemos de tener en cuenta es que cuanto m´as profunda
sea la exploraci´on, mejor podremos tomar la decisi´on sobre qu´e jugada debemos
escoger.
Para juegos con un factor de ramificaci´on elevado, esta profundidad no po-
dr´a ser muy grande, ya que el c´alculo necesario para cada decisi´on ser´a pro-
hibitivo. Su tiempo de exploraci´on ser´a prohibitivo.
Para reducir este tiempo se han estudiado los ´arboles de b´usqueda, y se ha
llegado a la conclusi´on de que es muy factible usar heur´ısticos con poda. En
otras palabras, una t´ecnica de ramificaci´on y poda (branch and bound) con
la cual una soluci´on parcial se abandonar´a cuando se compruebe que es peor
que otra soluci´on ya conocida.
La estrategia denominada alfa-beta aprovecha que el algoritmo del MiniMax
hace una exploraci´on en profundidad para guardar informaci´on sobre cu´al es el
valor de las mejores jugadas encontradas para cada jugador.
Concretamente guarda dos valores, denominados umbrales alfa y beta (de
ah´ı el nombre del heur´ıstico).
El valor alfa representa la cota inferior del valor que puede asignarse en
´ultimo t´ermino a un nodo maximizante, y an´alogamente el valor beta represen-
tar´a la cota superior del valor que puede asignarse como ´ultima opci´on en un
nodo minimizante.
4.1 Poda Alfa-Beta 6
De esta manera el algoritmo podr´a acotar el valor de una exploraci´on, pues
gracias a los umbrales alfa y beta conocer´a si vale la pena explorar un camino
o no, como se ve en la Figura 1.
Figura 1: Ejemplo de Poda Alfa-Beta
En el ´arbol superior podemos ver que el valor que propagar´ıa MiniMax al
nodo ra´ız ser´ıa 8. Pero si nos fijamos en el nodo marcado, en el segundo de-
scendiente de la ra´ız ya sabe que el mejor nodo del primer descendiente tiene
valor 8. Puesto que el desdendiente es un nodo Min, y se ha encontrado por
debajo un valor de 6, el algoritmo interpretar´a que por ese camino como mejor
resultado habr´a ese 6 (pues el nodo inferior elegir´a o el 6 o algo inferior). Como
ya conocemos el posible 8, todos los nodos que cuelgan del Min que elegir´ıa el 6
ya no hace falta explorarlos, pues seguro que ah´ı no se encuentra nuestra mejor
jugada. En este momento se realizar´ıa la poda de esa rama e ir´ıa a explorar el
tercer posible camino.
Podemos observar tambi´en que esta circunstancia se repetir´a en el tercer
descendiente al explorar su ´ultimo nodo, pero al no quedar m´as descendientes la
poda no nos ahorrar´ıa nada. Significa que la efectividad de esta heur´ıstica depen-
der´a del orden de los nodos, pues cuanto antes encuentres un valor penalizado
por el umbral, antes podr´as podar la rama.
Esta heur´ıstica modifica el algoritmo del minimax introduciendo dos par´amet-
ros en las llamadas de las funciones, alfa y beta, y representar´an el l´ımite del
valor que pueden tomar las jugadas que exploramos. Una vez superado ese l´ımite
sabremos que podemos parar la exploraci´on porque ya tenemos el valor de la
mejor jugada accesible.
4.1 Poda Alfa-Beta 7
La funci´on MiniMax se mantiene igual. S´olo var´ıan las funciones que hacen
la exploraci´on de cada nivel, el c´odigo de las cuales ser´ıa el siguiente:
funcion valorMax( g , alfa , beta ) retorna entero
si estado_terminal( g ) entonces
retorna ( evaluacion( g ) )
sino
para cada mov en movs_posibles( g ) hacer
alfa:=max( alfa , valorMin( aplicar(mov, g ), alfa, beta ) )
si alfa >= beta entonces
retorna ( beta )
fsi
fpara
retorna ( alfa )
fsi
ffuncion
funcion valorMin( g , alfa , beta ) retorna entero
si estado_terminal( g ) entonces
retorna ( evaluacion( g ) )
sino
para cada mov en movs_posibles( g ) hacer
beta:=min( beta , valorMax( aplicar (mov, g ), alfa, beta ) );
si alfa >= beta entonces
retorna ( alfa )
fsi
fpara
retorna ( beta )
fsi
ffuncion
La llamada que har´a la funci´on MiniMax a la funci´on valorMax le pasar´a ?in-
finito como valor de alfa y +infinito como valor de beta (pues al no conocerse
ning´un valor es imposible marcar un umbral predefinido).
4.1 Poda Alfa-Beta 8
En la Figura 2 se ve c´omo explorar´ıa el algoritmo de MiniMax con poda alfa
beta el ejemplo anterior:
Figura 2: Ejemplo de Poda Alfa-Beta
En conclusi´on, con poda alfa beta podremos ampliar el l´ımite de profundidad
de nuestra exploraci´on, ya que con las podas nos ahorramos la exploraci´on de
varias parte del ´arbol de b´usqueda, lleg´andonos a ahorrar as´ı m´ultiples niveles.
De ah´ı deriva que algunas de las siguientes ampliaciones se basen en mejorar el
comportamiento de la poda alfa-beta.
5 Funci´on de Utilidad-Heur´ıstica 9
5. Funci´on de Utilidad-Heur´ıstica
int heuristica(int tablero[FILAS][COLUMNAS], int jugador)
{
if(verifica_ganador(tablero, jugador))
{
if(jugador == CPU)
return MAX_VALUE;
else
return MIN_VALUE;
}
return costo(MAX)-costo(MIN);
}
Si la jugada actual logro hacer ganar a CPU (computadora) la funci´on de
utilidad regresa 10000 siendo el m´aximo valor posible en el juego, si quien gana
en la tirada es el rival (humano) retornar´a -10000 siendo el m´ınimo valor posible
en el juego.
En caso contrario que ninguno haya ganado. La funci´on heur´ıstica retornara
el valor calculado de acuerdo a la siguiente evaluaci´on
h(n) = costo(MAX) − costo(MIN)
Donde costo(MAX) es el n´umero total de l´ıneas posibles que tiene el jugador
MAX para ganar (CPU). costo(MIN) es el n´umero total de l´ıneas posibles que
tiene el jugador MIN para ganar (humano). n es el estado actual en el tablero.
Si el jugador MAX (CPU) tiene ventaja sobre MIN, el valor retornado es
positivo puesto que el n´umero de l´ıneas ser´a mayor a MIN.
Si el jugador MIN (humano) tiene ventaja sobre MAX, el valor retornado
ser´a negativo puesto que el n´umero de l´ınea ser´a mayor a MAX.
Con dicha evaluaci´on si humano tiene ventaja en el tiro sobre cpu, la funci´on
valorMin tomara esa jugada y MAX se encargar´a de evitarla.