miércoles, 8 de julio de 2015

El Para y los diagramas de flujo: ese pequeño gran detalle

Una pregunta en el foro de PSeInt trajo consecuencias inesperadas. La versión corta de la historia: hace más de 10 años que cometo sistemáticamente un error en mis diagramas de flujo (y entonces el error está en los diagramas de PSeInt). Es un detalle, pero según cómo se mire, puede no ser menor. Antes de revelar cuál es y contar la historia, hagamos una prueba. Solo voy a decir que el error está relacionado a la estructura repetitiva Para (el "for"). Antes de seguir avanzando en la lectura de este post, intente adivinar qué tiene "mal" el siguiente dibujo:

jueves, 2 de julio de 2015

Mientras tanto, en... (III)

Van dos meses sin novedades visibles en PSeInt: sin publicar versiones nuevas, sin hacer comentarios en el blog y sin terminar de ponerme al día con el foro. Por el lado de ZinjaI, pasa algo similar (no hay versiones desde hace 4 meses), aunque es más común dado que los cambios en ZinjaI usualmente requieren más tiempo y más pruebas. Y para completar, hace casi un mes que no escribo nada en el blog. En ambos proyectos hemos visto períodos mucho más largos sin novedades, pero no quiere decir que esa situación me simpatice. Me gusta que siempre haya algún movimiento, por mínimo que sea. Y en verdad lo hubo. Tratando de seguir la filosofía "release erale, release often", en breve lanzaré un par de actualizaciones para compartirlos. Mientras tanto, les cuento por dónde pasan los cambios y les adelanto un "trailer" de la próxima release.

viernes, 5 de junio de 2015

std::function: Ya tengo mi (nuevo) martillo

Todos conocen la frase "si solo tienes un martillo, todo te parece un clavo" o alguna variación con la misma idea. A mi, con la programación me pasa algo curioso. Tengo una caja repleta de herramientas de todo tipo, pero cada vez que agrego a la caja un martillo nuevo, todo lo demás se me convierte en clavo. Mi caja está mayormente llena de C++. Diría que casi todo C++03 está en la caja, y que gradualmente he ido agregando herramientas de C++11/14. En algún punto me pasó con eso de SFINAE y los trucos que se podían hacer, y los apliqué por todos lados. En otro momento, agregé a la caja las maravillosas "Variadic Templates" y grité "I have a hammer!", y variadic templates para todos.

Ahora, la funcionalidad de C++11 que se está tornando increíblemente "martillosa", es la aparición de las funciones lambda, y como yapa de la clase auxiliar std::function. Es decir, la posibilidad de crear funciones y clausuras "al vuelo", sin siquiera ponerles tipo ni nombre, y la facilidad que provee la clase std::function para apuntarle a esos pequeños monstruitos sin que nos importen ni preocupen sus especies. En MotoGT 2 están martillando cuanto clavo (y tornillo) se les cruza. Y el resultado es una delicia. Un buen motor puede dar muchas más libertades sin agregar ruido cuando hace uso de estas cosas, y permite al programador ser mucho más productivo.

domingo, 31 de mayo de 2015

Las bases de MotoGT 2: overview

Hace un tiempo les comenté que pienso reescribir MotoGT desde cero. Llamo a este proyecto MotoGT 2. Aunque por fuera, al principio será un clon del primer MotoGT con apenas unos pocos detalles nuevos visibles, por dentro la historia es totalmente diferente. El objetivo es obtener una base de código más sólida con la cual experimentar fácilmente agregando y quitando cosas al juego, para que lo que limite su desarrollo sea mi creatividad y mi poca idea de game-design, y no un código complicado y difícil de modificar o mantener.

Entonces, tengo que escribir un pequeño motor de juego. Lo suficientemente general como para que me provea esa flexibilidad. No tan general como para renegar con cosas que no necesito. Con una interfaz de alto nivel para no lidiar con detalles finos de implementación al concetrarme en la lógica del juego. Con capas o subsistemas desacoplados para que, por ejemplo, la biblioteca que use para gráficos y sonido no me condicione la forma de programar esa lógica del juego. Y más, como para que un imprevisto no tire abajo el proyecto.

martes, 26 de mayo de 2015

Constructores privados y std::shared_ptr

