Pregunta

Estoy tratando de hacer un programa simple de blackjack. Lamentablemente, estoy teniendo problemas desde el principio con la generación de una baraja de cartas.

#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<char> deck;
    char suit[] = {'h','d','c','s'};
    char card[] = {'2','3','4','5','6','7','8','9','10','J','Q','K','A'};
    for (int j=0; j<13; j++) {
        for (int i=0; i<4; i++) {
            deck.push_back(card[j] suit[i]);
        }       
    }

    return 0;
}

Sé que mi problema comienza cuando intento asignar el valor '10' a un carácter. Obviamente no pude hacer que esto se compilara, pero estoy seguro de que cuando trato de asignar los valores de la tarjeta al mazo de vectores también obtendré un error ya que usé el tipo variable 'char'. Saber qué tipo de tipo variable usar parece estar matándome. Además, 'deck.push_back (carta [j] palo [i]);' ser el código correcto para combinar la tarjeta y el palo, o ¿tienes que poner algo entre la tarjeta [j] y el palo [i]? Agradecería que alguno de ustedes me guiara en la dirección correcta. También como una pequeña nota al margen, esto es parte de una tarea, así que no solo me des bloques enteros de código. Gracias por tu ayuda.

¿Fue útil?

Solución

Intenta crear una clase de Tarjeta con palo y tarjeta como miembro y configúrala como un tipo de vector. Me gusta

public class Card {
 public:
  Card(char suit, char card);
  char suit, card;
};

