Conecta 4 en C++ - Jugar partida contra CPU (inteligencia artificial)

Conecta 4 en C++ con IA, ranking y estadísticas de jugadores

En este post te mostraré el juego de Conecta 4 en C++ con opción para jugar contra el CPU con un algoritmo y una pequeña inteligencia artificial.

Además del juego de Conecta 4 en CPP llevaremos la gestión de usuarios con estadísticas, un ranking de mejores jugadores, opción para cambiar el tamaño del tablero y una manera de repetir la última partida.

Por cierto, he mejorado un poco el algoritmo del CPU, de modo que es más complejo ganarle una partida de Conecta 4. Pero bueno, vayamos a la explicación y el código fuente.

Descripción del problema

Se trata del conocido juego ‘Conecta 4’. Las partidas se jugarán sobre un tablero de a lo sumo 10×10 casillas, en el que tendremos que ir situando piezas alternativamente con el ordenador hasta conectar cuatro de ellas en horizontal, en vertical o en diagonal.

Ganará quien primer consiga el objetivo (ordenador o jugador), y se considerará un empate cuando se llene el tablero sin haberlo conseguido ninguno de los dos.

El funcionamiento del juego se apoyará en un fichero ranking.txt para almacenar las puntuaciones de los 10 mejores jugadores, y en tres ficheros para cada jugador, cuyo nombre será el nick del jugador, una barra baja y las siguientes terminaciones:

  • configuracion.txt, que almacenará el tamaño del tablero incluyendo el número de casillas (filas y columnas del tablero inicialmente 10 x 10).
  • resultados.txt, que contendrá los resultados conseguidos en las partidas.
  • ultimapartida.dat, que almacenará los datos necesarios para reproducir la última partida jugada.

Diseño del juego: menú

Menú para jugar Conecta 4 en C++
Menú para jugar Conecta 4 en C++

El juego comenzará solicitando al usuario su nick

Dame tu nick para comenzar el juego:

A continuación, mostrará por pantalla el siguiente menú:

  1. Visualizar configuración del tablero.
  2. Cambiar configuración del tablero.
  3. Ver estadísticas.
  4. Reproducir última partida.
  5. Mostrar top 10.
  6. Jugar partida.
  7. Salir

Dame opción:

Opciones del menú

La opción 1 (visualizar configuración) mostrará la información referente al tamaño del tablero, leyendo para ello el fichero correspondiente al jugador, de extensión txt y cuyo nombre será nombre la concatenación de su nick con la cadena “_configuración” con su nick.

Por ejemplo, para el nick Maria, el fichero será Maria_configuracion.txt

La opción 2 (cambiar configuración) permitirá modificar el contenido del fichero de configuración correspondiente al jugador, teniendo en cuenta el tamaño máximo del tablero y cambiando su tamaño para las partidas que se jueguen a partir de ese momento.

La opción 3 (ver estadísticas), se apoyará en la información contenida en el fichero de resultados asociado al nick del jugador, y mostrará el porcentaje de partidas ganadas, perdidas y empatadas; y el número promedio de movimientos del jugador por partida.

La opción 4 reproducirá los movimientos sobre el tablero de la última partida, de acuerdo a la información almacenada en el fichero de última partida asociado al jugador, que será de tipo binario.

Los movimientos se reproducirán uno a uno, pidiendo al usuario que pulse una tecla tras cada movimiento.

La opción 5 mostrará el ranking de los 10 mejores jugadores. A este fin, se calculará la puntuación de cada jugador como (número de partidas ganadas – números de partidas perdidas) / partidas totales.

En caso de empate entre jugadores, se considerará mejor jugador el que tenga el menor número de movimientos por partida.

Ejemplo de partida

La opción 6 iniciará el juego. A este fin, el ordenador mostrará un tablero como el que se muestra debajo (para un caso de ejemplo compuesto de 6 filas y 10 columnas), y solicitará al usuario el número de columna en el que quiere depositar su ficha.

La opción 7, obviamente, sale del juego.

El ordenador introducirá la ficha del jugador en la columna indicada (una X mayúscula) y a continuación introducirá la suya propia (una O mayúscula), diseñando para ello un algoritmo apropiado.

El diseño de este algoritmo influirá en la nota del proyecto (1 punto).

A continuación, se muestra un ejemplo de un posible resultado tras pedir depositar la ficha en la columna 3:

El programa deberá continuar solicitando al usuario su tirada hasta que el ordenador o el usuario consigan ganar la partida (o el tablero se llene).

En ese momento, se actualizará el fichero terminado en _resultados.txt con la nueva información, para permitir visualizar las estadísticas en la opción 3 en el futuro; y también el fichero terminado en _ultimapartida.dat, para permitir utilizar posteriormente la opción 4 si el usuario desea revisar sus movimientos.

Finalmente, se regresará al menú principal.

Declaración de constantes y encabezados

Comencemos con el código. En este caso primero veamos algunas constantes necesarias.

Por ejemplo, tenemos las fichas necesarias para ganar el juego, los caracteres que identifican al jugador, delimitadores, máximas columnas y filas, nombres de archivos, etcétera.

Nota: si quisieras jugar a Conecta 5, Conecta 10 o cualquier otra variante solo debes cambiar la constante de FICHAS_JUNTAS_NECESARIAS_PARA_GANAR.

