En este post de programación en C# también conocido como C sharp te enseñaré el juego de Conecta 4. He programado este juego para que se pueda jugar en la consola, pero obviamente puedes adaptarlo a una interfaz gráfica.
Jugando conecta 4 en C sharp (c#)
El código escrito en C# simula completamente el juego, y permite jugar en modo humano contra humano, humano contra CPU (con una pequeña IA) y también en modo CPU contra CPU.
A lo largo del post te enseñaré los detalles de este juego, mismo que se basa en mi otro programa ya escrito en lenguaje ANSI C.
Funcionamiento general
Todo el juego de Conecta 4 en c# se desarrolla en una matriz, también conocida como arreglo bidimensional o array de dos dimensiones. Ahí es en donde se dejan caer las piezas.
En cada turno, ya sea del CPU o del Humano, se debe elegir una columna en donde se va a colocar la pieza. Se dice que un jugador gana cuando se pueden conectar 4 piezas en cualquier dirección.
Por cierto, este juego está programado de tal manera que el tablero de juego es libre de tener cualquier cantidad de filas y columnas, además de que se puede cambiar el número de piezas que se deben conectar para ganar el juego.
De este modo podríamos jugar a Conecta 5, Conecta 6, etcétera.
Por cierto, para hacer que el CPU piense y elija una columna ganadora se ha usado este algoritmo.
Funciones ayudantes
Vamos a necesitar ciertas funciones. En primer caso una que nos permita clonar una matriz, pues dentro del juego vamos a simular colocar piezas sobre todo cuando sea el turno del CPU.
La otra función que necesitamos es una que nos dé números aleatorios, ya que necesitamos saber cuál jugador inicia el juego, entre otras cosas.
Necesitamos varias operaciones que hacer con el tablero. Por ejemplo, debemos limpiarlo, imprimirlo (mostrando las piezas), validar que las columnas sean correctas, etcétera. Para empezar, el tablero es el siguiente:
string[,] tablero =newstring[FILAS, COLUMNAS];
Este arreglo bidimensional es en donde se lleva a cabo todo el juego. Hay varias funciones que usan, pero la principal es la siguiente:
Esta función coloca la pieza del jugador en la columna especificada dentro del tablero. También verifica si la columna está llena y si la misma es válida.
Contando conexiones
Dentro del juego necesitamos saber si determinado jugador ha ganado, es decir, que ha conectado más de 4 piezas en cualquier dirección. Las funciones que hacen el conteo son las siguientes:
Simplemente verifican si se hace una línea recta y devuelven el contador.
Ganador y empate
Veamos ahora las funciones que dicen si el usuario es ganador o si se ha dado un empate.
Para determinar si es empate en este juego de conecta 4 en C# simplemente contamos las piezas que formen una línea y si son 4 (o las especificadas para ganar) indicamos el jugador ganador.
En el caso del empate, verificamos si ya no quedan espacios vacíos en el tablero.
staticintganador(string jugador,string[,] tablero){/*
* Solo necesitamos
* Arriba
* Derecha
* Arriba derecha
* Abajo derecha
*
* */int y;for(y =0; y < FILAS; y++){int x;for(x =0; x < COLUMNAS; x++){int conteoArriba =contarArriba(x, y, jugador, tablero);if(conteoArriba >= CONECTA){return CONECTA_ARRIBA;}if(contarDerecha(x, y, jugador, tablero)>= CONECTA){return CONECTA_DERECHA;}if(contarArribaDerecha(x, y, jugador, tablero)>= CONECTA){return CONECTA_ARRIBA_DERECHA;}if(contarAbajoDerecha(x, y, jugador, tablero)>= CONECTA){return CONECTA_ABAJO_DERECHA;}}}return NO_CONECTA;}
Inteligencia artificial de Conecta 4 en C sharp
Pasemos a la inteligencia artificial del CPU para que el mismo pueda jugar contra el ser humano. Simplemente se hacen simulaciones del tablero y se elige la mejor columna, siguiendo el algoritmo que mencioné anteriormente.
staticintobtenerColumnaGanadora(string jugador,string[,] tableroOriginal){string[,] tablero =newstring[FILAS, COLUMNAS];int i;for(i =0; i < COLUMNAS; i++){
tablero =clonarMatriz(tableroOriginal);int resultado =colocarPieza(jugador, i, tablero);if(resultado == ERROR_NINGUNO){int gana =ganador(jugador, tablero);if(gana != NO_CONECTA){return i;}}}return COLUMNA_GANADORA_NO_ENCONTRADA;}staticintobtenerPrimeraFilaLlena(int columna,string[,] tablero){int i;for(i =0; i < FILAS;++i){if(tablero[i, columna]!= ESPACIO_VACIO){return i;}}return FILA_NO_ENCONTRADA;}static(int,int)obtenerColumnaEnLaQueSeObtieneMayorPuntaje(string jugador,string[,] tableroOriginal){int conteoMayor =0, indiceColumnaConConteoMayor =-1;string[,] tablero =newstring[FILAS, COLUMNAS];int i;for(i =0; i < COLUMNAS;++i){
tablero =clonarMatriz(tableroOriginal);int estado =colocarPieza(jugador, i, tablero);if(estado == ERROR_NINGUNO){int filaDePiezaRecienColocada =obtenerPrimeraFilaLlena(i, tablero);if(filaDePiezaRecienColocada != FILA_NO_ENCONTRADA){int c =contarArriba(i, filaDePiezaRecienColocada, jugador, tablero);if(c > conteoMayor){
conteoMayor = c;
indiceColumnaConConteoMayor = i;}
c =contarArribaDerecha(i, filaDePiezaRecienColocada, jugador, tablero);if(c > conteoMayor){
conteoMayor = c;
indiceColumnaConConteoMayor = i;}
c =contarDerecha(i, filaDePiezaRecienColocada, jugador, tablero);if(c > conteoMayor){
conteoMayor = c;
indiceColumnaConConteoMayor = i;}
c =contarAbajoDerecha(i, filaDePiezaRecienColocada, jugador, tablero);if(c > conteoMayor){
conteoMayor = c;
indiceColumnaConConteoMayor = i;}}}}return(conteoMayor, indiceColumnaConConteoMayor);}staticintobtenerColumnaAleatoria(string jugador,string[,] tableroOriginal){while(true){string[,] tablero =newstring[FILAS, COLUMNAS];
tablero =clonarMatriz(tableroOriginal);int columna =aleatorio_en_rango(0, COLUMNAS -1);int resultado =colocarPieza(jugador, columna, tablero);if(resultado == ERROR_NINGUNO){return columna;}}}staticintobtenerColumnaCentral(string jugador,string[,] tableroOriginal){string[,] tablero =newstring[FILAS, COLUMNAS];
tablero =clonarMatriz(tableroOriginal);int mitad =(COLUMNAS -1)/2;int resultado =colocarPieza(jugador, mitad, tablero);if(resultado == ERROR_NINGUNO){return mitad;}return COLUMNA_GANADORA_NO_ENCONTRADA;}staticintelegirColumnaCpu(string jugador,string[,] tablero){// Voy a comprobar si puedo ganar...int posibleColumnaGanadora =obtenerColumnaGanadora(jugador, tablero);if(posibleColumnaGanadora != COLUMNA_GANADORA_NO_ENCONTRADA){
System.Console.Write("*elijo ganar*\n");return posibleColumnaGanadora;}// Si no, voy a comprobar si mi oponente gana con el siguiente movimiento, para evitarlostring oponente =obtenerOponente(jugador);int posibleColumnaGanadoraDeOponente =obtenerColumnaGanadora(oponente, tablero);if(posibleColumnaGanadoraDeOponente != COLUMNA_GANADORA_NO_ENCONTRADA){
System.Console.Write("*elijo evitar que mi oponente gane*\n");return posibleColumnaGanadoraDeOponente;}// En caso de que nadie pueda ganar en el siguiente movimiento, buscaré en dónde se obtiene el mayor// puntaje al colocar la piezavar(conteoCpu, columnaCpu)=obtenerColumnaEnLaQueSeObtieneMayorPuntaje(jugador, tablero);var(conteoOponente, columnaOponente)=obtenerColumnaEnLaQueSeObtieneMayorPuntaje(oponente, tablero);if(conteoOponente > conteoCpu){
System.Console.Write("*elijo quitarle el puntaje a mi oponente*\n");return columnaOponente;}elseif(conteoCpu >1){
System.Console.Write("*elijo colocarla en donde obtengo un mayor puntaje*\n");return columnaCpu;}// Si no, regresar la central por si está desocupadaint columnaCentral =obtenerColumnaCentral(jugador, tablero);if(columnaCentral != COLUMNA_GANADORA_NO_ENCONTRADA){
System.Console.Write("*elijo ponerla en el centro*\n");return columnaCentral;}// Finalmente, devolver la primera disponible de manera aleatoriaint columna =obtenerColumnaAleatoria(jugador, tablero);if(columna != FILA_NO_ENCONTRADA){
System.Console.Write("*elijo la primera vacía aleatoria*\n");return columna;}
System.Console.Write("Esto no debería suceder\n");return0;}
Puedes leer los comentarios de la función para entender cómo se hace la elección de la columna. En este caso la CPU elige la mejor columna, eligiendo entre ganar o evitar que el oponente gane.
Jugando Conecta 4
Finalmente veamos cómo se desarrolla el juego. Este programa soporta 3 modos, mismos que son:
Básicamente es un if muy simple que coloca la columna en el tablero. Lo que cambia es la solicitud de la columna dependiendo del modo, ya que el programa le dice al CPU que piense en una columna o se la pregunta al usuario.
Como puedes ver es un ciclo infinito que se rompe cuando hay un empate o hay un ganador.
Probando el juego
Puedes compilar el juego con cualquier herramienta. Yo uso el compilador del proyecto Mono, pero puedes usar Visual Studio y todas esas cosas que no me agradan de Microsoft (imagina tener que descargar un IDE solo para ejecutar un simple archivo .cs jajaja)
En fin, una vez que tengas el .exe puedes pasarle los valores de un archivo de texto para probar el juego. He incluido varios dentro del repositorio, hay uno para causar un empate, otro para ganar en diagonal, etcétera.
Por ejemplo, si yo quiero causar un empate hago esto:
Conecta4.exe < empate.txt
Obviamente hay que cambiar el nombre del ejecutable.
Poniendo todo junto
No puedo poner y colocar todo el código aquí, pues me llevaría bastante tiempo. Te dejaré el código completo junto con todas las constantes (para que puedas cambiar el tamaño de tablero de juego de Conecta 4 en C# o las piezas a conectar) en GitHub.
Jugando conecta 4 en C sharp (c#)
Como te dije anteriormente, se puede hacer en interfaz gráfica. De hecho yo lo hice en JavaScript con GUI usando el mismo algoritmo que en ANSI C, así que lo puedes portar a cualquier lenguaje.
Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto
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.
En este post de programación en C te mostraré el código fuente para el juego conocido como tres en línea, tres en raya, tic tac toe, gatitos, etcétera. He programado el juego en C estándar así que se puede compilar en varios sistemas operativos, y también se puede compilar con…
En este post te mostraré el algoritmo a seguir para programar una pequeña IA que puede jugar Conecta 4 contra un contrincante (un ser humano), balanceando la defensa y ataque. De este modo se sentirá que se está jugando contra un contrincante real, aunque la dificultad no será elevada y…
En este post te mostraré el juego Conecta 4 programado en C por consola. Se trata del juego que lleva el mismo nombre en donde se deben conectar cuatro fichas del mismo color de manera que formen una línea, ya sea horizontal, vertical o diagonal. Las características del mismo son:…