int main() {
    vector<Card> deck;
    char suit[] = {'h','d','c','s'};
    char card[] = {'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
    for (int j=0; j<13; j++) {
        for (int i=0; i<4; i++) {
                deck.push_back(new Card(card[j],suit[i]));
        }               
    }
    return 0;
}

también usar enumeraciones en lugar de caracteres en traje y tarjeta lo haría más claro.

Otros consejos

Creo que lo que está buscando usar es una enumeración. Aclarará su código y resolverá su problema.

enum SUIT { HEART, CLUB, DIAMOND, SPADE }; 
enum VALUE { ONE, TWO, THREE, ..., TEN, JACK, QUEEN, KING};

La forma en que lo modelas realmente depende de lo que intentas hacer.

¿Estás creando un juego real y las estructuras de datos solo necesitan soportar el juego?

Si es así, crearía una clase de tarjeta, con un campo de enumeración para el palo y un tipo numérico (con valores del 1 al 13) para el valor nominal.

Por otro lado, si está creando una aplicación de análisis o un reproductor de IA, entonces el modelo podría ser un poco diferente.

Hace unos años, escribí un simulador para calcular las probabilidades en varios escenarios de Texas Holdem, y quería que hiciera crujir los números REALMENTE rápidamente. Comencé con un modelo muy sencillo (clase de tarjeta, enumeración de palo, etc.) pero después de una gran cantidad de perfiles y optimización, terminé con una representación bit a bit.

Cada carta tenía un valor de dieciséis bits, con los trece bits de alto orden representando el valor nominal, los dos bits de bajo orden representando el palo, y con el bit [2] como una bandera especial que indica un as (usado solo en casos en los que el as podría aparecer en una recta A2345).

Aquí hay algunos ejemplos:

0000000000001001  <----  Two of hearts
0100000000000011  <----  King of spades
1000000000000110  <----  Ace of diamonds

^^^^^^^^^^^^^            ("face-value" bits)
             ^           ("low-ace" flag)
              ^^         ("suit" bits)

Puedes imaginar cómo, con un diseño como este, se ilumina rápidamente para buscar pares, tríos y rectos (los rubores son un poco más complicados).

No entraré en todas las operaciones particulares, pero basta con decir que este tipo de modelo admite millones de operaciones por segundo ...

Por supuesto, ten en cuenta que en realidad no estoy recomendando que uses un diseño como este en una implementación de juego sencilla. La única razón por la que terminé con este diseño es porque necesitaba realizar simulaciones estadísticas masivas.

Así que piense detenidamente cómo quiere modelar:

  • Cada tarjeta
  • La mano de un jugador
  • Toda la baraja
  • El estado de la mesa ... incluidas todas las manos de los jugadores (incluidos los jugadores que han dividido su mano inicial), tal vez un zapato de seis mazos, la pila de descarte, etc.

El modelo general de la aplicación, y los objetivos de la aplicación en general, determinarán en gran medida los tipos de estructuras de datos que serán más apropiados.

¡Diviértete!

Use 'T' en lugar de 10.

¿Has intentado reemplazar J con 11, Q con 12 y K con 13? Entonces podría usar int egers en lugar de char acters. Reemplace 11-13 con la letra apropiada más adelante.

Bueno, antes que nada, el mazo [0] es un personaje, pero estás intentando rellenar & "; 2h &"; en ello. (por el momento, ignoraremos que lo que está haciendo es incorrecto).

Básicamente, deberás hacer que el mazo sea un vector<std::string>. Convierta la tarjeta en una matriz de const char * s y convierta los elementos en una cadena.

luego use:

deck.push_back(std::string(card[j]) + suit[i]);

Como lo mencionaron otros, puede usar 'T' para diez, J, Q y K para las figuras. En cuanto a push_back ... dado que el deck es un vector de caracteres, solo puede pasar un carácter a push_back como argumento. Pasar tanto el valor de la tarjeta (1 ... 9, T, J, Q, K) como su suite no funciona.

Yo personalmente crearía una pequeña estructura, para representar una Tarjeta, con un valor y una propiedad Suite. Luego, puedes convertir tu mazo en un vector de Cartas.

Editado: arreglando la última palabra desde que la tarjeta vector (menor que) (mayor que) se representaba como vector (nada).

Esto podría no compilarse, pero este es el enfoque que usaría (y he usado). Querrás usar ints para representar tus cartas, pero puedes abstraerlo fácilmente en una clase. Lo que escribiré para ti.

class Card
{
public:
    enum ESuit
    {
        kSuit_Heart,
        kSuit_Club,
        kSuit_Diamond,
        kSuit_Spade,
        kSuit_Count
    };

    enum ERank
    {
        kRank_Ace,
        kRank_Two,
        kRank_Three,
        kRank_Four,
        kRank_Five,
        kRank_Six,
        kRank_Seven,
        kRank_Eight,
        kRank_Nine,
        kRank_Ten,
        kRank_Jack,
        kRank_Queen,
        kRank_King,
        kRank_Count
    };

    static int const skNumCards = kSuit_Count * kRank_Count;

    Card( int cardIndex )
    : mSuit( static_cast<ESuit>( cardIndex / kRank_Count ) )
    , mRank( static_cast<ERank>( cardIndex % kRank_Count ) )
    {}

    ESuit GetSuit() const { return mSuit );
    ERank GetRank() const { return mRank );

private:
    ESuit mSuit;
    ERank mRank;
}

Ahora es muy simple agregar a esta clase para obtener todo lo que desea de ella. Para generar la lista es tan simple como a continuación.

rstl::vector<Card> mCards;
mCards.reserve( Card::skNumCards );

for ( int cardValue = 0; cardValue < Card::skNumCards; ++cardValue )
{
    mCards.push_back( Card( cardValue ) );
}

¿Necesita barajar?

#include <algorithm>
std::random_shuffle( mCards.begin(), mCards.end() );

¿Qué tal ver cuál es el valor de la primera tarjeta?

if ( mCards[0].GetSuit() == Card::kRank_Club && mCards[0].GetRank() == Card::kRank_Ace )
{
    std::cout << "ACE OF CLUBS!" << std::endl;
}

No compilé nada de esto, pero debería estar cerca.

Dado que este es un programa de blackjack, agregará y comparará el valor de las tarjetas.

Siendo ese el caso, puede ahorrarse algo de programación y dolor adicionales al dar a las tarjetas valores int (1-13) en lugar de valores char .

Cuando creé mi clase de baraja de cartas C ++ , Me encontré con algunos problemas propios. En primer lugar, estaba tratando de convertir mi clase de mazo de cartas PHP a C ++, con mínima suerte. Decidí sentarme y ponerlo en papel. Decidí optar por una configuración orientada a objetos, principalmente porque siento que es la más fácil de usar para la expansión. Utilizo los objetos Card y Deck , así que, por ejemplo, si quieres poner 10 mazos en el Shoe de tu juego de blackjack, podría crear 10 mazos, lo cual sería bastante simple, porque decidí hacer que todo fuera autónomo. De hecho, es tan autónomo que, para crear su zapato, el código sería:

#include "AnubisCards.cpp"

int main() {

    Deck *shoe = new Deck(10);

}

Pero, eso fue por simplicidad, no exactamente necesario en juegos más pequeños donde solo necesitas una sola baraja.

EN CUALQUIER MODO, cómo I generó el mazo fue creando una matriz de 52 objetos de cartas. Los mazos son bastante fáciles, porque sabes que tienes 4 Trajes y 13 Cartas en cada palo , también sabes que tienes 2,3,4,5 , 6,7,8,9,10, Jack, Queen, King, Ace en cada palo . Esos nunca cambiarán. Entonces utilicé dos bucles, uno para el Traje y el otro para el Valor .

Fue algo como esto:

for(int suit = 1; suit <= 4; suit++){
    for(int card = 1; card <= 13; card++){
        // Add card to array
    }
}

Ahora, notará que en cada uno de esos bucles, uso un valor entero. La razón es simple, las tarjetas son números. 4 trajes 13 valores. Incluso el valor numérico en el juego de Blackjack. Valor nominal, hasta que golpees las cartas de la Cara, que son el valor numérico 10 hasta que alcances el As que es el valor numérico 1 u 11. Todo es números. Por lo tanto, puede utilizar esos números no solo para asignar el valor de la tarjeta, sino también el palo de la tarjeta y el número en la secuencia numérica.

Una idea sería almacenar un mapa en la clase Tarjeta, con los nombres de caracteres o Cadenas de las tarjetas, siendo 1,2,3 ... los índices para cada uno.

Iría con la sugerencia de Ross de usar números enteros. La mayoría de los juegos de cartas implicarán algunos cálculos matemáticos, por lo que es una mejor representación.

Convertir a 'A' o 'ACE' etc. en la salida.

Dado que esta es tarea para C ++, supongo que se espera que uses clases. De lo contrario, use las enumeraciones, y si esto fuera C, use una estructura o algo así.

Y para algunos juegos, aparte del valor de los puntos, querrás almacenar algún tipo de rango para la carta, que dependería del modo de juego actual.

No he hecho C simple para siempre, pero quiero decir algo como esto:

typedef struct struct_card {
  unsigned short int suit:2;
  unsigned short int card:4;
//  unsigned short int valu:4;
} card;

int main() {
  card a_card;
  card std_deck[52];
  const unsigned short int rummy_value[13] = {1,2,3,4,5,6,7,8,9,10,10,10,10};
  const char *std_card_name[13] = {"Ace","Two","Three","Four","Five","Six",
    "Seven","Eight","Nine","Ten","Jack","Queen","King"};
  const char *std_suit_name[4] = {"Spades","Clubs","Hearts","Diamonds"};

  int j, k, i=0;
  for(j=0; j<4; j++){
    for(k=0; k<13; k++){
      a_card.suit=j; a_card.card=k;
      std_deck[i++] = a_card;
    }
  }

  //check our work
  printf("In a game of rummy:\n");
  for(i=0;i<52;i++){
    printf("  %-5s of %-8s is worth %2d points.\n",
        std_card_name[std_deck[i].card],
        std_suit_name[std_deck[i].suit],
        rummy_value[std_deck[i].card]);
  }

  //a different kind of game.
  enum round_mode {SHEILD_TRUMP, FLOWER_TRUMP, BELL_TRUMP, ACORN_TRUMP, BOCK, GEISS} mode;
  const card jass_deck[36]={
    {0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},
    {1,1},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},
    {2,2},{2,1},{2,2},{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},
    {3,3},{3,1},{3,2},{3,3},{3,4},{3,5},{3,6},{3,7},{3,8},
  };
#define JASS_V {11,0,0,0,0,10,2,3,4}
  const unsigned short int jass_value[9] = JASS_V;
#define JASS_TRUMP_V {11,0,0,0,14,10,20,3,4}
  const unsigned short int jass_trump_value[9] = JASS_TRUMP_V;
#define JASS_BOCK_V {11,0,0,8,0,10,2,3,4}
  const unsigned short int jass_bock_value[9] = JASS_BOCK_V;
#define JASS_GEISS_V {0,11,0,8,0,10,2,3,4}
  const unsigned short int jass_geiss_value[9] = JASS_GEISS_V;
  const char *jass_card_name[9] = {"Ace","Six","Seven","Eight","Nine","Banner",
    "Under","Ober","King"};
  const char *jass_suit_name[4] = {"Sheilds","Flowers","Bells","Acorns"};
  const unsigned short int jass_all_value[6][4][9] = {
    { JASS_TRUMP_V, JASS_V, JASS_V, JASS_V },
    { JASS_V, JASS_TRUMP_V, JASS_V, JASS_V },
    { JASS_V, JASS_V, JASS_TRUMP_V, JASS_V },
    { JASS_V, JASS_V, JASS_V, JASS_TRUMP_V },
    { JASS_BOCK_V, JASS_BOCK_V, JASS_BOCK_V, JASS_BOCK_V },
    { JASS_GEISS_V, JASS_GEISS_V, JASS_GEISS_V, JASS_GEISS_V }
  };

  //check our work 2: work goes on summer vacation
  printf("In a game of jass with trump (Sheilds | Flowers | Bells | Acorns) | Bock | Geiss\n");
  for(i=0;i<36;i++){
    printf("  %-6s of %-7s is worth %8d%10d%8d%9d%8d%8d\n",
        jass_card_name[jass_deck[i].card],
        jass_suit_name[jass_deck[i].suit],
        jass_all_value[SHEILD_TRUMP][jass_deck[i].suit][jass_deck[i].card],
        jass_all_value[FLOWER_TRUMP][jass_deck[i].suit][jass_deck[i].card],
        jass_all_value[BELL_TRUMP][jass_deck[i].suit][jass_deck[i].card],
        jass_all_value[ACORN_TRUMP][jass_deck[i].suit][jass_deck[i].card],
        jass_all_value[BOCK][jass_deck[i].suit][jass_deck[i].card],
        jass_all_value[GEISS][jass_deck[i].suit][jass_deck[i].card]);
  }
  return 0;
}

La salida se ve así:

In a game of rummy:
  Ace   of Spades   is worth  1 points.
  Two   of Spades   is worth  2 points.
  Three of Spades   is worth  3 points.
  Four  of Spades   is worth  4 points.
  Five  of Spades   is worth  5 points.
...
  Nine  of Diamonds is worth  9 points.
  Ten   of Diamonds is worth 10 points.
  Jack  of Diamonds is worth 10 points.
  Queen of Diamonds is worth 10 points.
  King  of Diamonds is worth 10 points.
In a game of jass with trump (Sheilds | Flowers | Bells | Acorns) | Bock | Geiss
  Ace    of Sheilds is worth       11        11      11       11      11       0
  Six    of Sheilds is worth        0         0       0        0       0      11
  Seven  of Sheilds is worth        0         0       0        0       0       0
  Eight  of Sheilds is worth        0         0       0        0       8       8
  Nine   of Sheilds is worth       14         0       0        0       0       0
  Banner of Sheilds is worth       10        10      10       10      10      10
...
  Under  of Acorns  is worth        2         2       2       20       2       2
  Ober   of Acorns  is worth        3         3       3        3       3       3
  King   of Acorns  is worth        4         4       4        4       4       4

El blackjack es aburrido. Este código se compila.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top