Claude Elwood Shannon

Si quieres, puedes leer las partes anteriores a este artículo.

Ajedrez por ordenador: pasado, presente y futuro (Parte 1)

Ajedrez por ordenador: pasado, presente y futuro (Parte 2)

Ajedrez por ordenador: pasado, presente y futuro (Parte 3)

Decíamos ayer…

Lo primero, un saludo a los lectores después de dos meses largos. Espero que hayáis tenido un estupendo verano.

Un comentario antes de seguir analizando el artículo de Shannon: La posición empleada para probar la función de evaluación definida en el artículo anterior corresponde (como muchos lectores ya saben) a la partida Anderssen-Kieseritzky, Londres 1851, conocida como “La Inmortal”:

Figura 1: Una posición inmortal.

Para quien no la conozca, la partida completa, con muchos comentarios interesantes, puede verse en este enlace:

http://www.chessgames.com/perl/chessgame?gid=1018910

Y ahora sigamos donde lo dejamos entonces, es decir, en la función de evaluación f(P) que, como vimos, proporciona una valoración aproximada de cualquier posición dada. Este sería el primer paso para establecer una estrategia, ejecutable por un ordenador, que nos permitiera escoger una jugada (si no óptima, al menos plausible) en cualquier posición dada, en un tiempo razonable.

Una estrategia para todo el año

La primera estrategia propuesta por Shannon, a la que llamó Estrategia A (y como tal se sigue conociendo) consiste en lo siguiente:

  • Establecer un nivel de profundidad de análisis, adaptado al tiempo de proceso disponible. Supongamos, por ejemplo, una posición en la que es el turno del blanco y establezcamos un nivel de profundidad de 8 movimientos, lo que equivale a cuatro jugadas (cuatro movimientos de blancas y cuatro de negras).
  • Calcular f(P) para todas las posiciones finales (en nuestro ejemplo, todas las que se producen tras el cuarto movimiento de las negras) de todas las ramas del árbol de variantes. Es importante destacar esas dos “todas”, pues son parte fundamental de la Estrategia A.
  • Escoger, en cada nodo del penúltimo nivel, la valoración que más favorezca al bando que tiene el turno en ese punto (el negro en este caso); de esta forma asignamos a cada posición del penúltimo nivel (en nuestro ejemplo, tras el cuarto movimiento del blanco) un valor seleccionado en el último nivel.
  • Repetir el paso anterior para estas posiciones del penúltimo nivel, pero escogiendo ahora las valoraciones más favorables al blanco. Ahora son las posiciones del antepenúltimo nivel (tras el tercer movimiento del negro) las que reciben su valoración.
  • Esta iteración se llevará hasta que se alcance la posición inicial, que recibirá, de las valoraciones asignadas a las posiciones inmediatamente debajo de ella, la que favorezca a los intereses del bando que tiene el turno (en este caso el blanco).

En esta Estrategia A de Shannon, con algunos refinamientos que iremos viendo, se basan todos los módulos que han aparecido en los últimos treinta años, hasta la irrupción de AlphaZero y programas similares.

Quien haya leído mi segundo artículo ya habrá comprendido que estamos hablando de hacer un minimax parcial. En su momento mostré que esta estrategia tiene un defecto capital, conocido como efecto horizonte (el riesgo de que se nos escape algo importante porque está más allá de nuestro nivel de análisis). Shannon es consciente de este defecto, cuyos efectos en ajedrez son evidentes en posiciones dinámicas, como aquellas en las que hay un intercambio de piezas o un ataque al rey. Pero el peligro del efecto horizonte también existe en posiciones tranquilas (o aparentemente tranquilas). Por ejemplo:

Figura 2: Horizontes no lo bastante cercanos.

Mueven blancas. Supongamos que la profundidad de análisis es de 4 (dos movimientos por turno) y que la función de evaluación incluye, entre otros, estos criterios:

  • Número de peones rivales atacados.
  • Número de peones rivales protegidos.

Vayamos ahora al nodo que se genera después de 1 Rc5 Rg3. Aquí, a igualdad de otros criterios, e independientemente de cuál sea el segundo movimiento de las negras, el ordenador elegirá la jugada 2 Rd5, que ataca un peón rival y defiende uno propio. Esta jugada, en su función, es mejor que 2 Rd6, que ataca un peón rival pero no defiende ninguno propio; y mejor que todas las demás, que ni atacan ni defienden peones.

