Problema mazo de cartas

Iniciado por makul, 4 Septiembre 2019, 05:52 AM

0 Miembros y 1 Visitante están viendo este tema.

makul

Buenas tardes, tengo que hacer un juego de cartas llamado siete y medio, pero tengo serios problemas con el mazo. No tengo idea de como sacar una carta y descontarla del mazo.
Hasta ahora he podido hacer esto.

Código (cpp) [Seleccionar]

#include <iostream>
#include <ctime>
#include <conio.h>
#include<iostream>
#include<stdlib.h>

using namespace std;

int main ()
{
bool game_over;

cout<<"Bienvenido al juego siete y media"<<endl;
cout<<endl;

cout<<"Use tecla -i- para iniciar el juego y recibir una carta"<<endl;
cout<<"Use la tecla -n- para no recibir mas cartas"<<endl;
cout<<"Use la tecla -r- para ver las reglas"<<endl;
cout<<"Use la tecla -s- para salir del juego"<<endl;
cout<<endl;

int mazo [][10] =
{{1,2,3,4,5,6,7,10,11,12},{1,2,3,4,5,6,7,10,11,12},
{1,2,3,4,5,6,7,10,11,12},{1,2,3,4,5,6,7,10,11,12}};

int carta;
int palo;

   for (int carta =0; carta<10;carta++){
          for(int palo=0; palo<4;palo++)
  cout<<mazo[palo] [carta];
  cout<<endl;
         }
               
 cout<<"La carta es: ";
               
switch (carta){
case 1:cout<< " 1 de "; break;
        case 2:cout<< " 2 de ";break;
case 3:cout<< " 3 de ";break;
case 4:cout<< " 4 de ";break;
case 5:cout<< " 5 de ";break;
case 6:cout<< " 6 de ";break;
case 7:cout<< " 7 de ";break;
case 8:cout<< " 10 de ";break;
case 9:cout<< " 11 de ";break;
case 10:cout<< " 12 de ";break;
              }

       switch (palo) {      
             
                        case 0:cout<< "Espada. "<<endl;
case 1:cout<< "Basto. "<<endl;
case 2:cout<< "Oro. "<<endl;
case 3:cout<< "Copa. "<<endl;
}

                       
int valor_medio, valor_carta_entera;
                 
if (carta == 8 || carta == 9  || carta == 10 )
                   {valor_medio=0.5;}
else {valor_carta_entera = carta;}

int maximo =7.5;
float puntaje_pc;
float puntaje_jugador;

while (game_over == false)

             {while(!kbhit()) {
int tecla=getch();

switch(tecla)

                       {

                        case 'i': case 'I':
   
//aca va tirar una carta, sacarla del mazo y preguntar si quiere otra carta sino pasar a la pc y hacer los dos primeros pasos//

cout<<"Usted ha sacado: "<<carta<<endl;
cout<<"Si quiere otra carta ingrese tecla -i-"<<endl;
cout<<"si no quiere otra carta, ingrese tecla -n- y será el turno de la PC."<<endl;


if (puntaje_jugador < maximo)
{
cout<<"A obtenido "<<puntaje_jugador<< " puntos, ahora es el turno de la PC. "<<endl;
}
else if  (puntaje_jugador == maximo)
{
cout<<"A obtenido " <<puntaje_jugador<< " puntos, ha ganado, felicidades."<<endl;
game_over = true;}
else
{
cout<<"Usted se ha pasado de 7.5, usted ha perdido."<<endl;
game_over = true;}



case 'n': case 'N':

cout<<"Usted no quiere mas cartas. Su resultado es: "<<puntaje_jugador<<endl;
cout<<"Ahora es el turno de la PC."<<endl;


if (puntaje_pc < puntaje_jugador || (puntaje_pc > maximo));
{
cout<<"La PC ha obtenido este puntaje: "<<puntaje_pc;
cout<<"Usted ha ganado"<<endl;
game_over = true;
}
else ((puntaje_pc == maximo) ||  (puntaje_pc == puntaje_jugador));  
{
cout<<"A obtenido " <<puntaje_pc<< " puntos, ha ganado la pc."<<endl;
game_over = true;
}


                      case 'r': case 'R':

cout<<"Reglas del juego: "<<endl;
cout<<endl;
cout<<"En este juego de cartas al jugador se le reparte 1 carta."<<endl;

cout<<"El objetivo es acercarse a 7.5, sin pasarse. Si cree que le falta puede pedir todas las cartas que quiera pero si se pasa, pierde."<<endl;

cout<<"Si decide plantarse antes de pasarse de 7 y medio, juega la Computadora que hace lo mismo. Si le empata o gana al jugador, entonces la PC gana."<<endl;

cout<<"Se juega con las cartas españolas, del 1 al 7 y las figuras. Cada carta vale su valor. Las figuras valen 0.5."<<endl;

cout<<"Al apretar tecla -i-, el juego inicia, dando entender que ya conoce estas reglas"<<endl;
cout<<"Si quiere salir del juego presioné la letra s."<<endl;break;



                        case 's': case 'S':

cout<<"Usted a salido del juego."<<endl;
   game_over = true;
}
}

}
return 0;
}


}





