Pergunta

Eu estou tentando fazer um programa simples blackjack. Infelizmente, eu estou tendo problemas logo de cara com a geração de um baralho 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;
}

Eu sei que meu problema começa comigo tentando atribuir o valor '10' para um char. Obviamente, eu não poderia chegar a este compilar mas tenho certeza que quando eu tentar atribuir os valores das cartas para o convés vector Eu também obterá um erro desde que eu usei 'char' variável do tipo. Sabendo que tipo de tipo de variável para uso parece estar me matando. Além disso, seria 'deck.push_back (cartão [j] terno [i]);' ser o código correto para combinar o cartão e terno, ou você tem que colocar algo entre o cartão de [j] e terno [i]? Eu apreciaria se algum de vocês poderia me levar na direção certa. Além disso, como uma pequena nota lado, isso é parte de uma lição de casa então por favor não me dê blocos inteiros de código. Obrigado por sua ajuda.

Foi útil?

Solução

Tente criar classe de cartão com o terno e um cartão de membro e defini-lo como um tipo de vetor. Como

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;
}

Também usando enums em vez de caracteres em terno e cartão faria mais claro.

Outras dicas

Eu acho que o que você está olhando para usar é uma enumeração. Isso fará com que o seu código mais claro e resolver o problema.

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

A maneira como você modelá-lo realmente depende do que você está tentando fazer.

Você está criando um jogo real, e as estruturas de dados só precisa apoiar o gameplay?

Se assim for, eu criar uma classe cartão, com um campo de enum para o terno e um tipo numérico (com valores 1 - 13). Para o valor de face

Por outro lado, se você está construindo uma aplicação de análise ou um jogador AI, então o modelo pode ser um pouco diferente.

Alguns anos atrás, eu escrevi um simulador para calcular probabilidades em vários cenários de Texas Hold'em, e eu queria que crunch números muito rapidamente. Eu comecei com um modelo muito simples (classe cartão, enum terno, etc), mas depois de um monte de profiling e otimização, acabei com uma representação bit a bit.

Cada cartão era um valor dezasseis bits, com os treze bits de ordem superior que representam o valor de cara, os dois bits de baixa ordem que representam o terno, e com pouco [2] como um sinalizador especial indicando um ace (utilizado apenas em casos em que o ace podem aparecer em uma linha reta A2345).

Aqui estão alguns exemplos:

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

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

Você pode imaginar como, com um projeto como este, está iluminando rápido para procurar pares, trios-de-um-tipo, e retas (afrontamentos são um pouco mais complicado).

Eu não vou entrar em todas as operações específicas, mas basta dizer que este tipo de suportes modelo milhões de operações por segundo ...

Claro, lembre-se, eu não estou realmente defendendo que você usar um projeto como este em uma implementação simples jogo. A única razão pela qual eu acabei com este projeto é porque eu precisava para realizar simulações estatísticas maciças.

Então, pense com cuidado sobre como você deseja modelo:

  • Cada cartão
  • mão de um jogador
  • Toda a plataforma
  • O estado da mesa ... incluindo todas as mãos do jogador (incluindo os jogadores que têm dividido a sua mão inicial), talvez um sapato de seis baralhos, a pilha de descarte, etc

O modelo de aplicação geral e os objetivos da aplicação em geral, irá determinar em grande medida os tipos de estruturas de dados que vai ser mais adequada.

Divirta-se !!!

Use 'T' em vez de 10.

Você já tentou substituir J com 11, Q com 12 e K com 13? Em seguida, você poderia usar integers em vez de characters. Substitua 11-13 com a letra apropriada mais tarde.

Bem, em primeiro lugar, deck [0] é um char, ainda que você está tentando, de coisas "2h" para ele. (Por enquanto, vamos ignorar que a forma como você está fazendo o que está errado.)

Basicamente, você vai precisar fazer deck de um vector<std::string>. cartão de fazer uma matriz de char const * s, e converter os elementos para string.

Em seguida, use:

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