Por desgracia para el ordenador, la jugada elegida es perdedora, pues tras 2 … Rf5 el rey blanco se ve obligado a alejarse de los peones. En cambio, 2 Rd6! gana, ya que después de 2 … Rf5 sigue 3 Rd5 (ahora sí) y es el rey negro el que tiene que ceder. Pero la jugada 3 Rd5, y todo lo que le sigue, está fuera del campo de visión del ordenador.

Hay técnicas de programación que permiten paliar (no eliminar) los efectos del efecto horizonte, y hablaremos de ellas más adelante. En cualquier caso, es algo con lo que hay que contar.

Una explicación patas arriba

Ya tenemos estrategia. Veamos ahora cómo introducirla en un ordenador.

En esta parte voy a apartarme bastante de la explicación formal de Shannon, aunque el fondo es equivalente. El motivo es que, desde que se escribió dicho artículo hasta hoy, la informática ha cambiado mucho. Entonces prácticamente no existían los lenguajes de programación, salvo el ensamblador, que más que un lenguaje es una traducción directa de las instrucciones básicas del procesador (el llamado código máquina) a abreviaturas comprensibles para un humano.

Empezaremos por definir numéricamente el tablero de ajedrez; después asignaremos valores a las piezas que contiene cada una de sus casillas (Shannon lo hace al revés: es cuestión de gustos).

Para lo primero crearemos una matriz bidimensional T, de 8×8 datos, cada uno de cuyos elementos, obviamente, corresponderá a una casilla del tablero. Cada elemento de esta matriz tendrá un valor numérico entero de dos cifras, empezando en 11 (casilla a1) y terminando en 88 (casilla h8). La siguiente figura muestra a cada elemento sobre la casilla que representa en el tablero:

Figura 3: El cartón de bingo ajedrecístico.

Shannon usa números de 0 a 7 en lugar de 1 a 8. Ambas opciones son equivalentes, pero a mí me gusta más la segunda, más que nada porque es más fácil de asociar con la notación algebraica (basta con sustituir la primera cifra por su equivalente en el orden alfabético: 1 = a, 2 = b, etcétera).

En esta estructura es fácil definir las operaciones necesarias para calcular a qué casillas puede ir una pieza:

  • El rey puede ir a casillas cuyas diferencias con respecto a la casilla de partida sean: ±1, ±10, ±11 ó ±9 (y que estén, obviamente, dentro del tablero). Por ejemplo, aplicando esas diferencias en el orden indicado, desde la casilla 51 (e1) obtendremos los siguientes valores, de los cuales descartaremos los que no correspondan a casillas reales:
    • 51 ± 1 = 52 (e2), 50 (no existe).
    • 51 ± 10 = 61 (f1), 41 (d1).
    • 51 ± 11 = 62 (f2), 40 (no existe).
    • 51 ± 9 = 60 (no existe), 42 (d2).
  • Además, en el enroque el rey puede ir a casillas con diferencias ±20.
  • La dama puede ir a casillas cuyas diferencias con respecto a la suya tengan los mismos valores que el rey, más sus múltiplos, siempre que estén dentro del tablero:
    • ±1, ±2, ±3, ±4…
    • ±10, ±20, ±30, ±40…
    • ±11, ±22, ±33, ±44…
    • ±9, ±18, ±27, ±36…
  • El caso de la torre es igual que el de la dama, pero usando solo las dos primeras líneas anteriores, que corresponden a movimientos en horizontal y vertical.
  • Para el alfil usaremos, en cambio, las dos últimas líneas del caso de la dama, correspondientes a movimientos en diagonal.
  • El caballo podrá ir a casillas con estas diferencias: ± 8, ±12, ±19, ±21.
  • El peón blanco podrá ir a casillas con estas diferencias:
    • +1 (avance normal).
    • +2 (avance doble, si está en su casilla inicial).
    • +9 y +11 (si puede capturar, ya sea o no al paso).
  • El peón negro, como el blanco, pero con valores negativos.