Tuve un problema de diseño/implementación con una clase en particular mientras escribía algunas cosas básicas para el nuevo MotoGT, que me resultó muy interesante por lo simple que es el planteo, y por los caminos rebuscados que puede tomar la respuesta. Básicamente quería garantizar que las instancias de una clase particular solo se pudiesen crear por medio de una función auxiliar. La solución habitual es poner el constructor de la clase como privado/protegido y hacer a la clase amiga de la función. Pero esto no es 100% seguro desde algún punto de vista y, por sobretodo, se complica cuando queremos usar std::shared_ptr y std::make_shared con esa clase. Si no se van, les cuento mejor dónde aparece el problema, para qué sirve, y a qué solución llegué.

martes, 19 de mayo de 2015

Problemas con la terminal y el depurador (parte 2)

Empecé el artículo anterior diciendo que iba a mencionar dos problemas con las terminales y la depuración en ZinjaI, pero como se hizo largo describí solo uno. Pues aquí viene el segundo. Es un problema levemente relacionado, muy molesto, pero generalmente inofensivo. Es el mensaje "&warning: GDB failed to set controlling terminal: Operation not permited" que se muestra al comenzar la depuración en GNU/Linux. Desde la versión 7.0 de gdb, muchos IDEs sufren este mensaje, que asusta al usuario inexperto y genera consultas de lo más variadas. Hay miles de hilos al respecto en foros varios en Internet, pero absolutamente ninguna solución. Yo tampoco pude solucionarlo, pero al menos llegué a entenderlo y me convencí de por qué en general no se puede, y qué consecuencias puede traer. Vengo a documentarlo porque leí miles de respuestas, y la mayoría no están ni remotamente cerca de la verdadera causa, y sus consecuencias.

miércoles, 13 de mayo de 2015

Problemas con la terminal y el depurador (parte 1)

Estuve analizando dos diferencias en el comportamiento de la terminal que usa ZinjaI para ejecutar un programa o proyecto entre la ejecución normal y la ejecución para depuración. La primera es que hasta ahora, la terminal donde se ejecuta la depuración se cierra al finalizar el programa, pase lo que pase, y no le hace caso a las opciones de ejecución que pueden decir que espere una tecla, o que no se cierre si el código de salida no es 0. Esto implica que en la mayoría de los casos, si una ejecución en el depurador finaliza como debe, no llegamos a ver los resultados, a menos que nos tomemos el trabajo de poner algún breakpoint al final del main. Tengo solo la mitad de este problema resuelto.

martes, 5 de mayo de 2015

Variables globales otra vez

Ya comenté que pensaba reescribir desde cero MotoGT. También que el no poder predecir/controlar el orden en que se construyen y destruyen las variables globales me trajo serios problemas. Pues bien, dado que en el nuevo MotoGT voy a volver a usar una buena cantidad de variables globales, me vi forzado a repensar el problema. Y finalmente, encontré una buena solución, con la que puedo tener mis queridas y odiadas variables globales, pero puedo además asegurarme de que se creen y destruyan en un orden correcto.

martes, 14 de abril de 2015

La terminal en blanco y una historia de variables globales

En marzo publiqué una actualización de PSeInt, y tardé como 20 días (mayormente por mi culpa, por mi delay con los foros) en notar que a varios usuarios no les funcionaba ni la ejecución básica. Cuando querían ejecutar un algoritmo, la terminal quedaba en blanco; y si querían editar el diagrama de flujo, estaba vacío. Y así algunos problemas más, pero todas cosas gruesas, importantes, absolutamente impresentables.... Y entonces ¿cómo es que subí eso y no me di cuenta? He aquí una historia de variables globales y estáticas en C++, con moraleja conocida: evitarlas a toda costa.

jueves, 9 de abril de 2015

MinGW64 y otras variantes para ZinjaI en Windows