Como mencionado por outros, você pode usar 'T' para dez, J, Q e K para as figuras. Tanto quanto push_back .. desde deck é um vetor de caracteres, você pode passar apenas um char para push_back como argumento. Passando tanto o valor do cartão (1 ... 9, T, J, Q, K) e seu conjunto não funciona.

Eu, pessoalmente, iria criar um pouco struct, para representar um cartão, com um valor e uma propriedade Suite. Então, você pode fazer seu deck um vetor de cartões.

Editado:. Fixação última palavra desde vetor (menos-que) Cartão (maior que) foi processado como vector (nada)

Isto pode não compilar, mas aqui é a abordagem que eu faria (e ter usado). Você vai querer usar ints para representar seus cartões, mas você pode facilmente o abstrato esta em uma classe. Que eu vou escrever para você.

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;
}

Agora é muito simples de adicionar a esta classe para obter tudo o que você quer fora dele. Para gerar a lista é tão simples como abaixo.

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

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

Você precisa para baralhar?

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

Que tal ver o que o valor do primeiro cartão é?

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

Eu não compilar nada disso, mas ele deve estar perto.

Uma vez que este é um programa de blackjack, você estará adicionando e comparar o valor das cartas.

Sendo esse o caso, você pode salvar a si mesmo um pouco de programação e dor adicional, dando as cartas int valores (1-13) em vez de caractere valores.

Quando eu criei meu C ++ plataforma de cartões de classe , corri em alguns problemas da minha própria. Em primeiro lugar eu estava tentando converter meu PHP baralho de cartas classe para C ++, com o mínimo de sorte. Eu decidi sentar e basta colocá-lo no papel. Eu decidi ir com uma configuração orientada a objetos, principalmente porque eu sinto que é o mais fácil de usar para a expansão. Eu uso os objetos Cartão e plataforma , por isso, por exemplo, se você quiser colocar 10 plataformas para o Shoe de seu jogo blackjack, você poderia criar 10 plataformas, o que seria suficiente simples, porque eu decidi fazer tudo auto-contido. Na verdade, é tão auto-suficientes, para criar seu sapato o código seria:

#include "AnubisCards.cpp"

int main() {

    Deck *shoe = new Deck(10);

}

Mas, que era para simplificar, não exatamente necessário em jogos menores, onde você só precisa de uma única plataforma.

Enfim, como I gerou o deck foi criando uma matriz de 52 objetos de cartão. Decks são fáceis o suficiente, porque você sabe que você tem 4 ternos e 13 cartas em cada naipe , você também sabe que você tem 2,3,4,5 , 6,7,8,9,10, Jack, Rainha, Rei, Ás em cada naipe . Aqueles nunca vai mudar. Então eu usei dois loops, um para o Terno e outro para o Valor .

Foi algo como isto:

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

Agora, você vai notar em cada um desses loops, eu uso um valor inteiro. A razão é simples, cartões são números. 4 naipes. 13 valores. Mesmo o valor numérico no jogo de Blackjack. valor de face, até que você bata cartões de cara, que são valor numérico 10 até chegar Ace que é valor numérico 1 ou 11. Tudo é número. Assim você pode usar esses números para não só atribuir o valor do cartão, mas o naipe da carta, e o número na seqüência numérica.

Uma idéia seria armazenar um mapa na classe Card, com o caractere ou nomes de corda dos cartões, com 1,2,3 ... sendo os índices para cada um.

Eu iria com a sugestão de Ross para inteiros de uso. A maioria dos jogos de cartas irá envolver alguns pedaços de matemática de modo que é uma representação melhor.

Converter para 'A' ou 'Ace', etc. na saída.

Uma vez que esta é a lição de casa para C ++ Eu estou indo para adivinhar que se espera para usar classes. Caso contrário, use os enums, e se isso fosse C usar um struct ou algo assim.

E para alguns jogos, além de valor de pontos, que você gostaria de armazenar algum tipo de classificação para o cartão, que dependem do modo atual de jogo.

Eu não fiz C simples para sempre, mas eu quero dizer algo como isto:

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;
}

aparência saída como:

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

Blackjack é chato. Este código faz compilação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top