Ya hemos dado valores a las casillas. Ahora se los daremos a las piezas que ocupan las casillas, siguiendo, en este caso sí, las indicaciones de Shannon (como siempre, según mi traducción):

Una casilla de un tablero de ajedrez puede ocuparse de 13 maneras diferentes: o bien está vacía (0) o bien ocupada por una de las seis posibles clases de piezas blancas (Peón=+1, Caballo=+2, Alfil=+3, Torre=+4, Dama=+5, Rey=+6) o negras (Peón=-1, Caballo=-2, …, Rey=-6). Así, el estado de una casilla viene dado por un número entero de -6 a +6.

De acuerdo con esto, crearemos una segunda matriz P, también bidimensional 8×8, como la matriz T. Cada elemento de P tendrá, como indica Shannon, un valor numérico de -6 a +6. Estos valores no corresponden a los valores relativos de las piezas que vimos en el artículo anterior, ni tienen significado en ese aspecto; son solo una representación numérica que nos permite “decir” al ordenador qué pieza hay en cada casilla.

Así pues, hemos “superpuesto” al tablero dos matrices T y P, de manera que cada casilla tiene dos valores asignados:

  • Su valor propio, procedente de la matriz T, y que representa su ubicación en el tablero. Este valor es único e inmutable para cada casilla.
  • Su valor asociado, procedente de la matriz P, y que representa la pieza que ocupa dicha casilla, o si está vacía. Este valor no es único (varias casillas pueden estar vacías u ocupadas por piezas del mismo valor) ni inmutable (cada casilla puede tener diferentes piezas en diferentes momentos).

En la posición inicial, por ejemplo, la casilla e8 tendrá los valores T(e8) = 58 (inmutable) y P(e8) = -6 (por estar ocupada en este momento por el rey negro).

Propongo ahora al lector que identifique la siguiente posición:

Figura 4: Viene un mate de campeonato.

Por tanto, ya hemos definido el tablero y las piezas, pero para definir la posición necesitamos representar numéricamente algunos elementos más:

  • El turno de juego se representará por una variable J, que valdrá +1 si es el turno de las blancas y -1 si lo es de las negras.
  • Para las opciones de enroque usaremos otra matriz bidimensional, esta vez de 2×2, a la que llamaremos E. Sus elementos valdrán 1 si el enroque es posible y 0 si no lo es, y corresponderán a las siguientes opciones:
    • E(1,1): enroque largo de las blancas.
    • E(1,2): enroque corto de las blancas.
    • E(2,1): enroque largo de las negras.
    • E(2,2): enroque corto de las negras.
  • La posibilidad de captura al paso se representará por una variable C, que podrá tener estos valores:
    • Si la última jugada ha sido un avance doble de peón, C tendrá el valor de la casilla en la que se puede producir la captura al paso. Por ejemplo, después de 1 e4, la variable C valdrá 53 (casilla e3).
    • Si la última jugada no ha sido un avance doble de peón, C valdrá 0.
  • Los movimientos que han transcurrido desde la última captura o avance de peón. Esta cuenta la llevaremos en una variable M, que se pondrá a 0 cuando haya una captura o avance de peón, y se incrementará en una unidad cuando no.
  • Por último, el número de jugada en que estamos se almacenará en la variable N, que se aumentará en una unidad siempre que haya un movimiento de las blancas.

Algunas aclaraciones:

  • El turno de juego J tiene un significado importante, además del obvio de saber quién mueve: Cuando estemos buscando jugadas legales para un bando, al encontrar una pieza en una casilla sabremos si es amiga o enemiga multiplicándola por J: si la pieza es del bando que mueve, la multiplicación indicada dará un resultado positivo, y si es del rival, negativo.
  • En lo que se refiere al enroque, hablamos de opciones duraderas; por ejemplo, en una posición concreta el blanco puede estar en jaque y no podrá enrocar en ese momento; pero si se defiende del mismo sin mover el rey, podrá enrocar más adelante. En este caso consideraremos que el enroque es posible y por tanto el elemento correspondiente valdrá 1, aunque en ese momento no sea una jugada legal (y como tal deberá excluirla el procedimiento encargado de generar jugadas legales que veremos más adelante).
  • En cuanto a la captura al paso, daremos valor a C independientemente de que haya un peón rival que pueda aprovecharse del doble avance para capturar al paso. Eso lo determinará, como en el caso anterior, el procedimiento generador de jugadas legales.
  • La variable M crece en una unidad con cada movimiento, ya sea blanco o negro; esto quiere decir que, para saber si se han hecho cincuenta jugadas desde la última captura o avance de peón, habrá que comprobar si M vale 100, no 50 (pues la regla se refiere a cincuenta jugadas, es decir, cincuenta movimientos de cada bando).
  • El número de jugada tiene un significado relativo, y de hecho Shannon no lo menciona; pero hoy en día es habitual indicarlo para transcribir una partida de forma más exacta.