Estructuras necesarias

Necesitamos declarar algunos struct para este juego de Connect 4 en C++, por ejemplo la configuración del tablero o las estadísticas de un jugador.

Esto es más que nada para facilitar las cosas y abstraer mejor cada concepto, aprovechando las características del lenguaje.

Configuración del tablero de juego

Guardar y mostrar configuración del tablero
Guardar y mostrar configuración del tablero

Veamos los ajustes del tablero de juego. Como se dijo anteriormente, se debe permitir ver y cambiar el tamaño del tablero, guardando los ajustes en un archivo.

Así que veamos las siguientes funciones ayudantes:

Lo que estamos haciendo es leer y escribir un struct como lo vimos en mi otro post. En cuanto a las funciones que solicitan las nuevas filas y columnas y modifican la configuración las veremos más adelante.

Estadísticas del jugador

Estadísticas de jugador - Partidas de Conecta 4 ganadas, perdidas y empatadas
Estadísticas de jugador – Partidas de Conecta 4 ganadas, perdidas y empatadas

Tal y como lo solicita el ejercicio debemos guardar las estadísticas del jugador con sus movimientos y el resultado del juego.

En este caso lo que debemos hacer es agregar contenido al fichero, y no sobrescribirlo. Aquí tenemos las funciones que nos ayudan:

Aquí te estoy mostrando la función que guarda la partida terminada junto con su modo de uso. Y ya para ver las estadísticas del jugador simplemente leemos de ese archivo:

Si te fijas, estamos calculando los porcentajes en la función, ya que en el archivo solo guardamos la cantidad de partidas ganadas, perdidas, empatadas y movimientos.

Reproducir última partida

Reproducir última partida - Programación de juego Conecta 4 en C++
Reproducir última partida – Programación de juego Conecta 4 en C++

Otra opción que el juego solicita es la de reproducir la última partida. Para ello decidí crear un vector de structs con movimientos, indicando el jugador y la columna que elige.

Obviamente solo te estoy mostrando los fragmentos importantes en donde tenemos el vector y vamos agregando los movimientos.

Ya después de terminar la partida se invoca a la función que guarda los movimientos de la partida de Conecta 4 usando C++.

Nota: si el tamaño del tablero al momento de reproducir la última partida es distinto al que se usó al momento de guardarla, puede haber problemas. Yo no lo validé porque el ejercicio no lo requería.

En el caso de obtener los movimientos y reproducir la última partida tenemos esto:

Simplemente leemos el archivo y simulamos el juego. Como diseñé todas las funciones de manera que reciban el jugador y la columna pude reutilizarlas y hacer como si fuera un juego normal.

Ranking de jugadores

Ranking de jugadores de Conecta 4 en CPP
Ranking de jugadores de Conecta 4 en CPP

Esto fue un poco complejo de hacer y pensar, pues nunca lo había hecho como lo pide el ejercicio. Aquí, después de cada partida, debemos calcular el ranking y guardarlo en un archivo de texto.

Entonces el algoritmo es: leer el ranking del archivo, agregar el jugador si no existe (si ya existe, lo actualizas), luego ordenar el vector tomando en cuenta las 2 propiedades y finalmente guardar solo las primeras 10 posiciones.

El ordenamiento tomando en cuenta los dos parámetros (si la puntuación es igual, se toma en cuenta la cantidad de movimientos) está en la función de la línea 56.

Estoy usando el algoritmo de ordenamiento por selección que ya publiqué anteriormente en C.

Jugar

Conecta 4 en C++ - Jugar partida contra CPU (inteligencia artificial)
Conecta 4 en C++ – Jugar partida contra CPU (inteligencia artificial)

Ahora viene la más importante: jugar a Conecta 4 programado en C++ contra la CPU. No voy a tardarme exponiendo todas las funciones aquí, ya que he explicado esto anteriormente en varios lenguajes.

El algoritmo es simple: iniciamos el tablero con espacios vacíos, luego solicitamos la columna ya sea al CPU o al jugador y dejamos caer la pieza, calculando la primera fila vacía.

Después de que un jugador ha colocado su pieza comprobamos si hay algún ganador o si hay empate, y en ese caso se termina el juego.

Me parece que el código se explica por sí mismo. Y para el algoritmo de la CPU inteligente para que pueda ganar Conecta 4 el código es el siguiente:

Dicho algoritmo ya lo he explicado antes en Algoritmo para ganar Conecta 4.

Por cierto, esta misma función puede ser invocada para el jugador humano, y así tendríamos al CPU enfrentándose contra sí mismo (en donde siempre ganará el jugador que tiene el primer turno).

Poniendo todo junto

Ya te expliqué el código más relevante, aunque falta mostrarte el código completo; mismo que te dejaré en mi GitHub. Todo está en el archivo main.cpp.

Para compilarlo te recomiendo usar el compilador g++ de MinGW, aunque también es compatible con el viejo compilador incluido en DevC++.

Recuerda que ya he hecho este juego en C, C#, Python y JavaScript.

Para terminar te dejo con más tutoriales de C++.

Encantado de ayudarte


Estoy disponible para trabajar en tu proyecto, modificar el programa del post o realizar tu tarea pendiente, no dudes en ponerte en contacto conmigo.

No te pierdas ninguno de mis posts

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.

Dejar un comentario