Cómo construí mi proyecto individual: un motor de ajedrez para un motor de desarrollo de juegos popular

Recientemente terminé uno de mis proyectos de verano: un motor GUI de ajedrez construido usando el motor de desarrollo de juegos Ren'Py Visual Novel y la biblioteca python-chess.

Este motor se integrará en un juego de novela cinética, The Wind at Dawn , al finalizar ese juego.

En esta publicación, me gustaría compartir algunos aprendizajes clave, técnicos y no técnicos, que obtuve al impulsar este proyecto de una sola persona de principio a fin en un mes.

Aprecia el valor de reescribir el código antiguo

Para los proyectos de informática en la escuela, rara vez tengo la oportunidad o experimento la necesidad de revisar mi código.

Sin embargo, este no es el caso cuando trabajo en mis proyectos apasionantes: me encanta aprovechar cada oportunidad para mejorar su usabilidad y reutilización con la esperanza de que mi código sea de valor para otros desarrolladores.

Este motor de ajedrez se basa en un motor de ajedrez que creé en Ren'Py y vanilla Python mientras me enseñaba Python durante mis primeras vacaciones de verano en la universidad.

Ese viejo motor de ajedrez se basa, a su vez, en un proyecto de mi clase de introducción a la informática de la universidad (un juego de ajedrez GUI escrito en Racket, un lenguaje de programación funcional). Es decir, he reescrito mi código dos veces para producir este motor de ajedrez final.

Para mi primera reescritura, simplemente "traduje" la lógica del ajedrez (para determinar si un movimiento es legal, las condiciones del final del juego, etc.) de Racket a Python. También experimenté con la programación orientada a objetos, escribí una IA de ajedrez minimax siguiendo los tutoriales en línea e implementé la GUI en Ren'Py.

Como solo conocía los conceptos básicos del ajedrez y escribí mi lógica de ajedrez según la especificación de calificación de mi proyecto escolar, mi primer motor de ajedrez no admitía movimientos especiales como al paso, enroque o promoción.

Para abordar este problema en mi segunda reescritura, investigué bibliotecas de Python de código abierto y encontré python-chess, una biblioteca con soporte completo para movimientos de ajedrez y condiciones de final de juego, como reclamar un empate cuando ocurre una repetición triple.

Además de eso, también ha integrado Stockfish, una IA de ajedrez, y esta integración permitirá que mi motor de ajedrez configure la fuerza de la IA de ajedrez.

Estas dos características agregaron un gran valor a la versión 2.0 de mi motor de ajedrez y me permitieron concentrarme en los aspectos más importantes de mi reescritura, que describiré a continuación.

Lea la documentación y tenga en cuenta la compatibilidad

Se ha convertido en mi hábito de hojear la documentación de las bibliotecas que necesito para mi proyecto antes de saltar al diseño y al código. Esto me ayuda a evaluar cualquier problema de dependencia y compatibilidad que pueda surgir.

Este problema de Ren'Py GitHub apunta al hecho de que Ren'Py usa Python 2 y aún no se ha portado a Python 3. Entonces reconocí que necesitaba una versión de python-chess que admita Python 2, ya que solo es la última versión es compatible con Python 3.7+.

Afortunadamente, la versión 0.23.10 es compatible con Python 2.7 y Python 3.4+. Finalmente me decidí por la versión 0.23.11 ya que es la última versión que todavía es compatible con Python 2.7.

Habiendo resuelto los problemas de dependencia y compatibilidad, estaba listo para pasar al diseño y la codificación.

Siga las mejores prácticas de ingeniería de software

Nota: Muchos de los términos mencionados en esta sección son de Agile / Scrum.

Reúna los requisitos de funciones para el diseño de proyectos

Si bien es tentador saltar directamente a la codificación, no puedo enfatizar lo suficiente la importancia del diseño.

Piense en el diseño como una hoja de ruta de alto nivel que delimita claramente el punto de partida, los hitos y los puntos finales del proyecto. Esto permite a los desarrolladores referirse a los detalles de implementación intrincados hasta la cintura.

Esto es especialmente importante para los proyectos extracurriculares, ya que generalmente no tienen una especificación detallada y altamente técnica, mientras que la mayoría de los proyectos escolares sí.

Para mi motor de ajedrez, identifiqué las siguientes reescrituras / características adicionales:

  • Integrar la lógica del ajedrez de python-chess
  • En mi código de interfaz gráfica de usuario de Ren'Py, reemplace la lógica de ajedrez y la IA de ajedrez que escribí con la lógica de ajedrez y las API de Stockfish de python-chess
  • Admite varios modos de juego: jugador contra jugador, jugador contra computadora (donde el jugador puede elegir jugar en blanco o negro), fuerza ajustable de la IA del ajedrez mediante ajustes en los parámetros de configuración de Stockfish
  • Desarrolle una GUI de Ren'Py para la promoción de peones
  • Desarrolle una interfaz gráfica de usuario de Ren'Py para reclamar un empate en el caso de una repetición triple o la regla de los cincuenta movimientos