Ya podemos completar la posición del tablero anterior (figura 4) con estas variables:

  • J = 1 (juegan blancas).
  • E(1,1) = E(1,2) = E(2,1) = E(2,2) = 0 (ningún enroque es posible).
  • C = 0 (no hay casilla de captura al paso).
  • M = 5 (hace cinco movimientos que se produjo la última captura o avance de peón).
  • N = 49 (estamos en la jugada 49).

Con esto hemos pasado a valores numéricos todos los elementos que confirman una posición. Lo hemos hecho con una representación que no es la más económica, pero sí es sencilla de implementar en un programa de ordenador. Por ejemplo, la representación FEN (Forsyth–Edwards Notation), que tiene más de cien años, es más compacta y “legible a simple vista”; sin embargo, es poco práctica para realizar cálculos.

Un fleco “de poca monta”

Hay un aspecto importante de la posición que no hemos considerado, y es la posibilidad de que se dé una triple repetición de la posición. Evidentemente, esta posibilidad es un factor importante y por tanto deberíamos tenerlo en cuenta. Supongamos, por ejemplo, una posición en la que hay una variante ganadora forzada, pero la posición que se da tras la primera jugada de dicha variante se ha repetido ya dos veces en la partida; entonces la jugada llevaría a tablas, si el rival reclama la triple repetición.

Por desgracia, en la práctica no hay forma eficaz de representar esta circunstancia. Incluso si tuviéramos presente solo el caso del ejemplo descrito, tendríamos que indicar todas las jugadas que dan lugar a una triple repetición (y pueden ser varias; recordemos que la regla habla de repetición de posiciones, no de jugadas). Ahora bien, para que la información fuera completa, también tendríamos que indicar qué otras posiciones se han repetido antes; de hecho, tendríamos que indicar todas las posiciones que se han dado en la partida, aunque solo haya sido una vez, por si acaso se repiten en el futuro.

Dicho de otro modo, para controlar esta regla no nos basta con la posición, necesitamos la partida entera. Por este motivo, ninguna representación de posiciones tiene en cuenta este factor; solo se tiene en cuenta durante el transcurso de una partida (haciendo precisamente lo que decía antes, es decir, guardar la información de las posiciones que se han repetido).

¡Un poco de acción!

Ya sabemos cómo representar con números cualquier posición de ajedrez. Veamos ahora cómo representar jugadas. Si asumimos que nuestras jugadas son legales, esto es relativamente simple. Volviendo de nuevo a Shannon:

Cualquier movimiento (excepto la promoción de peón y el enroque) se puede especificar dando las casillas inicial y final ocupados por la pieza movida. […] Para representar la promoción de un peón, se añade un tercer valor que indique la pieza en la que el peón se convierte. El enroque viene descrito por el movimiento del rey (al ser esta la única ocasión en que el rey puede mover dos casillas). Por lo tanto, un movimiento es representado por (a, b, c), donde a y b son casillas y c especifica una pieza en caso de promoción.

En nuestro caso, las a y b de Shannon serán los valores inmutables de las casillas de origen y destino, y c será, o bien un valor de 2 a 5 (según se promocione a caballo, alfil, torre o dama, respectivamente), o bien 0, si no hay una promoción implicada. Ejemplos:

  • Si el rey negro situado en e8 captura un alfil blanco en f7, el movimiento se representará como (58, 67, 0).
  • Si un peón blanco corona avanzando de c7 a c8 y se promociona a torre, la representación será (37, 38, 4).

