Tic-Tac-Toe en una sola línea de código

Fuentes: GitHub - carlini/printf-tac-toe: tic-tac-toe in a single call to printf

Este código, creado por Carlini, es una implementación sorprendentemente compacta del juego Tic-Tac-Toe (Tres en Raya) escrita completamente en un único printf en C. El objetivo es demostrar la capacidad de printf para realizar cálculos complejos y control de flujo, más allá de su función principal de formateo de salida. El código fue creado como una demostración de la completitud de Turing de printf, una idea explorada previamente en un artículo académico.

La clave de esta implementación reside en el uso ingenioso de las características avanzadas de printf, específicamente sus especificadores de formato. Normalmente, printf toma argumentos para insertar en una cadena de formato. Sin embargo, los especificadores de formato pueden tomar argumentos adicionales que modifican su comportamiento. Por ejemplo, %1$.*2$d imprime el segundo argumento como un entero, con un número de dígitos (rellenados con ceros) determinado por el primer argumento. Esto permite realizar cálculos arbitrarios dentro de la cadena de formato.

El juego en sí se representa como un conjunto de bits almacenados en memoria. Estos bits representan el estado del tablero (quién ha colocado una ficha dónde) y el turno del jugador. Las operaciones lógicas (OR, NOT) se implementan utilizando combinaciones específicas de especificadores de formato, manipulando la cadena de formato para realizar cálculos binarios. Por ejemplo, una operación OR se logra con printf("%1$s%2$s%3$hhn", a, b, c), donde a y b son cadenas que representan bits, y c es un puntero a una variable donde se almacenará el resultado. La función %hhn escribe el número de bytes escritos hasta el momento en la variable apuntada por c, lo que permite realizar operaciones bit a bit.

La detección de victorias y empates también se implementa dentro de la cadena printf, utilizando lógica similar para evaluar las posibles combinaciones ganadoras. La visualización del tablero se construye dinámicamente dentro de la cadena printf, utilizando especificadores de formato para convertir los bits internos en caracteres 'X', 'O' y espacios en blanco.

Finalmente, el código incluye una llamada a scanf para leer la entrada del usuario (la jugada del jugador). La cadena de formato para scanf también se construye dinámicamente dentro de la cadena printf, lo que permite alternar entre la visualización del tablero y la lectura de la entrada del usuario en una sola secuencia de llamadas a printf. El código es una demostración impresionante de la flexibilidad y el poder oculto de la función printf en C.