En este proyecto vamos a crear un juego de Truco argentino en PSeInt para un jugador contra la computadora. Además de ser un juego divertido, es un ejercicio excelente para practicar Funciones, SubProcesos, vectores, números aleatorios, condicionales, ciclos y manejo de estados.
La idea es que el programa sea entendible incluso para alguien que nunca jugó al Truco. Por eso primero veremos las reglas que vamos a implementar y recién después construiremos el juego.
¿Qué versión del Truco vamos a programar?
El Truco argentino tiene muchas variantes. Para que el proyecto sea completo pero manejable, implementaremos:
- 1 jugador contra la computadora;
- mazo español de 40 cartas;
- 3 cartas para cada jugador;
- partida a 15 puntos;
- Envido;
- Truco;
- Retruco;
- Vale Cuatro;
- reglas de parda;
- alternancia de quién es mano;
- mezcla aleatoria del mazo antes de cada mano.
Para esta primera versión dejaremos afuera Flor, Real Envido, Falta Envido y partidas de 2 contra 2. Son excelentes mejoras para agregar después.
Reglas básicas del Truco
El objetivo
El objetivo es ser el primero en llegar a 15 puntos. Cada mano permite ganar puntos mediante el Envido y mediante el Truco.
El mazo
Se utiliza un mazo español de 40 cartas. Los palos son:
- Espada;
- Basto;
- Oro;
- Copa.
En cada palo existen las cartas 1, 2, 3, 4, 5, 6, 7, 10, 11 y 12. No se utilizan 8 ni 9.
Reparto
Al comienzo de cada mano se mezclan las 40 cartas y se reparten 3 cartas a cada jugador. Una carta nunca puede repetirse porque primero mezclamos el mazo completo y luego tomamos las seis primeras posiciones.
Jerarquía de las cartas en el Truco
Una de las particularidades del Truco es que el valor numérico de una carta no determina directamente su fuerza. La jerarquía, de mayor a menor, es:
- 1 de Espada;
- 1 de Basto;
- 7 de Espada;
- 7 de Oro;
- todos los 3;
- todos los 2;
- 1 de Oro y 1 de Copa;
- todos los 12;
- todos los 11;
- todos los 10;
- 7 de Copa y 7 de Basto;
- todos los 6;
- todos los 5;
- todos los 4.
Para simplificar las comparaciones, nuestra función ValorTruco() transforma cada carta en un valor interno. Cuanto mayor sea ese valor, más fuerte será la carta.
¿Cómo se gana una mano?
Cada mano puede tener hasta tres vueltas. En cada vuelta ambos jugadores tiran una carta.
Normalmente gana la mano quien gana dos vueltas. Sin embargo, existen empates llamados pardas:
- si la primera vuelta empata, quien gane la segunda gana la mano;
- si alguien gana la primera y la segunda empata, gana quien había ganado la primera;
- si cada jugador gana una de las dos primeras, la tercera decide;
- si la tercera empata después de que cada uno ganó una vuelta, gana quien ganó la primera;
- si todas las vueltas empatan, gana quien era mano.
Ser mano significa jugar primero al comienzo de esa mano. En nuestro programa esta condición alternará después de cada mano.
El Envido
El Envido compara combinaciones de cartas del mismo palo. Para calcularlo:
- si tenemos dos cartas del mismo palo, sumamos sus valores y agregamos 20;
- las figuras 10, 11 y 12 valen 0 para el Envido;
- si no tenemos dos cartas del mismo palo, vale la carta numérica más alta entre 1 y 7;
- si hay empate, gana quien es mano.
Ejemplos:
6 de Oro + 7 de Oro = 33 de Envido 1 de Copa + 12 de Copa = 21 de Envido 7 de Espada + 4 de Oro + 12 de Basto = 7 de Envido
En esta versión usamos solamente Envido: si es aceptado vale 2 puntos; si el rival no quiere, quien lo cantó recibe 1 punto.
Truco, Retruco y Vale Cuatro
La mano comienza valiendo 1 punto. Durante el juego puede aumentarse su valor:
- Truco: la mano pasa a valer 2 puntos;
- Retruco: pasa a valer 3 puntos;
- Vale Cuatro: pasa a valer 4 puntos.
El rival puede aceptar o rechazar. Si rechaza, quien realizó el último canto gana el valor que tenía la mano antes de aumentar. Por ejemplo, rechazar un Truco entrega 1 punto; rechazar un Retruco entrega 2; rechazar un Vale Cuatro entrega 3.
Después de que un canto es aceptado, solamente el rival de quien realizó ese canto puede subir nuevamente la apuesta.
Representar las cartas con números
Internamente representaremos cada carta con un número del 1 al 40. Diez posiciones pertenecen a cada palo. Luego usaremos funciones para transformar ese número interno en el número y palo que ve el jugador.
Esto permite trabajar con un único vector:
Dimension mazo[40]; Para i <- 1 Hasta 40 Hacer mazo[i] <- i; FinPara
Mezclar el mazo con Fisher-Yates
No conviene generar seis números aleatorios independientes porque podríamos obtener una carta repetida. En cambio, creamos las 40 cartas y mezclamos sus posiciones.
Usaremos una variante del algoritmo Fisher-Yates. En cada paso intercambiaremos una carta con una posición aleatoria de la parte del vector que todavía no fue procesada.
SubProceso MezclarMazo(mazo Por Referencia) Definir i, posicionAleatoria, auxiliar Como Entero; Para i <- 40 Hasta 2 Con Paso -1 Hacer posicionAleatoria <- Aleatorio(1,i); auxiliar <- mazo[i]; mazo[i] <- mazo[posicionAleatoria]; mazo[posicionAleatoria] <- auxiliar; FinPara FinSubProceso
Después de mezclar, las cartas mazo[1] a mazo[3] pueden ir al jugador y mazo[4] a mazo[6] a la computadora.
Código completo del juego
Funcion numero <- NumeroCarta(carta) Definir posicion Como Entero; posicion <- carta - Trunc((carta - 1) / 10) * 10; Si posicion <= 7 Entonces numero <- posicion; SiNo numero <- posicion + 2; FinSi FinFuncion Funcion palo <- PaloCarta(carta) Definir codigo Como Entero; Definir palo Como Cadena; codigo <- Trunc((carta - 1) / 10) + 1; Segun codigo Hacer 1: palo <- "Espada"; 2: palo <- "Basto"; 3: palo <- "Oro"; 4: palo <- "Copa"; FinSegun FinFuncion Funcion valor <- ValorTruco(carta) Definir numero Como Entero; Definir palo Como Cadena; numero <- NumeroCarta(carta); palo <- PaloCarta(carta); Si numero = 1 Y palo = "Espada" Entonces valor <- 14; SiNo Si numero = 1 Y palo = "Basto" Entonces valor <- 13; SiNo Si numero = 7 Y palo = "Espada" Entonces valor <- 12; SiNo Si numero = 7 Y palo = "Oro" Entonces valor <- 11; SiNo Segun numero Hacer 3: valor <- 10; 2: valor <- 9; 1: valor <- 8; 12: valor <- 7; 11: valor <- 6; 10: valor <- 5; 7: valor <- 4; 6: valor <- 3; 5: valor <- 2; 4: valor <- 1; FinSegun FinSi FinSi FinSi FinSi FinFuncion Funcion valor <- ValorEnvidoCarta(carta) Definir numero Como Entero; numero <- NumeroCarta(carta); Si numero >= 10 Entonces valor <- 0; SiNo valor <- numero; FinSi FinFuncion Funcion envido <- CalcularEnvido(mano) Definir v1, v2, v3, candidato Como Entero; Definir p1, p2, p3 Como Cadena; v1 <- ValorEnvidoCarta(mano[1]); v2 <- ValorEnvidoCarta(mano[2]); v3 <- ValorEnvidoCarta(mano[3]); p1 <- PaloCarta(mano[1]); p2 <- PaloCarta(mano[2]); p3 <- PaloCarta(mano[3]); envido <- v1; Si v2 > envido Entonces envido <- v2; FinSi Si v3 > envido Entonces envido <- v3; FinSi Si p1 = p2 Entonces candidato <- 20 + v1 + v2; Si candidato > envido Entonces envido <- candidato; FinSi FinSi Si p1 = p3 Entonces candidato <- 20 + v1 + v3; Si candidato > envido Entonces envido <- candidato; FinSi FinSi Si p2 = p3 Entonces candidato <- 20 + v2 + v3; Si candidato > envido Entonces envido <- candidato; FinSi FinSi FinFuncion Funcion ganador <- CompararCartas(cartaJugador, cartaCPU) Definir valorJugador, valorCPU Como Entero; valorJugador <- ValorTruco(cartaJugador); valorCPU <- ValorTruco(cartaCPU); Si valorJugador > valorCPU Entonces ganador <- 1; SiNo Si valorCPU > valorJugador Entonces ganador <- 2; SiNo ganador <- 0; FinSi FinSi FinFuncion Funcion nombre <- NombreCanto(nuevoValor) Definir nombre Como Cadena; Segun nuevoValor Hacer 2: nombre <- "TRUCO"; 3: nombre <- "RETRUCO"; 4: nombre <- "VALE CUATRO"; FinSegun FinFuncion SubProceso CrearMazo(mazo Por Referencia) Definir i Como Entero; Para i <- 1 Hasta 40 Hacer mazo[i] <- i; FinPara FinSubProceso SubProceso MezclarMazo(mazo Por Referencia) Definir i, posicionAleatoria, auxiliar Como Entero; Para i <- 40 Hasta 2 Con Paso -1 Hacer posicionAleatoria <- Aleatorio(1,i); auxiliar <- mazo[i]; mazo[i] <- mazo[posicionAleatoria]; mazo[posicionAleatoria] <- auxiliar; FinPara FinSubProceso SubProceso Repartir(mazo, manoJugador Por Referencia, manoCPU Por Referencia) manoJugador[1] <- mazo[1]; manoJugador[2] <- mazo[2]; manoJugador[3] <- mazo[3]; manoCPU[1] <- mazo[4]; manoCPU[2] <- mazo[5]; manoCPU[3] <- mazo[6]; FinSubProceso SubProceso MostrarCarta(carta) Escribir Sin Saltar NumeroCarta(carta), " de ", PaloCarta(carta); FinSubProceso SubProceso MostrarMano(manoJugador, usadaJugador) Definir i Como Entero; Escribir ""; Escribir "Tus cartas:"; Para i <- 1 Hasta 3 Hacer Si NO usadaJugador[i] Entonces Escribir Sin Saltar i, ". "; MostrarCarta(manoJugador[i]); Escribir ""; FinSi FinPara FinSubProceso Funcion posicion <- ElegirCartaJugador(manoJugador, usadaJugador) Repetir MostrarMano(manoJugador, usadaJugador); Escribir "Elegí la posición de la carta que querés jugar:"; Leer posicion; Hasta Que posicion >= 1 Y posicion <= 3 Y NO usadaJugador[posicion] FinFuncion Funcion posicion <- ElegirCartaCPU(usadaCPU) Repetir posicion <- Aleatorio(1,3); Hasta Que NO usadaCPU[posicion] FinFuncion Funcion aceptar <- CPUAceptaTruco(manoCPU) Definir i, mejorCarta, probabilidad Como Entero; mejorCarta <- 0; Para i <- 1 Hasta 3 Hacer Si ValorTruco(manoCPU[i]) > mejorCarta Entonces mejorCarta <- ValorTruco(manoCPU[i]); FinSi FinPara probabilidad <- Aleatorio(1,100); Si mejorCarta >= 11 Entonces aceptar <- probabilidad <= 85; SiNo Si mejorCarta >= 8 Entonces aceptar <- probabilidad <= 65; SiNo aceptar <- probabilidad <= 40; FinSi FinSi FinFuncion SubProceso GestionarEnvido(manoJugador, manoCPU, mano, puntosJugador Por Referencia, puntosCPU Por Referencia) Definir opcion, envidoJugador, envidoCPU, probabilidad Como Entero; Definir acepta, cantado Como Logico; cantado <- Falso; envidoJugador <- CalcularEnvido(manoJugador); envidoCPU <- CalcularEnvido(manoCPU); Escribir ""; Escribir "¿Querés cantar ENVIDO?"; Escribir "1. Sí"; Escribir "2. No"; Leer opcion; Si opcion = 1 Entonces cantado <- Verdadero; probabilidad <- Aleatorio(1,100); Si envidoCPU >= 27 Entonces acepta <- Verdadero; SiNo acepta <- probabilidad <= 55; FinSi Si acepta Entonces Escribir "La computadora dice: ¡QUIERO!"; SiNo Escribir "La computadora dice: NO QUIERO."; puntosJugador <- puntosJugador + 1; FinSi SiNo Si envidoCPU >= 27 O Aleatorio(1,100) <= 25 Entonces cantado <- Verdadero; Escribir "La computadora canta: ¡ENVIDO!"; Escribir "1. Quiero"; Escribir "2. No quiero"; Leer opcion; Si opcion = 1 Entonces acepta <- Verdadero; SiNo acepta <- Falso; puntosCPU <- puntosCPU + 1; FinSi SiNo acepta <- Falso; FinSi FinSi Si cantado Y acepta Entonces Escribir "Tu Envido: ", envidoJugador; Escribir "Envido de la computadora: ", envidoCPU; Si envidoJugador > envidoCPU Entonces puntosJugador <- puntosJugador + 2; Escribir "Ganaste el Envido."; SiNo Si envidoCPU > envidoJugador Entonces puntosCPU <- puntosCPU + 2; Escribir "La computadora ganó el Envido."; SiNo Si mano = 1 Entonces puntosJugador <- puntosJugador + 2; Escribir "Empate de Envido: ganás por ser mano."; SiNo puntosCPU <- puntosCPU + 2; Escribir "Empate de Envido: gana la computadora por ser mano."; FinSi FinSi FinSi Esperar Tecla; FinSi FinSubProceso SubProceso IntentarCantoJugador(manoCPU, apuestaTruco Por Referencia, ultimoCantor Por Referencia, puntosJugador Por Referencia, manoTerminada Por Referencia) Definir nuevoValor Como Entero; nuevoValor <- apuestaTruco + 1; Escribir "Cantás: ¡", NombreCanto(nuevoValor), "!"; Si CPUAceptaTruco(manoCPU) Entonces Escribir "La computadora dice: ¡QUIERO!"; apuestaTruco <- nuevoValor; ultimoCantor <- 1; SiNo Escribir "La computadora dice: NO QUIERO."; puntosJugador <- puntosJugador + apuestaTruco; manoTerminada <- Verdadero; FinSi FinSubProceso SubProceso IntentarCantoCPU(apuestaTruco Por Referencia, ultimoCantor Por Referencia, puntosCPU Por Referencia, manoTerminada Por Referencia) Definir nuevoValor, opcion Como Entero; nuevoValor <- apuestaTruco + 1; Escribir "La computadora canta: ¡", NombreCanto(nuevoValor), "!"; Escribir "1. Quiero"; Escribir "2. No quiero"; Leer opcion; Si opcion = 1 Entonces apuestaTruco <- nuevoValor; ultimoCantor <- 2; SiNo puntosCPU <- puntosCPU + apuestaTruco; manoTerminada <- Verdadero; FinSi FinSubProceso Funcion ganador <- ResolverDespuesDeDos(g1, g2) ganador <- -1; Si g1 = 0 Y g2 <> 0 Entonces ganador <- g2; FinSi Si g1 <> 0 Y g2 = 0 Entonces ganador <- g1; FinSi Si g1 <> 0 Y g1 = g2 Entonces ganador <- g1; FinSi FinFuncion Funcion ganador <- ResolverConTercera(g1, g2, g3, mano) Si g1 = 0 Y g2 = 0 Entonces Si g3 = 0 Entonces ganador <- mano; SiNo ganador <- g3; FinSi SiNo Si g1 <> 0 Y g2 <> 0 Y g1 <> g2 Entonces Si g3 = 0 Entonces ganador <- g1; SiNo ganador <- g3; FinSi SiNo ganador <- ResolverDespuesDeDos(g1,g2); FinSi FinSi FinFuncion Proceso Truco_Argentino Definir mazo, manoJugador, manoCPU Como Entero; Definir usadaJugador, usadaCPU Como Logico; Definir puntosJugador, puntosCPU, mano Como Entero; Definir apuestaTruco, ultimoCantor, vuelta, lider Como Entero; Definir posJugador, posCPU, cartaJugador, cartaCPU Como Entero; Definir g1, g2, g3, ganadorVuelta, ganadorMano Como Entero; Definir opcion, i Como Entero; Definir manoTerminada Como Logico; Dimension mazo[40]; Dimension manoJugador[3]; Dimension manoCPU[3]; Dimension usadaJugador[3]; Dimension usadaCPU[3]; puntosJugador <- 0; puntosCPU <- 0; mano <- 1; Mientras puntosJugador < 15 Y puntosCPU < 15 Hacer CrearMazo(mazo); MezclarMazo(mazo); Repartir(mazo, manoJugador, manoCPU); Para i <- 1 Hasta 3 Hacer usadaJugador[i] <- Falso; usadaCPU[i] <- Falso; FinPara apuestaTruco <- 1; ultimoCantor <- 0; manoTerminada <- Falso; g1 <- 0; g2 <- 0; g3 <- 0; Limpiar Pantalla; Escribir "===================================="; Escribir " TRUCO ARGENTINO"; Escribir "===================================="; Escribir "Vos: ", puntosJugador, " puntos"; Escribir "CPU: ", puntosCPU, " puntos"; Si mano = 1 Entonces Escribir "Sos mano."; SiNo Escribir "La computadora es mano."; FinSi MostrarMano(manoJugador, usadaJugador); GestionarEnvido(manoJugador, manoCPU, mano, puntosJugador, puntosCPU); lider <- mano; vuelta <- 1; Mientras vuelta <= 3 Y NO manoTerminada Hacer Limpiar Pantalla; Escribir "Marcador: Vos ", puntosJugador, " - CPU ", puntosCPU; Escribir "Valor actual de la mano: ", apuestaTruco; Escribir "Vuelta ", vuelta; Si lider = 1 Entonces MostrarMano(manoJugador, usadaJugador); Si apuestaTruco < 4 Y (ultimoCantor = 0 O ultimoCantor = 2) Entonces Escribir "1. Jugar carta"; Escribir "2. Cantar ", NombreCanto(apuestaTruco + 1); Leer opcion; Si opcion = 2 Entonces IntentarCantoJugador(manoCPU, apuestaTruco, ultimoCantor, puntosJugador, manoTerminada); FinSi FinSi Si NO manoTerminada Entonces posJugador <- ElegirCartaJugador(manoJugador, usadaJugador); cartaJugador <- manoJugador[posJugador]; usadaJugador[posJugador] <- Verdadero; Escribir Sin Saltar "Jugaste: "; MostrarCarta(cartaJugador); Escribir ""; Si apuestaTruco < 4 Y (ultimoCantor = 0 O ultimoCantor = 1) Y Aleatorio(1,100) <= 18 Entonces IntentarCantoCPU(apuestaTruco, ultimoCantor, puntosCPU, manoTerminada); FinSi FinSi Si NO manoTerminada Entonces posCPU <- ElegirCartaCPU(usadaCPU); cartaCPU <- manoCPU[posCPU]; usadaCPU[posCPU] <- Verdadero; Escribir Sin Saltar "CPU juega: "; MostrarCarta(cartaCPU); Escribir ""; FinSi SiNo Si apuestaTruco < 4 Y (ultimoCantor = 0 O ultimoCantor = 1) Y Aleatorio(1,100) <= 18 Entonces IntentarCantoCPU(apuestaTruco, ultimoCantor, puntosCPU, manoTerminada); FinSi Si NO manoTerminada Entonces posCPU <- ElegirCartaCPU(usadaCPU); cartaCPU <- manoCPU[posCPU]; usadaCPU[posCPU] <- Verdadero; Escribir Sin Saltar "CPU juega: "; MostrarCarta(cartaCPU); Escribir ""; MostrarMano(manoJugador, usadaJugador); Si apuestaTruco < 4 Y (ultimoCantor = 0 O ultimoCantor = 2) Entonces Escribir "1. Jugar carta"; Escribir "2. Cantar ", NombreCanto(apuestaTruco + 1); Leer opcion; Si opcion = 2 Entonces IntentarCantoJugador(manoCPU, apuestaTruco, ultimoCantor, puntosJugador, manoTerminada); FinSi FinSi FinSi Si NO manoTerminada Entonces posJugador <- ElegirCartaJugador(manoJugador, usadaJugador); cartaJugador <- manoJugador[posJugador]; usadaJugador[posJugador] <- Verdadero; Escribir Sin Saltar "Jugaste: "; MostrarCarta(cartaJugador); Escribir ""; FinSi FinSi Si NO manoTerminada Entonces ganadorVuelta <- CompararCartas(cartaJugador, cartaCPU); Si ganadorVuelta = 1 Entonces Escribir "Ganaste la vuelta."; lider <- 1; SiNo Si ganadorVuelta = 2 Entonces Escribir "La CPU ganó la vuelta."; lider <- 2; SiNo Escribir "Parda."; FinSi FinSi Si vuelta = 1 Entonces g1 <- ganadorVuelta; FinSi Si vuelta = 2 Entonces g2 <- ganadorVuelta; ganadorMano <- ResolverDespuesDeDos(g1,g2); Si ganadorMano <> -1 Entonces manoTerminada <- Verdadero; FinSi FinSi Si vuelta = 3 Entonces g3 <- ganadorVuelta; ganadorMano <- ResolverConTercera(g1,g2,g3,mano); manoTerminada <- Verdadero; FinSi vuelta <- vuelta + 1; Esperar Tecla; FinSi FinMientras Si ganadorMano = 1 Entonces puntosJugador <- puntosJugador + apuestaTruco; Escribir "Ganaste la mano y sumás ", apuestaTruco, " punto(s)."; FinSi Si ganadorMano = 2 Entonces puntosCPU <- puntosCPU + apuestaTruco; Escribir "La CPU ganó la mano y suma ", apuestaTruco, " punto(s)."; FinSi Si mano = 1 Entonces mano <- 2; SiNo mano <- 1; FinSi Esperar Tecla; FinMientras Limpiar Pantalla; Escribir "===================================="; Escribir " FIN DEL JUEGO"; Escribir "===================================="; Si puntosJugador >= 15 Entonces Escribir "¡Ganaste la partida!"; SiNo Escribir "La computadora ganó la partida."; FinSi Escribir "Resultado final: ", puntosJugador, " a ", puntosCPU; FinProceso
¿Qué hace cada parte?
NumeroCarta() y PaloCarta()
Estas funciones traducen el número interno del 1 al 40 a una carta real. De esta manera el resto del programa puede trabajar con enteros sin perder una presentación comprensible para el jugador.
ValorTruco()
Convierte cada carta a un valor de fuerza. Esto evita llenar el programa de comparaciones especiales cada vez que queremos decidir quién ganó una vuelta.
CalcularEnvido()
Analiza las tres cartas de una mano. Primero obtiene el valor individual de cada una y luego compara las tres posibles parejas para verificar si comparten palo.
MezclarMazo()
Usa Aleatorio() para implementar Fisher-Yates. Como solamente cambiamos posiciones de un mazo ya existente, no hay riesgo de generar cartas repetidas.
ResolverDespuesDeDos() y ResolverConTercera()
Estas funciones concentran las reglas de las pardas. Separarlas del proceso principal hace que la lógica de quién gana una mano sea mucho más fácil de leer y modificar.
La computadora
La CPU elige cartas disponibles al azar, pero algunas decisiones tienen una pequeña lógica. Por ejemplo, es más probable que acepte un Truco si posee al menos una carta fuerte y tiende a cantar Envido cuando su puntaje es alto.
No estamos intentando construir una inteligencia artificial perfecta: queremos una computadora suficientemente impredecible como para que el juego resulte entretenido y, al mismo tiempo, mantener el código accesible.
Un detalle importante sobre el azar
Aleatorio() aparece en varias partes del proyecto:
- mezcla del mazo;
- selección de cartas de la CPU;
- decisión de aceptar o rechazar ciertos cantos;
- decisión de la computadora de cantar Truco.
Por eso dos partidas no deberían desarrollarse exactamente igual.
Ideas para mejorar el proyecto
- agregar Real Envido y Falta Envido;
- implementar Flor;
- jugar a 30 puntos;
- hacer una CPU que analice las cartas ya jugadas;
- permitir que la computadora mienta o “farolee” con más frecuencia;
- guardar estadísticas de partidas ganadas y perdidas;
- crear una versión para 2 jugadores humanos;
- crear la modalidad 2 contra 2;
- separar todavía más la lógica en nuevos SubProcesos.
Desafío
Como primer desafío, modificá la lógica de la computadora para que no elija siempre una carta completamente al azar. Por ejemplo, podría intentar jugar una carta baja cuando ya sabe que no puede ganar una vuelta o reservar su mejor carta para más adelante.
Después agregá Real Envido y Falta Envido. Ahí vas a tener que transformar el Envido en un verdadero sistema de apuestas encadenadas, de manera similar a lo que ya hicimos con Truco, Retruco y Vale Cuatro.
¿Te sirvió este proyecto? ☕
Si este juego te resultó útil y querés apoyar a Club Programador para que podamos seguir publicando ejercicios, proyectos y guías gratuitas, podés colaborar mediante:
Cualquier aporte ayuda a seguir creando contenido gratuito para aprender programación.
Seguí aprendiendo PSeInt
Este proyecto combina prácticamente todos los conceptos que fuimos viendo en la serie. Si necesitás repasar alguno, podés volver a la guía principal:
Aprender PSeInt: guía completa y ejercicios resueltos →
Descubre más desde Club Programador
Suscríbete y recibe las últimas entradas en tu correo electrónico.