Como siempre, algunas aclaraciones:

  • Que la jugada sea una captura o no es indiferente en esta representación (y en prácticamente todas las representaciones usadas en ajedrez; de hecho, el uso de “x” o “:” para indicar una captura al transcribir una partida es opcional).
  • El enroque se describe solo con el movimiento del rey. La parte del proceso que se encargue de “efectuar” la jugada deberá en estos casos, si se trata de un rey, mover también la torre correspondiente (ya hemos asumido que nuestras jugadas son legales, por tanto un movimiento del rey entre estas casillas solo lo sería si se dieran las condiciones legales del enroque).
  • Similarmente, asumimos que la presencia de un valor de c distinto de 0 solo se dará en caso de una promoción legal.

El monstruo entra en escena

Ya sabemos cómo representar numéricamente posiciones y jugadas de ajedrez de forma que el ordenador las entienda; ahora queda lo difícil, que es conseguir que el ordenador haga algo con ellas. Para ello, Shannon propone una serie de subprogramas (hoy los llamaríamos rutinas) que realicen las diferentes tareas que componen la estrategia adoptada. De nuevo me voy a permitir modificar un poco la forma de la exposición, siempre conservando el fondo.

Claude Elwood Shannon

Imaginemos que nuestro módulo acaba de realizar su jugada. Su información de entrada en este momento es la posición resultante de dicha jugada (en realidad los módulos actuales tienen mucha más información a mano, pero de eso hablaremos otro día). De repente le llega una nueva información: la respuesta del rival. ¡La maquinaria se pone en marcha!

Por simplificar, voy a asumir que el dato que le llega al módulo, en lugar de la jugada del rival, es directamente la posición resultante de la misma (con toda la información asociada que conocemos, acerca de si es posible enrocar, capturar al paso, etcétera). Después de todo, saber cuál ha sido la última jugada es importante para un humano (puede darnos pistas sobre las intenciones del rival), pero a nuestro módulo esa información le da igual.

Nuestro programa necesitará las siguientes rutinas de proceso (los nombres son a gusto del programador o, en este caso, del articulista):

  • GEN: Rutina que genera una lista de todos los movimientos legales en una posición.
    • Datos de entrada: Una posición P.
    • Datos de salida: Una lista de todos los movimientos M(P) legales en la posición P.
  • MOV: Rutina que efectúa un movimiento sobre una posición dada.
    • Datos de entrada: una posición P y un movimiento M(P) legal en dicha posición.
    • Datos de salida: una posición P’, resultante de aplicar dicho movimiento a la posición de entrada.
  • EVAL: Rutina que calcula la valoración de una posición.
    • Datos de entrada: Una posición P.
    • Datos de salida: Una valoración V(P), resultado de aplicar la función de evaluación f(P) a la posición de entrada.
  • SEL: Rutina que selecciona la mejor jugada.
    • Datos de entrada: Todas las posiciones y valoraciones generadas en los procesos previos.
    • Datos de salida: El movimiento M(P) seleccionado como óptimo en la posición inicial.
  • PRIN: Rutina principal que llama a las rutinas anteriores cuando procede.
    • Datos de entrada: Una posición P.
    • Datos de salida: El movimiento M(P) seleccionado como óptimo en la posición inicial.

Y las consabidas aclaraciones:

  • Shannon consideraba una rutina GEN por cada pieza, no una rutina para todas. Efectivamente cada pieza tiene sus costumbres, pero también comparten rasgos comunes, por lo que resulta conveniente agruparlas en una sola rutina.
  • La función f(P) es la que vimos en el artículo anterior, u otra similar.
  • Las posiciones de entrada de la rutina SEL son todas las posiciones de todos los niveles, organizadas de forma que conserven la estructura de árbol de variantes; las valoraciones de entrada, en cambio, son solo las del último nivel (pues, como vimos en la segunda entrega, estas se van asociando a los niveles superiores).
  • Como es de esperar, la entrada de la rutina principal PRIN coincide con la entrada de la primera rutina secundaria; y la salida de PRIN coincide con la salida de la última rutina (todas en cursiva).

