Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Acabamos esta serie sobre Python examinando su capacidad para el procesamiento de XML e introduciendo Jython, la implementacin Java de Python. Tambin discutiremos una implementacin ms inteligente del juego de tres en raya que usa un algoritmo de inteligencia artificial.
Introduccin
En los ltimos aos el estndar XML (eXtensible Markup Language) se ha establecido como el principal mecanismo para el intercambio de datos entre aplicaciones. XML es un metalenguaje que permite disear otros lenguajes. Algunos ejemplos de lenguajes derivados de XML son WML, MathML o XHTML. Con XML cualquiera puede desarrollar su propio lenguaje de etiquetas adecuado al tipo de aplicacin que ms le convenga. Un documento XML puede ser fcilmente procesado y sus datos manipulados, por medio de APIs estndar disponibles en lenguajes como Java, C, C++, C# y, por supuesto, Python. En esencia, XML define datos portables, al igual que Python o Java definen cdigo portable. Por otra parte, el lenguaje de programacin Java ha experimentado desde su nacimiento en 1995 un crecimiento extraordinario. En los ltimos 10 aos Java no slo ha ido madurando como lenguaje de programacin si no que gracias al ofrecimiento gratuito por parte de Sun de la JDK (Java Development Kit) su adopcin ha sido espectacular. Como resultado ha habido numerossimas contribuciones de cdigo abierto que facilitan el desarrollo de cualquier problema informtico que podamos concebir. Jython, la implementacin Java de Python, fue creado para poder aprovechar todas estas contribuciones del mundo Java y tener acceso a su funcionalidad desde la elegante sintaxis de Python. En este artculo describiremos cmo programar aplicaciones que usan XML y acceden a paquetes des-
arrollados en Java desde Python. Concluiremos con una discusin del algoritmo de inteligencia artificial MiniMax que permitira a la mquina ser un contrincante de entidad en el juego de tres en raya.
XML
En las prximas lneas vamos a hacer un repaso de la tecnologa XML, aunque este tema ha sido tratado con profundidad en ediciones anteriores de Slo Programadores. Si el lector quiere ampliar lo aqu expuesto, puede consultar los nmeros 110, 111, 114, 115 y 116. XML no es slo un lenguaje de lenguajes, es tambin un conjunto de tecnologas que permiten su representacin y procesamiento, tales como XPath, XLink, XPointer o XML. La especificacin de XML 1.0 puede encontrarse en la direccin de Internet http://www.w3.org/TR/REC-xml. Un documento XML est estructurado en los siguientes componentes: Instrucciones de procesamiento (processing instructions PI). Las PI son instrucciones para el procesador del documento XML. El prlogo del documento es una PI obligatoria:
<?xml version=1.0 encoding=iso-8859-1?>
Declaraciones de tipo de documento. Especifican la estructura y sintaxis de un documento XML a travs de una gramtica bien en la forma de un DTD (Document Type Definition) o un Schema. Se declaran en un documento en el siguiente modo:
<!DOCTYPE <elemento-raz> SYSTEM <fichero-con-dtd>
A travs del DTD una instancia de un documento puede ser validada contra la gramtica que define los elementos y posicin de los mismos en un documento. Comentarios. Sirven para realizar anotaciones tiles al autor del documento. Un ejemplo sera:
<! Esto es un comentario >
Elementos. Aportan estructura semntica al documento. Se delimitan por etiquetas de apertura y cierre o vienen sin elementos interiores (etiquetas vacas como <br/>). Las etiquetas de apertura y las vacas suelen venir
36
MIDDLEWARE
acompaadas de atributos, que parametrizan el elemento. Referencias a entidades. Sirven para insertar un determinado contenido definido previamente. Por ejemplo:
<!ENTITY Empresa Universidad de Deusto>...<pie>Creado por &Empresa; </pie>
Secciones CDATA. Contienen texto que no queremos sea procesado por el parser de XML. Por ejemplo:
<![CDATA[<saludo>Hola, mundo! </saludo>]]>
Las razones fundamentales del xito de XML son: Permite etiquetar los datos con su significado (self-describing data). Estructurar la informacin de acuerdo a las necesidades de la aplicacin. Tratar automticamente la informacin a travs de procesadores libremente disponibles, que se ajustan a APIs estndar. XML es la base de una nueva generacin de aplicaciones web, siendo un estndar para el intercambio de datos. Entre otras cosas XML se utiliza como formato de datos en sitios web para separar contenido y presentacin, como medio de comunicacin para el intercambio de datos entre organizaciones o para la transmisin de mensajes en servicios web (SOAP).
El lenguaje de programacin XSL fue diseado para responder al segundo enfoque, y el lector debera ser conocedor de ello, pues XSL-FO es objeto de nuestro estudio desde hace unos meses. XSL consta de dos partes: XML Stylesheet Transformation Language (XSLT) XSL Formatting Language (XSL-FO) XSLT es el componente de XSL que transforma un documento XML en otro documento XML. XSL-FO formatea y estiliza documentos en varios modos. La especificacin de XSLT se encuentra disponible en http://www.w3.org/TR/xslt. Las principales ventajas de XSLT son: No asume un nico formato de salida de documentos. Permite manipular de muy diversas maneras un documento XML: reordenar elementos, filtrar, aadir, borrar, etc. Las desventajas de XSLT son: Su utilizacin es ms compleja que un lenguaje de programacin convencional. Consume bastante memoria y capacidad de proceso, usa DOM por debajo.
Procesamiento XML
La popularidad de XML estriba en no tener que crear un nuevo compilador por cada lenguaje de representacin de datos que queremos disear. Las herramientas que llevan a cabo la validacin lxica y sintctica de los documentos y su transformacin en una representacin manejable por programas vienen ya dados. A cambio, los diseadores de nuevos tipos de documentos XML slo deben seguir las restricciones que un documento XML bien formado debe cumplir: Debe tener un prlogo. Debe tener una etiqueta (elemento) raz. Las etiquetas se hallan correctamente anidadas. Se usan caracteres vlidos y bien aplicados. Los valores de los atributos vienen encerrados entre comillas. La industria utiliza tres estndares principales para el procesamiento de documentos XML: SAX, DOM y XSL. A continuacin, pasamos a describirlos en ms detalle.
MIDDLEWARE
LISTADO 1
Documento Cartelera.xml
peliAttribs.getNamedItem(codigo). nodeValue
<?xml version=1.0 encoding=iso-8859-1?> <Cartelera> <Cine codigo=1 nombre=Guridi Zinemak direccion=San Prudencio poblacion=Vitoria-Gasteiz> <Pelicula codigo=1 titulo=Malena director=Santiago Segura actores=Bo Derek, Al Pacino, Robert Reford> <Sesion>16:00</Sesion> <Sesion>19:30</Sesion> <Sesion>22:00</Sesion> </Pelicula> <Pelicula codigo=2 titulo=Los Otros director=Alejandro Amenabar actores=Nicole Kidman> <Sesion>16:30</Sesion> <Sesion>19:45</Sesion> <Sesion>22:30</Sesion> </Pelicula> </Cine> ... </Cartelera>
Permiten recuperar el contenido del atributo cuyo nombre se pasa al mtodo getNamedItem. La figura 2 muestra el resultado de tal procesamiento. Puede verse este ejemplo en el fichero ejemploDOM.py incluido en el CD-ROM.
cin correspondiente a las pelculas encontradas en el mismo. El mtodo DOM principal que se utiliza es getElementsByTag Name(<nombre-elemento>), que dado el nombre de un elemento recupera todas Figura 1. Ejecucin del programa ElementCounterSAX.py las instancias del aplicado a Cartelera.xml. mismo encontradas to al entrar en una parte significativa del docu- en un rbol DOM. El atributo de un elemento mento. El listado 2 muestra un ejemplo de DOM attributes se usa para recuperar los atricdigo Python que procesa el fichero butos de cada elemento pelcula. Las sentenCartelera.xml para contar el nmero de ele- cias en la forma: mentos y atributos XML encontrados en l. LISTADO 2 Procesamiento del fichero Cartelera.xml usando SAX Tanto el documento XML (Cartelera.xml) como el script Python (ElementCounterSAX.py) estn # Uso: python ElementCounterSAX.py Cartelera.xml disponibles en el CD-ROM que acompaa a la import sys from xml.sax import make_parser, handler revista. La figura 1 muestra el resultado de la class ElementCounter(handler.ContentHandler): ejecucin de este script. def __init__(self):
self._elems = 0 self._attrs = 0 self._elem_types = {} self._attr_types = {} def startElement(self, name, attrs): self._elems = self._elems + 1 self._attrs = self._attrs + len(attrs) self._elem_types[name] = self._elem_types.get(name, 0) + 1 for name in attrs.keys(): self._attr_types[name] = self._attr_types.get(name, 0) + 1 def endDocument(self): print There were, self._elems, elements. print There were, self._attrs, attributes. print -ELEMENT TYPES for pair in self._elem_types.items(): print %20s %d % pair print -ATTRIBUTE TYPES for pair in self._attr_types.items(): print %20s %d % pair parser = make_parser() parser.setContentHandler(ElementCounter()) parser.parse(sys.argv[1])
MIDDLEWARE
LISTADO 3
#!/usr/bin/env python # -*- coding: iso-8859-1 -*import xml.dom.minidom, sys class Pelicula: def __init__(self, codigo, titulo, director, actores): self.codigo = codigo self.titulo = titulo self.director = director self.actores = actores def __repr__(self): return Codigo: + str(self.codigo) + - titulo: + self.titulo + - director: + self.director + - actores: + self.actores class PeliculaDOMParser: def __init__(self, filename): self.dom = xml.dom.minidom.parse(filename) self.peliculas = [] def getPeliculas(self): # Si no hemos ya recuperado las pelculas en el documento ... if not self.peliculas: peliculaNodes = self.dom.getElementsByTagName(Pelicula) numPelis = len(peliculaNodes) for i in range(numPelis): pelicula = peliculaNodes.item(i) # Recuperar los attributes de cada nodo Pelicula peliAttribs = pelicula.attributes codigo = peliAttribs.getNamedItem(codigo).nodeValue titulo = peliAttribs.getNamedItem(titulo).nodeValue director = peliAttribs.getNamedItem(director).nodeValue actores = peliAttribs.getNamedItem(actores).nodeValue # crear un nuevo objeto de tipo pelcula self.peliculas.append(Pelicula(codigo,titulo,director,actores)) return self.peliculas if __name__ == __main__: domParser = PeliculaDOMParser(sys.argv[1]) for peli in domParser.getPeliculas(): print peli
LISTADO 4
# Ejecuta: python xsltexample.py Cartelera.xml Cartelera.xsl Cartelera.html import libxslt import sys if len(sys.argv) != 4: print Usage: python xsltexample <xml-file> <xslt-file> <output-file> sys.exit(0) else: styledoc = libxml2.parseFile(sys.argv[2]) style = libxslt.parseStylesheetDoc(styledoc) doc = libxml2.parseFile(sys.argv[1]) result = style.applyStylesheet(doc, None) style.saveResultToFilename(sys.argv[3], result, 0) style.freeStylesheet() doc.freeDoc() result.freeDoc()
pgina web de la figura 3. El listado 5 contiene slo un pequeo fragmento de la hoja de estilo Cartelera.xsl. Una hoja XSLT es un documento XML bien formado que tiene como elemento raz el elemento xsl:stylesheet. Este elemento contiene un conjunto de xsl:templates, o plantillas de transformacin que asocian un fragmento del documento XML de entrada con otro del documento XML de salida. En la especificacin de XSLT http://www.w3.org/TR/xslt, puede encontrarse una minuciosa descripcin de este lenguaje.
integra de manera transparente con la plataforma Java. Jython complementa a Java y es especialmente indicada para las siguientes tareas: Empotrar scripts en aplicaciones Java, de modo que los usuarios finales puedan escribir scripts que aadan funcionalidad a la aplicacin. Experimentacin interactiva por medio del intrprete interactivo suministrado por Jython que permite interactuar con los paquetes Java o aplicaciones en ejecucin. Desarrollo rpido de aplicaciones. Los programas en Python son tpicamente entre 2 y 10 veces ms cortos que los programas Java. Esto se traduce en una mayor productividad en la programacin. La integracin transparente de Jython y Java permite combinar estos dos lenguajes en productos. Existen otros lenguajes de scripting que se integran transparentemente con Java como Jacl, implementacin en Java de Tcl, Rhino, implementacin en Java de JavasScript o BeanShell. Sin embargo Jython se distingue de otras alternativas por: Compilacin dinmica de Jython en bytecodes de Java (conduce al mayor rendimiento posible). Habilidad para extender las clases Java en Jython. Compilacin esttica opcional, que permite la creacin de applets, servlets y beans. Lo hace a travs de la herramienta jythonc que transforma ficheros .PY en .CLASS. Uso del lenguaje Python que combina poder con simplicidad sintctica, soportando el modelo orientado a objetos de Java. Las herramientas de compilacin/ejecucin de Jython son disponibles en http://www. jython.org/download.html. Para instalarlo simplemente hay que ejecutar el comando java jython21, que lanzar el instalador de Jython. Como prerrequisito, la mquina donde se instale debe tener preinstalada una mquina virtual de Java. Si no se dispone de ella, puede ser obtenida desde http://java.sun.com/j2se/1.4.2/download.html.
Programacin en Jython
Jython bsico
Jython (http://www.jython.org) es una implementacin Open Source en Java de Python que se La figura 4 muestra una sesin interactiva de Jython. Para ejecutar el intrprete de Jython
39
MIDDLEWARE
simplemente hay que escribir en la lnea de comando jython. El ejemplo muestra cmo el usuario puede crear una instancia de la clase Java java.util.Random para obtener una serie de nmeros aleatorios. Este ejemplo ha sido prestado de http://www.jython.org/docs/usejava. html. Como observamos en la figura, para crear una instancia de una clase Java se usa la convencin de Python, es decir una funcin con el nombre de la clase no precedida del operador new. En la invocacin de mtodos de clases Java desde Jython hay que tener en cuenta la conversin de los tipos de datos de Python a Java, y cuando se reciben resultados lo opuesto, es decir, la conversin de tipos de datos Java en Python. Dado que Python y Java definen casi los mismos tipos de datos primitivos, apenas hay nunca problemas durante esta tarea de coercin (conversin de tipos de datos).
3.- Tres en Raya modo grfico en Jython con acceso a base de datos MySQL.
Nuestra implementacin original de Tres en Raya en modo texto, a la que llamamos tresenraya.py, requiere mnimos cambios para ser ejecutable en Jython. Tan solo debemos aadir dos variables globales True y False con los valores 1 y 0, respectivamente. Esto es debido a que Figura 3. Pgina web resultante de aplicar Cartelera.xsl a Cartelera.xml. Jython no soporta todava el tipo booleano de Python. Hemos incluido la ver- listado 6 muestra el constructor de la clase sin modificada de este script en el CD-ROM bajo JuegoTresEnRayaJythonGUI, incluida en el CDel nombre tresenrayajython.py Las dos nicas ROM bajo el nombre tresenrayajythongui.py, . Transformando la aplicacin Tres lneas que difieren del script original presentado en junto con la implementacin del mtodo la primera entrega de este curso son: onClick. La lgica principal de esta aplicacin en Raya en una aplicacin Jython est gobernada por el mtodo jugar no incluido True = 1 Qu mejor manera de evaluar el potencial de por falta de espacio pero disponible tambin en el False = 0 Jython que retomar nuestra conocida aplicacin CD-ROM. La clase JuegoTresEnRayaJythonGUI del Tres en Raya y aplicar los cambios requeridos La ejecucin de este script Jython se presen- hereda de tresenrayajython.JuegoTresEnRaya, para poderla ejecutar en Jython. Vamos a dividir ta en la figura 5. que es la clase base del juego. En el constructor de esta tarea de transformacin en tres fases: Tres en Raya modo grfico en Jython esta clase: (1) se obtiene una instancia a la imple1.- Tres en Raya modo texto en Jython. El siguiente paso en la transformacin del juego mentacin de la clase del registro de jugadores 2.- Tres en Raya modo grfico en Jython Tres en Raya en Jython es crear la interfaz grfica que guarda datos en un mapa persistente, (2) se con acceso a mapa persistente. del mismo usando el paquete Swing de Java. El invoca al constructor de la clase base y (3) luego simplemente se crea un Frame donde se coloLISTADO 5 Fragmento hoja de estilo Cartelera.xsl can los botones correspondientes a las casillas del tablero de tres en raya. <?xml version=1.0 encoding=iso-8859-1?> Obsrvese lo sencillo que es en Jython asig<xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/XSL/Transform version=1.0> <xsl:output method=html/> nar un manejador de eventos a un botn:
<xsl:template match=/> <html> <head> <style type=text/css> table {font-family: arial, sans serif; margin-left: 15pt;} th,td {font-size: 80%;} th {background-color:#FAEBD7} </style> </head> <body> <table border=1> <xsl:apply-templates/> </table> </body> </html> </xsl:template> <xsl:template match=Cartelera> <xsl:for-each select=Cine> <tr> <th><xsl:text>Cine</xsl:text></th> <th><xsl:text>Direccin</xsl:text></th> <th><xsl:text>Poblacin</xsl:text></th> <th></th> </tr> ... </xsl:stylesheet> button = swing.JButton(self.icono Vacio, actionPerformed=self.onClick)
Si hubiramos efectuado una traduccin literal del cdigo Java a Jython hubiramos necesitado el siguiente cdigo:
class action(awt.event.ActionListener): def onClick(self,event): # la implementacin del manejador button = swing.JButton(self.iconoVacio) button.addActionListener(action())
40
MIDDLEWARE
DB API de Python, si no que JDBC para acceder a la base de datos que creamos en la tercera entrega. El script SQL de creacin de la base de datos tresenraya ha sido incluido en el CD-ROM junto con las instrucciones de cmo ejecutar este script en MySQL. El listado 7 muestra un fragmento de la clase transformada a la que hemos denominado RegistroJugadores DBJython. Como las otras variedades de registros de jugadores que hemos implementado deriva de la clase base RegistroJugadores. Si se desconoce la manera de interactuar con JDBC se recomienda al lector que repase los contenidos de los nmeros 105, 106 y 107 de Slo Programadores y/o que visite la pgina http://java.sun.com/products/jdbc/. En pocas palabras, en el constructor de esta clase se carga el driver JDBC para MySQL (disponible en http://www.mysql.com/products/ connector/j/) en memoria, se obtiene una conexin a la base de datos tresenraya y luego se utiliza esa conexin para ejecutar comandos
(Statements) SQL. Las figuras 6 y 7 corresponden a pantallazos de la versin Jython del juego Tres en Raya en modo grfico.
LISTADO 6
import java from java import awt from javax import swing from javax.swing import ... class JuegoTresEnRayaJythonGUI(tresenrayajython.JuegoTresEnRaya): def __init__(self): registro = tresenrayajython.RegistroJugadoresPersistente() tresenrayajython.JuegoTresEnRaya.__init__(self, registro, solop, solop) self.frame = swing.JFrame(Juego Tres en Raya, visible=1, windowClosing=self.exit) gridSizer = awt.GridLayout(3,3) self.frame.getContentPane().setLayout(gridSizer) self.iconoMaquina = swing.ImageIcon(Images\\x.PNG) self.iconoUsuario = swing.ImageIcon(Images\\o.PNG) self.iconoVacio = swing.ImageIcon(Images\\blank.PNG) self.buttons = [] for i in range(9): button = swing.JButton(self.iconoVacio, actionPerformed=self.onClick) button.setBackground(awt.Color.WHITE) self.frame.contentPane.add(button) self.buttons.append(button) self.frame.pack() ...
En Marzo del 2004 en la conferencia PyCon fue pre- Figura 5. Sesin interactiva de tresenrayajython.py. sentado IronPython (http:// ironpython.com/), una implementacin Python Dinmico, soporta el modo de ejecucin orientada a las plataformas .NET y Mono. Las interactivo como Python. caractersticas principales de IronPython son: Opcionalmente esttico, se pueden comTan rpida como la versin estndar de pilar ficheros Python para producir ejecuPython. tables (.EXE) que pueden ejecutarse direcIntegrada de modo transparente con la tamente o incluso DLLs. Common Language Runtime de .NET. Desde Soporta cdigo gestionado (managed code). IronPython podemos usar las libreras de No finalizado, todava en versin alfa no clases .NET y extender otras clases .NET. puede ser utilizada para produccin de software. Clase JuegoTresEnRayaJythonGUI En definitiva, IronPython parece una contribucin prometedora que nos permitir programar aplicaciones .NET desde la cmoda y sencilla sintaxis de Python. Mantngase JOptionPane atento a los progresos en este proyecto.
El algoritmo MiniMax
No quera concluir esta serie sobre Python, en la que el juego Tres en Raya nos ha ayudado a entender tantos conceptos, sin proponer un algoritmo ms sofisticado referente a la eleccin de casillas por la mquina. En definitiva, muchos de vosotros os habris preguntado cmo hacer que la mquina piense y elija la mejor casilla en cada momento. Este razonamiento es posible a travs del algoritmo de inteligencia artificial, MiniMax.
def onClick(self, event): indexButtonClicked = self.__get_index_button_clicked(event.getSource()) if self.buttons[indexButtonClicked].getIcon() == self.iconoVacio: if not self.__jugar(indexButtonClicked): self.resetGame() self.__resetTablero() ...
41
MIDDLEWARE
LISTADO 7
Clase RegistroJugadoresDBJython.py
from java import lang from java import sql import tresenrayajython, string, sys class RegistroJugadoresDBJython(tresenrayajython.RegistroJugadores): def __init__(self): tresenrayajython.RegistroJugadores.__init__(self) try: lang.Class.forName(org.gjt.mm.mysql.Driver) except Exception, e: print Se ha producido un error en la carga del driver, e try: url = jdbc:mysql://localhost:3306/tresenraya self.con = sql.DriverManager.getConnection(url,tresenraya,tresenraya) except Exception, e: print Se ha producido un error en el establecimiento de la conexion con la base de datos, e # Asegurarse que si no existe un usuario solop se aada usuarioSolop = self._executeSQLCommand(select * from usuario where nombreUsuario=solop) ... def _executeSQLCommand(self, command): # si la consulta devuelve resultados lo har como una lista de tuplas, # cada tupla es una fila de la tabla, y cada elemento de la tupla una columna resultado = [] command = string.strip(command) if len(command): try: stmt = self.con.createStatement() if string.lower(command).startswith(select): # si es una select ... rs = stmt.executeQuery(command) metadata = rs.getMetaData() # recupera todas las filas while rs.next(): # recupera todas las columnas contenidoFila = [] for i in range(1, metadata.getColumnCount()+1): try: columnType = metadata.getColumnType(i) contenidoColumna = None if columnType == sql.Types.INTEGER: contenidoColumna = rs.getInt(i) elif columnType == sql.Types.VARCHAR: contenidoColumna = rs.getString(i) else: contenidoColumna = rs.getObject(i) contenidoFila.append(contenidoColumna) except Exception, e: print e break resultado.append(tuple(contenidoFila)) else: stmt.execute(command) except: raise uExcepcion producida en ejecucion de comando + command return resultado
mximo valor de sus hijos. Los nodos del jugador MIN el mnimo de sus hijos. Los valores representan cmo de bueno es el movimiento. El jugador MAX tratar de elegir el movimiento que maximice el valor al final. Sin embargo, el jugador MIN, mientras tanto, seleccionar los movimientos que son mejores para l, minimizando en todo lo posible el resultado de MAX. Para ms detalles sobre este algoritmo y otros basados en IA recomendamos permanecer atentos a las novedades que incluir Slo Programadores en los prximos meses. En el CDROM ofrecemos una implementacin de la aplicacin de Tres en Raya que hace uso de MiniMax.
Conclusiones
Aqu acabamos nuestro recorrido por el lenguaje de programacin Python. Confo que a lo largo de estas cuatro entregas el lector haya podido descubrir el potencial de este gran lenguaje de scripting que combina a la vez potencia y sencillez. La aplicacin de tres en raya que hemos ido desarrollando tan solo ha mostrado cmo implementar en Python la funcionalidad correspondiente a las tareas programticas ms tpicas: programacin grfica, de acceso a bases de datos, web y XML. Por falta de tiempo no hemos podido descubrir otras muchas reas en las que Python tambin juega un papel destacado. Espero que, tras lo descrito en esta serie, el poder de Python os acompae en vuestras prximas tareas de programacin.
Antes de explicar el algoritmo es necesaria una breve introduccin a rboles de bsqueda. Un rbol de bsqueda es una notacin para representar bsquedas. La figura 8 representa uno de estos rboles. Los cuadrados son conocidos como nodos y representan puntos de decisin en la bsqueda. Los nodos estn conectados por ramas. La bsqueda comienza en el nodo raz, en la parte superior de la figura. En cada punto de decisin, los nodos para cada posible camino de bsqueda son generados, hasta que ms 42
decisiones no sean posibles. Los nodos al final de la bsqueda son los nodos raz. El algoritmo MiniMax considera la existencia de dos jugadores, el MAX y el MIN. Un rbol de bsqueda es generado, depth-first, comenzando con la posicin actual del juego hasta la posicin final del juego. Luego, la posicin final es evaluada desde el punto de vista de MAX. A continuacin, los nodos interiores del rbol son rellenados de abajo a arriba con los valores evaluados. Los nodos que corresponden al jugador MAX reciben el