Mod: Arregladas las etiquetas.

K-YreX

Voy a intentar ayudarte aunque sin revisar tu código ya que al centrarlo creo que me está dando dolor de cabeza leerlo... :xD
Depende de los recursos que quieras/puedas usar:
  • Usar contenedores de la STL como <set>, <multiset> u otros.
  • Usar un array unidimensional de TAM = numCartas y cada vez que escoges una carta, la pones en array[numCartasDisponibles - 1] y decrementas <numCartasDisponibles>.
    Habrá más formas de hacerlo pero creo que esas son las más intuitivas y sencillas haciendo uso o no de la STL. :-X
    PD: Cambia la alineación del código para verlo bien tabulado  :silbar: y si aprovechas y pones las etiquetas específicas de C++ mejor ya que así resalta la sintaxis. (Para ello en la etiqueta de apertura que pone "code" entre corchetes, añade "=cpp" para que quede <corchete><code=cpp><corchete> :-X
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

@XSStringManolo

#2
Script live, tiene la opción de eliminar cartas de una mano que prestablezcas. Es decir, si tienes X cartas en la mano, esas cartas las elimina del mazo. https://test-nbopmp.blogspot.com/2019/07/scriptpoker-var-cartasinicialesenelmazo.html?m=1

Yo andaba haciendo movidas de estadísticas de poker en javascript que aún tengo pendiente. Puedes probar y ver más código arriba, eso de las cartas lo hice así:

Código (javascript) [Seleccionar]
var ARRAYmazoOriginal = ["T1", "T2", "T3", "T4", "T5", "T6", "T7", "T8", "T9", "T10", "TJ", "TQ", "TK", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "C10", "CJ", "CQ", "CK", "P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9", "P10", "PJ", "PQ", "PK", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "RJ", "CQ", "CK"];

var ARRAYmazoEnPartida = ["T1", "T2", "T3", "T4", "T5", "T6", "T7", "T8", "T9", "T10", "TJ", "TQ", "TK", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "C10", "CJ", "CQ", "CK", "P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9", "P10", "PJ", "PQ", "PK", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "RJ", "CQ", "CK"];

var ARRAYmiMano = [cartaMano1, cartaMano2, cartaMesa1, cartaMesa2, cartaMesa3, cartaMesa4, cartaMesa5];

case 2:

  alert("Para introducir tus cartas:\n T = Trebol\n P = Picas\n R = Rombos\n C = Corazones\n\n Ejemplos: T1 T2 C3 PQ ...");

  cartaMano1 = prompt("Pon la primera carta de tu mano");
  cartaMano2 = prompt("Pon tu otra carta");

  cartaMesa1 = prompt("Pon la primera carta de la mesa");
  cartaMesa2 = prompt("Pon la segunda carta de la mesa");
  cartaMesa3 = prompt("Pon la tercera carta de la mesa");
  cartaMesa4 = prompt("Pon la cuarta carta de la mesa");
  cartaMesa5 = prompt("Pon la quinta carta de la mesa");

ARRAYmiMano = [cartaMano1, cartaMano2, cartaMesa1, cartaMesa2, cartaMesa3, cartaMesa4, cartaMesa5];


tamanhoARRAYmazoEnPartida = ARRAYmazoEnPartida.length;

for (var i = 0; i<tamanhoARRAYmazoEnPartida;i++)
{
 if (ARRAYmazoEnPartida[i] == cartaMano1)
{
ARRAYmazoEnPartida.splice(i,1);
}

if (ARRAYmazoEnPartida[i] == cartaMano2)
{
ARRAYmazoEnPartida.splice(i,1);
}

if (ARRAYmazoEnPartida[i] == cartaMesa1)
{
ARRAYmazoEnPartida.splice(i,1);
}

if (ARRAYmazoEnPartida[i] == cartaMesa2)
{
ARRAYmazoEnPartida.splice(i,1);
}

if (ARRAYmazoEnPartida[i] == cartaMesa3)
{
ARRAYmazoEnPartida.splice(i,1);
}

if (ARRAYmazoEnPartida[i] == cartaMesa4)
{
ARRAYmazoEnPartida.splice(i,1);
}

if (ARRAYmazoEnPartida[i] == cartaMesa5)
{
ARRAYmazoEnPartida.splice(i,1);
}
}

No me suena de que haya algo estandar en C++ como splice, que lo que hace es eliminar desde la posición i del array (primer parámetro). El número de elementos que introduzcas en el segundo parámetro.

Puedes hacer tu una implementación de la función Splice o cualquier otra que haga lo mismo para C++. Por ejemplo creando un nuevo array temporal y metiendo todos los elementos menos el elemento del índice a excluir. Le sumas una variable a 0 al ínidice y ese es el segundo parámetro de la función.

makul

#3
Cita de: YreX-DwX en  4 Septiembre 2019, 06:13 AM
Voy a intentar ayudarte aunque sin revisar tu código ya que al centrarlo creo que me está dando dolor de cabeza leerlo... :xD
Depende de los recursos que quieras/puedas usar:
  • Usar contenedores de la STL como <set>, <multiset> u otros.
  • Usar un array unidimensional de TAM = numCartas y cada vez que escoges una carta, la pones en array[numCartasDisponibles - 1] y decrementas <numCartasDisponibles>.
    Habrá más formas de hacerlo pero creo que esas son las más intuitivas y sencillas haciendo uso o no de la STL. :-X
    PD: Cambia la alineación del código para verlo bien tabulado  :silbar: y si aprovechas y pones las etiquetas específicas de C++ mejor ya que así resalta la sintaxis. (Para ello en la etiqueta de apertura que pone "code" entre corchetes, añade "=cpp" para que quede <corchete><code=cpp><corchete> :-X
Muchas gracias, ahora intentare aplicar lo que me dijiste de crear otro array, pero para que salga la carta al azar, tambien debo aplicar srand en ese array? Gracias por el dato de las etiquetas.

K-YreX

No, es mucho más fácil. Generas un número aleatorio entre 0 y numCartasDisponibles-1 y listo:
Código (cpp) [Seleccionar]

// Obtener una carta aleatoria
int indiceAleatorio = rand() % numCartasDisponibles;
int cartaAleatoria = cartas[indiceAleatorio];

// Eliminamos esa carta de las disponibles
cartas[indiceAleatorio] = cartas[numCartasDisponibles-1];
--numCartasDisponibles;

// Tambien puedes hacer
cartas[indiceAleatorio] = cartas[numCartasDisponibles-1];
cartas[numCartasDisponibles-1] = cartaAleatoria;
--numCartasDisponibles;

Si eliminas la carta de la primera forma estás perdiendo el valor de esa carta en el array mientras que si lo haces de la segunda forma tendrás de <0> a <cartasDisponibles-1> las cartas que aún no han salido y de <cartasDisponibles> a <numCartas> las cartas que ya han salido.
Yo te recomendaría la segunda forma porque es una sola línea de código más y te permite ver en cualquier momento todas las cartas que ya han salido y así puedes llevar un mayor control.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

@XSStringManolo

Si utilizas rand sin semilla, o con una semilla que se mantenga tras cafda ejecución, la serie pseudoaleatoria se mantiene tras cada ejecución.

Soy el usuario. Inicio el programa. Primer número pseudoaleatorio 4, segundo 8, tercero 11, cuarto 1, quinto 37...
Cierro el programa.

Vuelvo a abrir el programa. Primer número 4, segundo 8, tercero 11, cuarto 1...

Siempre van a ser los mismos.
Puedes usar la hora del sistema entre otros, ya que la hora cambia entre cada ejecución.

makul

#6
Cita de: YreX-DwX en  4 Septiembre 2019, 20:09 PM
No, es mucho más fácil. Generas un número aleatorio entre 0 y numCartasDisponibles-1 y listo:
Código (cpp) [Seleccionar]

// Obtener una carta aleatoria
int indiceAleatorio = rand() % numCartasDisponibles;
int cartaAleatoria = cartas[indiceAleatorio];

// Eliminamos esa carta de las disponibles
cartas[indiceAleatorio] = cartas[numCartasDisponibles-1];
--numCartasDisponibles;

// Tambien puedes hacer
cartas[indiceAleatorio] = cartas[numCartasDisponibles-1];
cartas[numCartasDisponibles-1] = cartaAleatoria;
--numCartasDisponibles;

Si eliminas la carta de la primera forma estás perdiendo el valor de esa carta en el array mientras que si lo haces de la segunda forma tendrás de <0> a <cartasDisponibles-1> las cartas que aún no han salido y de <cartasDisponibles> a <numCartas> las cartas que ya han salido.
Yo te recomendaría la segunda forma porque es una sola línea de código más y te permite ver en cualquier momento todas las cartas que ya han salido y así puedes llevar un mayor control.

Aun me salta error cuando quiero hacerlo >:(. Pude fijarme el resto del codigo y no hay errores. Esto de array sinceramente ya me da dolor de cabeza desde hace 2 meses.

Código (cpp) [Seleccionar]

#include <iostream>
#include <ctime>
#include <conio.h>
#include<iostream>
#include<stdlib.h>

using namespace std;


int main ()
{
bool game_over;
int mazo [][10] = {{1,2,3,4,5,6,7,10,11,12},{1,2,3,4,5,6,7,10,11,12},{1,2,3,4,5,6,7,10,11,12},{1,2,3,4,5,6,7,10,11,12}};
int carta,palo,cartaAleatoria;


   
   

           for (int carta =0; carta<10;carta++)
              {
                    for(int palo=0; palo<4;palo++)
             cout<<mazo[palo] [carta];
             cout<<endl;
                  }
                  int indiceAleatorio = rand() % 40+1;
  int cartaAleatoria = carta[rand() % 40+1];
               
               cout<<"La carta es: ";
               
                    switch (carta)
{
                       case 1:cout<< " 1 de "; break;
case 2:cout<< " 2 de ";break;
case 3:cout<< " 3 de ";break;
case 4:cout<< " 4 de ";break;
case 5:cout<< " 5 de ";break;
case 6:cout<< " 6 de ";break;
case 7:cout<< " 7 de ";break;
case 8:cout<< " 10 de ";break;
case 9:cout<< " 11 de ";break;
case 10:cout<< " 12 de ";break;
                    }
                    switch (palo)
{       case 0:cout<< "Espada. "<<endl;
        case 1:cout<< "Basto. "<<endl;
case 2:cout<< "Oro. "<<endl;
case 3:cout<< "Copa. "<<endl;
}

                       int valor_medio, valor_carta_entera;
                 
   if (carta == 8 || carta == 9  || carta == 10 )
{
valor_medio=0.5;
}
else
{
valor_carta_entera = carta;
}


cout<<"Bienvenido al juego siete y media"<<endl;
cout<<endl;

cout<<"Use tecla -i- para iniciar el juego y recibir una carta"<<endl;
cout<<"Use la tecla -n- para no recibir mas cartas"<<endl;
cout<<"Use la tecla -r- para ver las reglas"<<endl;
cout<<"Use la tecla -s- para salir del juego"<<endl;
cout<<endl;


int maximo =7.5;
float puntaje_pc;
float puntaje_jugador;

while (game_over == false)
{

while(!kbhit()) {
int tecla=getch();

switch(tecla)
{
case 'i': case 'I':
   
//aca va tirar una carta, sacarla del mazo y preguntar si quiere otra carta sino pasar a la pc y hacer los dos primeros pasos//

               cout<<"Usted ha sacado la carta: "<<carta<<endl;
               cartas[indiceAleatorio] = cartas[numCartasDisponibles-1];
cartas[numCartasDisponibles-1] = cartaAleatoria;
--numCartasDisponibles;


               cout<<"Si quiere otra carta ingrese tecla -i-"<<endl;
cout<<"si no quiere otra carta, ingrese tecla -n- y será el turno de la PC."<<endl;


                                 if (puntaje_jugador < maximo)
                                 
                                  {
                                  cout<<"A obtenido "<<puntaje_jugador<< " puntos, ahora es el turno de la PC. "<<endl;
  }
  else if  (puntaje_jugador == maximo)
  {
  cout<<"A obtenido " <<puntaje_jugador<< " puntos, ha ganado, felicidades."<<endl;
  game_over = true;
  }
  else
  {
  cout<<"Usted se ha pasado de 7.5, usted ha perdido."<<endl;
  game_over = true;
  }
case 'n': case 'N':

cout<<"Usted no quiere mas cartas. Su resultado es: "<<puntaje_jugador<<endl;
cout<<"Ahora es el turno de la PC."<<endl;
cout<<"Usted ha sacado la carta: "<<carta<<endl;
               cartas[indiceAleatorio] = cartas[numCartasDisponibles-1];
cartas[numCartasDisponibles-1] = cartaAleatoria;
--numCartasDisponibles;



     if (puntaje_pc < puntaje_jugador || (puntaje_pc > maximo))
 {
 cout<<"La PC ha obtenido este puntaje: "<<puntaje_pc;
 cout<<"Usted ha ganado"<<endl;
 game_over = true;}
     
          else ((puntaje_pc == maximo) ||  (puntaje_pc == puntaje_jugador));
         {
         
                     cout<<"A obtenido " <<puntaje_pc<< " puntos, ha ganado la pc."<<endl;
         game_over = true;
     }

case 'r': case 'R':
cout<<"Reglas del juego: "<<endl;
cout<<endl;
           cout<<"En este juego de cartas al jugador se le reparte 1 carta."<<endl;
               cout<<"El objetivo es acercarse a 7.5, sin pasarse. Si cree que le falta puede pedir todas las cartas que quiera pero si se pasa, pierde."<<endl;
               cout<<"Si decide plantarse antes de pasarse de 7 y medio, juega la Computadora que hace lo mismo. Si le empata o gana al jugador, entonces la PC gana."<<endl;
               cout<<"Se juega con las cartas españolas, del 1 al 7 y las figuras. Cada carta vale su valor. Las figuras valen 0.5."<<endl;
               cout<<"Al apretar tecla -i-, el juego inicia automaticamente dando entender que ya conoce estas reglas"<<endl;
cout<<"Si quiere salir del juego presioné la letra s."<<endl;
break;

case 's': case 'S':

cout<<"Usted a salido del juego."<<endl;
game_over = true;
}
}

}
return 0;
}

K-YreX

Está claro que hay errores. Yo te he mostrado una forma de hacer el ejercicio y he usado nombres de variables para que entiendas el funcionamiento, pero tú no puedes meter mi código en el tuyo y esperar que funcione cuando no has declarado esas variables.
Además:
  • Declaras dos veces <cartaAleatoria> (línea 14 y 27)
  • Creas la variable <indiceAleatorio> (línea 26) pero luego no lo usas en la siguiente instrucción (línea 27)
  • Estás asignando decimales a variables de tipo <int> (líneas 55 y 73)

    PD: Cuida las tabulaciones... No me extraña que si llevas dos meses con este código te duela la cabeza porque ya me duele a mí y lo he visto dos veces. :xD
    PD 2: Te recomendaría usar funciones para hacer el programa más limpio y más fácil de revisar tanto para ti como para nosotros. :-X
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

makul

#8
Cita de: YreX-DwX en  5 Septiembre 2019, 01:10 AM
Está claro que hay errores. Yo te he mostrado una forma de hacer el ejercicio y he usado nombres de variables para que entiendas el funcionamiento, pero tú no puedes meter mi código en el tuyo y esperar que funcione cuando no has declarado esas variables.
Además:
  • Declaras dos veces <cartaAleatoria> (línea 14 y 27)
  • Creas la variable <indiceAleatorio> (línea 26) pero luego no lo usas en la siguiente instrucción (línea 27)
  • Estás asignando decimales a variables de tipo <int> (líneas 55 y 73)

    PD: Cuida las tabulaciones... No me extraña que si llevas dos meses con este código te duela la cabeza porque ya me duele a mí y lo he visto dos veces. :xD
    PD 2: Te recomendaría usar funciones para hacer el programa más limpio y más fácil de revisar tanto para ti como para nosotros. :-X
Gracias por el dato de tabulaciones jaja. Aun no aprendì funciones asi que no puedo usarlas para cuando deba entregar esto. Por cierto, algun libro de c++ que puedas recomendar? jaja. Seguramente me falte algo mas de lectura para poder hacer esta clase de programas.

K-YreX

Libros no sé ya que yo apenas he leído uno. Es posible que @string Manolo te recomiende alguno ya que he visto otros temas en los que ha recomendado algunos libros. También puedes ver cursos online (posiblemente gratuitos) y sobre todo practicar mucho.
Te dejo un enlace AQUÍ a la página de <cplusplus.com>. Está en inglés pero es un inglés muy fácil de entender. Ahí puedes ver un montón de librerías con sus respectivas funciones y ejemplos de uso. Puede que te sirva.

Personalmente lo que haría sería "quitar los palos". Para este juego lo importante es el valor de la carta, el palo importa más bien poco y al quitar los palos podemos guardar todos los números en un solo array y aplicar el código que te puse para sacar una carta y hacer que no salga más veces.

Código (cpp) [Seleccionar]

#include <iostream>
#include <cstdlib>
#include <ctime>

const int NUM_CARTAS = 40;

int main(){
    int cartasDisponibles = NUM_CARTAS;
    int cartas[NUM_CARTAS] = {1,2,3,4,5,6,7,10,11,12,1,2,3,4,5,6,7,10,11,12,1,2,3,4,5,6,7,10,11,12,1,2,3,4,5,6,7,10,11,12};

    srand(time(NULL));

    while(cartasDisponibles > 0){
        int indiceAleatorio = rand() % cartasDisponibles;
        int cartaActual = cartas[indiceAleatorio];
        cout << "La carta sacada es: " << cartaActual << endl;
       
        // Guardamos la carta que hemos sacado al final del array para que no salga mas veces
        int auxiliar = cartas[indiceAleatorio];
        cartas[indiceAleatorio] = cartas[cartasDisponibles-1];
        cartas[cartasDisponibles-1] = auxiliar;
        --cartasDisponibles;

        // Si quieres ver las cartas que ya han salido
        cout << "Cartas que ya han salido: ";
        for(size_t i = cartasDisponibles; i < NUM_CARTAS; ++i)
            cout << cartas[i] << "  ";
    }
}

Puedes probar este código para que veas como saca todas las cartas y muestra las que ya han salido. Luego es cosa tuya ver qué cosas puedes aprovechar y cuáles no para tu programa.
En caso de hacerlo con una matriz y con los palos como lo tienes implementado, se complica un poco más el código. Tendrías que llevar 4 contadores: <orosDisponibles>, <copasDisponibles>, <espadasDisponibles> y <bastosDisponibles> y en vez de guardar las cartas que ya han salido al final del array, tendrías que guardarlos al final de la fila correspondiente a ese palo.

También tienes opciones un poco más "profesionales" pero que supongo que no habrás visto todavía como usar un <struct> o <class> llamado <Carta> que tenga <numero> y <palo> y hacer uso de contenedores de la STL como el <multiset>.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;