Además de la posición de partida (resultante de la jugada del rival), proporcionaremos al módulo un dato más: el nivel de máxima profundidad que el programa deberá avanzar en el árbol de variantes. Llamaremos a este valor nivel máximo o Nm (hoy en día los módulos manejan este valor de forma dinámica, dependiendo del tiempo disponible). Utilizaremos otro valor variable, nivel actual o Na, que empezará valiendo 0 y aumentará después de cada iteración, hasta que alcance el valor de Nm.

Un análisis rutinario

Veamos ahora cómo funcionaría la rutina principal PRIN. Su esquema de proceso simplificado (muy simplificado) sería este:

Figura 4: La rutina PRIN.

Y este sería el funcionamiento:

  • Al recibir el dato de entrada P (posición generada por el último movimiento del contrincante), la rutina PRIN se pone en marcha y llama a la rutina GEN para que esta genere todos los movimientos legales en dicha posición. Por tanto, al comienzo, GEN se ejecuta una sola vez.
  • La rutina GEN genera la lista de dichos movimientos M(P) y la entrega a PRIN, que llama ahora, para cada elemento de la lista, a la rutina MOV. Esta efectúa en la posición P cada movimiento M(P) recibido y genera una nueva posición P’ diferente.
  • La expresión “Na++” es una forma típica en programación de representar que la variable en cuestión se aumenta en una unidad. Es decir, que en este caso Na pasa a valer 0 + 1 = 1. Con esto se completa el primer bucle de proceso.
  • Lo siguiente que hace PRIN es comparar Na con Nm. Mientras Nm siga siendo mayor que Na, la condición “Na = Nm” no se cumplirá y el proceso volverá al primer paso (GEN).
  • El bucle se repite hasta que Na alcance el valor de Nm. En ese momento, la condición “Na = Nm” se cumple y el proceso sale del bucle hacia la derecha del esquema.
  • Ejecutamos la rutina EVAL y, a continuación la rutina SEL, que nos devolverá la jugada elegida.

Como ya he dicho, este esquema está muy simplificado. ¿Por qué? Porque en realidad he obviado algunos bucles secundarios que se producen dentro del bucle principal (y otro que se produce fuera del mismo). Estos bucles indicarían que las rutinas GEN, MOV y EVAL se ejecutarán varias veces.

¿Y cuántas veces, exactamente? Lógicamente, eso dependerá de varios factores. Supongamos que Nm = 6 (nivel de profundidad de seis movimientos, es decir, tres jugadas). Supongamos, además, que en cada nivel hay 25 jugadas posibles (una estimación conservadora). En ese caso:

  • En el primer bucle, GEN se ejecuta una sola vez y MOV 25 veces.
  • En el segundo bucle, GEN se ejecuta 25 veces y MOV 25 x 25 = 625 veces (veinticinco jugadas legales para cada una de las veinticinco posiciones P’ generadas en el bucle anterior).
  • En el tercero, GEN se ejecuta 625 veces y MOV 15.625 veces.
  • En el cuarto, GEN se ejecuta 15.625 veces y MOV 390.625 veces.
  • Los valores para el quinto bucle son 390.625 y 91625, respectivamente.
  • Y para el sexto bucle, 91625 y 2441140.625.
  • La rutina EVAL se ejecutará también 2441625 veces.
  • Por último, la rutina SEL se ejecuta una sola vez, pero, como veremos, ¡menuda ejecución!

En otro momento entraré en detalles de las dificultades que pueden encontrarse al programar estas rutinas, en especial GEN y SEL (MOV y EVAL son más sencillas). Lo que queda claro es que, incluso usando una estimación conservadora del número de movimientos legales por posición (25), y con una profundidad de 3 movimientos por bando (insuficiente para la inmensa mayoría de posiciones), ya manejamos enormes cantidades de procesos. Y veamos cómo aumentan estas cifras para más niveles:

  • Para 4 movimientos por bando, MOV y EVAL se procesarán 152.5871625 veces cada una (considerando para MOV solo el último bucle).
  • Para 5 movimientos por bando, la cifra anterior sube a 9524311640.625 veces.
  • Para 6 movimientos por bando, 59.60427751390.600 veces. ¡Casi sesenta mil billones de veces!