Se supone que ZinjaI está preparado para configurar fácilmente más de un posible compilador. En GNU/Linux, suelo alternar entre gcc y llvm-clang sin problemas. Pero en Windows, el cambio es un poquito más delicado, porque el compilador y demás herramientas afines que están como parte de ZinjaI, y no del sistema. Si bien se suponía que era posible hacerlo de todas formas, y que teóricamente el cambio debía ser simple y directo, de la teoría a la práctica suele haber un buen trecho, y por eso no le tenía plena confianza a esta funcionalidad. Pero hace unos días finalmente lo probé y verifiqué que (muy sorprendentemente) funciona justo como esperaba. Y esto es algo muy bueno, porque ya es hora de empezar a utilizar 64bits. En este post les cuento cómo configurar otro MinGW que no sea el que trae ZinjaI, tomando una versión alternativa de 64bits como ejemplo, qué tiene esto de bueno, y cuáles son por ahora las limitaciones.

sábado, 4 de abril de 2015

La venganza de MotoGT (parte 2/2)

Les comenté hace poco que llegué a la inevitable conclusión de que tengo que reescribir MotoGT. A pesar de algunas ideas nuevas que mencioné para el diseño del juego, lo más importante es que en realidad ya no puedo seguir trabajando sobre el mismo proyecto. Y esto se debe a cuestiones técnicas, cuestiones de programación. Y como programar es lo que me gusta, muy probablemente me divierta más re-escribiendo el juego que jugandolo una vez "terminado".

lunes, 30 de marzo de 2015

La venganza de MotoGT (parte 1/2)

Hace unos días, cuando tuve algo más de tiempo libre de lo habitual, gracias a un fin de semana largo, intenté retomar algunas viejas cuestiones pendientes de MotoGT. Mi principal problema era (y es) migrar todo a SFML 2.x. Además, de eso, el juego estaba incompleto, y tenía algunas pocas ideas para mejorarlo. Pero al final no llegué a migrar ni implementar nada nuevo, sino que "solamente" (no es poca cosa) llegué a algunas conclusiones importantes al respecto. Resumiendo: tengo que escribir MotoGT 2, de cero. Los motivos son mayormente técnicos, pero en el medio de todo esto, hay lugar para muchas mejoras en el diseño del juego.

viernes, 20 de marzo de 2015

El boom de la Programación Funcional (parte 3/3)

Después de contar cómo fue mi primer acercamiento con la programación funcional y lo importante que me parece aprender algo al respecto (parte 1), y por qué siendo un paradigma tan viejo ha tomado nueva fuerza en los últimos años gracias al auge de la programación paralela principalmente (parte 2), hoy cierro contando muy básicamente cómo se lleva esto a mi lenguaje favorito, C++, que desde 2011 ha facilitado mucho las cosas en este sentido.

sábado, 14 de marzo de 2015

El boom de la Programación Funcional (parte 2/3)

Esta es la segunda parte de una trilogía de posts con desvarios propios y ajenos relacionados a la programación funcional. En la primera, hice una pequeña introducción intentando convencerlos de lo útil e interesante que es esto, pero sin decir nada en realidad. Y conté luego cual fue mi primer acercamiento casual a la misma, remontándome gracias a la Internet 30 años atrás. En esta segunda parte, volvemos a la actualidad, y les cuento cómo es que en estos últimos años se ha vuelto más importante.

lunes, 2 de marzo de 2015

El boom de la Programación Funcional (parte 1/3)

Desde hace relativamente pocos años, el paradigma de la programación funcional ha tomado un nuevo auge, hasta el punto en que hoy en día podríamos considerarlo como una especie de "trending topic" en el mundillo de la programación en general. Podría decir que los conceptos esenciales son más viejos que la programación misma. Pero, para alguien como yo, que tuve toda mi formación inicial en lenguajes estructurados y procedurales, que luego pasé a la "moderna" orientación a objetos, y que desde hace años C++ es mi herramienta de trabajo en el día a día, esto es nuevo. Es algo que empezó a hacerme ruido con la estandarización de C++11, y que por lo que veo, gracias al auge del paralelismo, llegó para quedarse.

Hay muchos programadores sueltos que han tenido una formación similar a la mía, y que aún no descubren lo enriquecedor que es el mundo de la programación funcional. A esos colegas les estoy escribiendo. Por que si bien, es muy probable que yo nunca use de verdad un lenguaje realmente funcional, las ideas que me va implantando el aprender sobre este paradigma sí repercuten en mi forma de pensar los problemas y analizar las implementaciones. Creo que todo informático debería tener una formación básica en programación funcional, con el solo objetivo de abrirle la cabeza a otra forma de analizar un programa y de entender la programación.