Ver Mensaje Individual
  #2 (permalink)  
Antiguo 13/06/2016, 01:59
eferion
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Juego de cartas

Cita:
Iniciado por demurral96 Ver Mensaje
Soy estudiante de ingeniería desoftware y apenas es mi segundo cuatrimestre por lo tanto todavía no se mucho ni domino esto de la programación.
Conozco chavales de 15 años que se hacen sus progamitas en Java... que estés en un curso X no implica que tus conocimientos tengan que ser necesariamente escasos.

Te lo comento porque intentar excusarte con este tipo de argumentos no te va a aportar nada.

Bueno, vamos a por tu código. Voy a ponerme un poco en modo profe así que espero que mis comentarios los veas desde una perspectiva crítica no despectiva.

La primera regla de todo programa es que este ha de ser legible. Esto implica que las variables y los objetos usados en el programa han de tener nombres lo más descriptivos posibles.

Código C:
Ver original
  1. struct c{
  2.   int x;
  3.   char signo;
  4. };

Estas 4 líneas de código de ejemplo violan completamente el párrafo anterior:
  • ¿Por que c? ¿Tanto cuesta poner carta?
  • ¿Qué demonios es x? ¿No será por algún casual el número de la carta?
  • ¿Y signo? No sabía que las cartas tenían signo. Espera... ¿No será que signo representa el palo?

Por otro lado, tenemos que una baraja tiene 4 palos diferentes: Oros, Copas, Espadas y Bastos. Aquí podría perfectamente usarse un enum y no tener que repetir una ristra tremendamente legible de 155, 156, 157 y 159. Si luego quieres cambiar el caracter asociado te toca hacer 13 sustituciones para que el programa siga funcionando:

Código C:
Ver original
  1. enum Palos
  2. {
  3.   PaloNoValido, // Para posibles errores
  4.   Oros,    // O Diamantes
  5.   Copas,   // O Trébol
  6.   Espadas, // O Picas
  7.   Bastos   // O Corazones
  8. };
  9. typedef enum Palos Palos;
  10.  
  11. struct Carta{
  12.   int valor;
  13.   Palos palo;
  14. };
  15. typedef struct Carta Carta;
  16.  
  17. char GetPalo(Palos palo)
  18. {
  19.   char toReturn = 0;
  20.  
  21.   switch( palo )
  22.   {
  23.     case Oros:
  24.       toReturn = 155;
  25.       break;
  26.  
  27.     case Copas:
  28.       toReturn = 156;
  29.       break;
  30.  
  31.     case Espadas:
  32.       toReturn = 157;
  33.       break;
  34.  
  35.     case Bastos:
  36.       toReturn = 158;
  37.       break;
  38.   }
  39.  
  40.   return toReturn;
  41. }

Aunque pueda parecer una chorrada hay convenciones que conviene adquirir. En el caso de C, las macros, por motivos históricos, se han escrito siempre en mayúsculas para diferenciarlas de las variables y funciones. En tu caso tarjetas debería estar en mayúsculas:

Código C:
Ver original
  1. #define TARJETAS 5

Por otro lado se asume que cada jugador va a manejar cartas. Esta parte del programa la puedes enfocar de dos formas diferentes:
  • Solo hay una lista de cartas y a cada jugador le facilitas un puntero (puntero o índice a la posición) a las cartas que posea.
  • Cada jugador recibe una copia de las cartas.

En tu caso has optador por una tercera vía que es que cada jugador tiene únicamente ¿un char? de cartas. ¿Qué pretendes almacenar en el char? Si es el índice al mazo entonces char no es la opción recomendable por semántica. Si pretendes almacenar una copia de la carta char se te queda corto.

Código C:
Ver original
  1. // Almacenar punteros
  2. Carta* jugador1[TARJETAS] = {0};
  3.  
  4. // Almacenar índices
  5. int jugador1[TARJETAS] = {-1};
  6.  
  7. // Almacenar copia (ojo)
  8. Carta jugador1[TARJETAS] = {};

Almacenar punteros o índices es sencillo porque para descartar una carta basta con asignar a ese elemento valor no válido (puntero=0 o índice=-1) para saber qué elemento hay que sustituir. En el caso de las copias necesitarías crear una carta especial para reconocerla y poder descartar correctamente.

Yo no soy demasiado amigo de tener los valores escritos a pelo en medio del código... y si es una baraja entera menos aun. Para generar el mazo de cartas yo te propondría usar símplemente un array de enteros de 0 a 52. Conocer el valor de la carta o el palo dado su índice es bastante sencillo:

Código C:
Ver original
  1. #define NUM_CARTAS 52
  2.  
  3. int GetValorCarta(int indice)
  4. {
  5.   return (indice%13) + 1;
  6. }
  7.  
  8. Palos GetPaloCarta(int indice)
  9. {
  10.   Palos toReturn = PaloNoValido;
  11.  
  12.   switch( indice/13 )
  13.   {
  14.     case 0:
  15.       toReturn = Oros;
  16.       break;
  17.  
  18.     case 1:
  19.       toReturn = Copas;
  20.       break;
  21.  
  22.     case 2:
  23.       toReturn = Espadas;
  24.       break;
  25.  
  26.     case 3:
  27.       toReturn = Bastos;
  28.       break;
  29.   }
  30.  
  31.   return toReturn;
  32. }
  33.  
  34. int main()
  35. {
  36.   int mazo[NUM_CARTAS];
  37.   for(int i=0; i<NUM_CARTAS; i++)
  38.     mazo[i] = i;
  39. }

Para mezclar las cartas lo más sencillo puede ser programar una serie de intercambios. Puedes, por ejemplo, recorrer la baraja 3 veces y en cada pasada vas intercambiando la carta actual con otra elegida al azar:

Código C:
Ver original
  1. #include <time.h>
  2. #include <stdlib.h>
  3.  
  4. // Macro para intercambiar valores
  5. #define SWAP(a,b) { int c=a; a=b; b=c; }
  6.  
  7. void barajar(int mazo[NUM_CARTAS])
  8. {
  9.   srand(time(NULL));
  10.  
  11.   for(int i=0; i<3; i++ ) // Recorremos 3 veces el mazo
  12.   {
  13.     for(int j=0; j<NUM_CARTAS; j++ ) // Iteramos cada carta
  14.     {
  15.       // Elegimos otra carta al azar
  16.       int otra = rand()%NUM_CARTAS;
  17.  
  18.       // intercambiamos las cartas
  19.       SWAP(mazo[j],mazo[otra]);
  20.     }
  21.   }
  22. }

Juntando todo lo dicho anteriormente tendríamos algo tal que:

Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5.  
  6. #define TARJETAS 5
  7. #define NUM_CARTAS 52
  8.  
  9. // Macro para intercambiar valores
  10. #define SWAP(a,b) { int c=a; a=b; b=c; }
  11.  
  12. enum Palos
  13. {
  14.   PaloNoValido, // Para posibles errores
  15.   Oros,    // O Diamantes
  16.   Copas,   // O Trébol
  17.   Espadas, // O Picas
  18.   Bastos   // O Corazones
  19. };
  20.  
  21. // Para convertir fácilmente cada palo a cadena
  22. const char* PalosToString[] = { "", "Oros", "Copas", "Espadas", "Bastos" };
  23.  
  24. typedef enum Palos Palos;
  25.  
  26. int GetValorCarta(int indice)
  27. {
  28.   return (indice%13) + 1;
  29. }
  30.  
  31. Palos GetPaloCarta(int indice)
  32. {
  33.   Palos toReturn = PaloNoValido;
  34.  
  35.   switch( indice/13 )
  36.   {
  37.     case 0:
  38.       toReturn = Oros;
  39.       break;
  40.  
  41.     case 1:
  42.       toReturn = Copas;
  43.       break;
  44.  
  45.     case 2:
  46.       toReturn = Espadas;
  47.       break;
  48.  
  49.     case 3:
  50.       toReturn = Bastos;
  51.       break;
  52.   }
  53.  
  54.   return toReturn;
  55. }
  56.  
  57. void barajar(int mazo[NUM_CARTAS])
  58. {
  59.   srand(time(NULL));
  60.  
  61.   for(int i=0; i<3; i++ ) // Recorremos 3 veces el mazo
  62.   {
  63.     for(int j=0; j<NUM_CARTAS; j++ ) // Iteramos cada carta
  64.     {
  65.       // Elegimos otra carta al azar
  66.       int otra = rand()%NUM_CARTAS;
  67.  
  68.       // intercambiamos las cartas
  69.       SWAP(mazo[j],mazo[otra]);
  70.     }
  71.   }
  72. }
  73.  
  74. int main()
  75. {
  76.   int mazo[NUM_CARTAS];
  77.   for(int i=0; i<NUM_CARTAS; i++)
  78.     mazo[i] = i;
  79.  
  80.   barajar(mazo);
  81.  
  82.   for( int i=0;i<NUM_CARTAS;i++)
  83.   {
  84.     int valor = GetValorCarta(mazo[i]);
  85.     Palos palo = GetPaloCarta(mazo[i]);
  86.     printf("%d de %s\n", valor, PalosToString[palo]);
  87.   }
  88.  
  89.   int jugador1[TARJETAS] = {-1};
  90.   int jugador2[TARJETAS] = {-1};
  91.   int jugador3[TARJETAS] = {-1};
  92.   int jugador4[TARJETAS] = {-1};
  93.  
  94. }

Creo que este es un buen punto para retomar tu ejercicio.

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.