En los años cincuenta, estas cifras eran inmanejables para cualquier ordenador. Por eso Shannon propuso una estrategia alternativa, a la que llamó “Estrategia B”. En el próximo artículo veremos en qué consiste esta estrategia, que durante décadas fue el Santo Grial de los programadores de ajedrez.

Contando nodos.

Con el final del verano llegan las clases y, con ellas, los deberes. Aquí va el de hoy:

¿Cuál es el número exacto de posiciones que contiene el árbol de variantes de la siguiente posición, con una profundidad de 2 (un movimiento por bando)?

Figura 5: Un problema problemático.

Hay que tener en cuenta algunas cosas:

  • La posición se dio en la partida López de Turiso-Elissalt, Campeonato de España de Veteranos, Altea, octubre de 2018, después de la jugada 29 del negro.
  • Al contar las posiciones del árbol, la inicial no cuenta, pero las de los niveles intermedios sí; hay que sumar todas ellas.

Recuérdese que mis preguntas siempre llevan trampas, aunque son trampas sin mala intención que se pueden sortear usando la información disponible…

8 COMENTARIOS

  1. Gracias otra vez, Juan. Celebro que te guste. Ya sabes que cualquier crítica, sugerencia, comentario… será bien recibido.

  2. Gracias por tu comentario, Jhonnatan.

    Shannon no escribió un código específico, simplemente dio unas pautas que otros siguieron durante varias décadas (de ahí su importancia). Por otro lado, el objetivo de estos artículos no es bajar hasta el nivel del código, sino describir la evolución del ajedrez por ordenador a lo largo de estos años.

    Saludos cordiales,

    JF

  3. Otro artículo bien desarrollado y muy interesante, pero como dije en algún comentario anterior, este también es muy técnico, y aunque tengo estudios superiores, nada relacionado con los números, donde soy un “negado”.

    Pero como el tema me gusta, lo leeré y releeré varias veces hasta “pillarlo”… espero. Aún así algo he “pillado” ya, y me ha gustado, así que seguiré en los pocos ratos libres que tengo, y volveré a comentar.

    • Muchas gracias Francisco.

      Mientras escribía los últimos artículos yo también tenía miedo de que fueran demasiado “matemáticos”. Pensé en quitar toda la parte técnica, pero al final decidí dejarla por dos motivos: (1) Me parece importante para entender cómo funcionan los módulos, y (2) Incluso para alguien poco aficionado a los números, creo que los argumentos se pueden seguir si se presta un poco de atención (al fin y al cabo, son sumas, restas y multiplicaciones).

      Por supuesto, si hay algo que no te quede claro, no dudes en preguntarlo, que para eso estamos.

      Saludos corrdaieles,

      jf

  4. José Fernando, he leído de forma rápida los 4 artículos. Los volveré a leer con más detenimiento, pero en esta primera lectura, me han parecido muy interesantes y espero que siga en esa línea que a los aficionados y profesionales abre una puerta extraordinaria.
    Cuando acabe con esta línea más numérica, sería interesante abrir líneas de otro tipo: como la influencia del tiempo en la reacción de los jugadores, sensaciones respecto al rival y del propio jugador, personalidad del jugador, etc. que se alejan del juego de la máquina pero que son tan reales en el juego diario, sea de competición oficial o no.

    Un cordial saludo

  5. Muchas gracias por tus comentarios, Antonio. Espero que las próximos entregas te gusten tanto como las anteriores.

    En cuanto a los temas que sugieres, no los trato directamente en esta serie de artículos, pero sí a menudo indirectamente, porque uno de los puntos más interesantes de todo esto es la enorme diferencia entre cómo decide un ordenador y cómo lo hace un ser humano.

    En este mismo cuarto artículo, por ejemplo, comento de pasada la diferencia entre la importancia de la última jugada para un humano o para un módulo (para este último es indiferente, ya que trata la posición resultante independientemente de cómo se haya producido; mientras que para el humano es una pista importante sobre las intenciones del rival).

    Y en artículos anteriores encontrarás algunas reflexiones sobre las diferentes “opciones” disponibles para uno y otro, y las muy diferentes formas que tiene cada uno de decidir entre ellas.

    Saludos cordiales,

    jf

DEJA UNA RESPUESTA

¡Por favor, escribe tu comentario!
Please enter your name here

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.