Desarrollar un prototipo de prueba de concepto

Un prototipo de prueba de concepto (POC) me ayuda a medir el tiempo y el esfuerzo necesarios para implementar las funciones necesarias.

Para mi motor de ajedrez POC, integré python-chess con mi código GUI original de Ren'Py. Me aseguré de que su conjunto de características fuera mínimo pero fácilmente extensible:

  • Integré python-chess con mi código GUI original de Ren'Py y pude mover piezas
  • Solo implementé Jugador contra Jugador para posponer la integración de Stockfish para la IA de ajedrez
  • Solo permití movimientos de no promoción para posponer el desarrollo de la GUI para la promoción de peones

Identificar la definición de listo y la definición de terminado del proyecto

La Definición de Listo (DoR) de mi proyecto se deriva naturalmente de mi investigación inicial sobre la compatibilidad de la versión de la biblioteca y mi POC.

Paralelamente, la Definición de Hecho (DoD) de mi proyecto se deriva de los requisitos de características que identifiqué en mi fase de diseño.

Entregue un producto mínimo viable, o mejor aún, un producto mínimo adorable

Cuando estaba en la fase de diseño reuniendo requisitos, sabía que había muchos objetivos ambiciosos en mi proyecto, quizás incluso más de los que podría lograr.

Así que era importante para mí implementar el conjunto básico de características requeridas, entregar un Producto Mínimo Viable (MVP) y recopilar comentarios para iterar sobre él.

Mejor aún, me gustaría ofrecer un producto adorable mínimo (MLP) en mi primera iteración. La pequeña diferencia es que mientras que un MVP no requiere más que características funcionales, un MLP tiene una experiencia de usuario adorable por diseño.

Por ejemplo, para implementar movimientos de promoción de peones, para un MVP podría pedirles a los usuarios que presionen diferentes teclas para seleccionar el tipo de pieza al que quieren promocionar (como B para alfil y K para caballo).

Para un MLP, implementaría una interfaz de usuario con botones en forma de pieza que cambian de color cuando se desplaza o se selecciona.

Sea su propio administrador de proyectos

Si le parece abrumador realizar un seguimiento de la lista de funciones (más la lista cada vez mayor de errores y correcciones), no está solo. Es hora de ser su propio director de proyectos.

Encontré que Trello es una herramienta increíble tanto para proyectos de una sola persona como para proyectos de equipos grandes.

Así es como suelo organizar mi tablero de Trello para un proyecto de codificación:

Tenga cuatro listas: Backlog (para clasificar las funciones), TODO , Doing y Done.

Tener etiquetas codificadas por colores:

  • Listo para el control de calidad: una etiqueta roja para llamar la atención de mis compañeros de equipo
  • Impacto: bajo (amarillo) frente a alto (naranja), determinado por la cantidad de impacto que generará una función o una corrección de errores. Por ejemplo, un panel de IU ligeramente desalineado es de bajo impacto cuando un error que se bloquea de forma determinista tiene un gran impacto.
  • Una estimación del tiempo que llevará implementar: trivial (<1 hora, verde azulado), medio (1 a 2 horas, azul claro) y difícil (2 a 4 horas, azul oscuro).

    Mi otra regla general es que, si estimo que una tarjeta tardará más de 4 horas en implementarse, probablemente debería dividirla en varias tarjetas más detalladas.

  • El color sirve como una gran pista visual: siempre abordo las tarjetas con etiquetas naranjas y verde azulado (alto impacto y poco compromiso de tiempo) antes de abordar aquellas con etiquetas amarillas y difíciles (bajo impacto pero alto compromiso de tiempo).

Escriba documentación y reflexione sobre su aprendizaje

Habiendo empujado cada tarjeta de Trello de TODO a Doing to Done y arreglado todos los errores desagradables, ¿finalmente es hora de llamar a un proyecto terminado? Si y no.

Para maximizar mi aprendizaje de un proyecto, me parece inmensamente valioso reflexionar sobre mis conclusiones, habilidades técnicas o blandas:

  1. Escriba un archivo README claro y conciso en el repositorio del proyecto de GitHub. Esto ayuda a otros desarrolladores a comprender e interesarse en el proyecto.
  2. Escriba una publicación de blog (como la que estoy escribiendo ahora) sobre los aspectos de nivel superior, por ejemplo, descripción general de la arquitectura, diseño de funciones, desafíos y soluciones, etc.

Créditos y enlaces

Muchas gracias a Tim Min por impulsarme a trabajar en este proyecto, por sus contribuciones (ideas de nuevas funciones + control de calidad) en el tablero de Trello y por hacerme responsable. Tim es el escritor del juego de novela cinética, The Wind at Dawn .

  • Mi motor de ajedrez repositorio de GitHub
  • El tablero público de Trello para este proyecto de motor de ajedrez
  • Ren'Py: un motor de desarrollo de juegos de novela visual
  • python-chess: una biblioteca de ajedrez de Python pura

¡Mantengamonos en contacto! Conéctese conmigo en LinkedIn, GitHub, Medium o visite mi sitio web personal.