Question

J'essaie de créer un programme de blackjack simple. Malheureusement, j'ai tout de suite des problèmes pour générer un jeu de cartes.

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

Je sais que mon problème commence lorsque je tente d’attribuer la valeur "10" à un caractère. Évidemment, je ne pouvais pas le faire compiler, mais je suis sûr que, lorsque j'essaie d'attribuer les valeurs de la carte au jeu de cartes vectorielles, j'obtiens aussi une erreur puisque j'ai utilisé le type de variable 'char'. Savoir quel type de variable utiliser semble me tuer. En outre, serait 'deck.push_back (card [j] suit [i]);' être le bon code pour combiner la carte et la couleur, ou devez-vous mettre quelque chose entre la carte [j] et la couleur [i]? J'apprécierais que l'un de vous puisse me guider dans la bonne direction. En outre, cela fait partie d'un devoir, donc ne me donnez pas que des blocs de code entiers. Merci pour votre aide.

Était-ce utile?

La solution

Essayez de créer une classe de cartes avec une combinaison et une carte en tant que membre et définissez-la comme un type de vecteur. Comme

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

utiliser également des enums au lieu de caractères en costume et en carte rendrait les choses plus claires.

Autres conseils

Je pense que vous cherchez à utiliser une énumération. Cela rendra votre code plus clair et résoudra votre problème.

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

La façon dont vous modélisez cela dépend vraiment de ce que vous essayez de faire.

Créez-vous un jeu réel et les structures de données doivent-elles simplement prendre en charge le gameplay?

Si tel est le cas, je créerais une classe de cartes, avec un champ enum pour la suite et un type numérique (avec les valeurs 1 à 13) pour la valeur faciale.

D'autre part, si vous construisez une application d'analyse ou un lecteur d'intelligence artificielle, le modèle sera peut-être un peu différent.

Il y a quelques années, j'ai écrit un simulateur pour calculer les probabilités dans divers scénarios de Texas Holdem, et je voulais qu'il comprenne les chiffres très rapidement. J'ai commencé avec un modèle très simple (classe de carte, costume enum, etc.), mais après beaucoup de profilage et d'optimisation, je me suis retrouvé avec une représentation au niveau du bit.

Chaque carte avait une valeur de seize bits, avec les treize bits de poids fort représentant la valeur faciale, les deux bits de poids faible représentant la poursuite et le bit [2] en tant qu'indicateur spécial indiquant un as (utilisé uniquement les cas où l'as pourrait apparaître dans une suite de A2345).

Voici quelques exemples:

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

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

Vous pouvez imaginer comment, avec un design comme celui-ci, l'éclairage est rapide et vous permet de rechercher des paires, des trois-de-un-genre et des lignes droites (les bouffées de chaleur sont légèrement plus délicates).

Je ne vais pas entrer dans toutes les opérations particulières, mais il suffit de dire que ce type de modèle prend en charge des millions d'opérations par seconde ...

Bien sûr, gardez à l'esprit que je ne préconise pas en fait que vous utilisiez un tel design dans une implémentation de jeu simple. La seule raison pour laquelle je me suis retrouvé avec ce modèle est parce que je devais effectuer des simulations statistiques massives.

Alors réfléchissez bien à la façon dont vous voulez modéliser:

  • chaque carte
  • La main d'un joueur
  • L'ensemble du pont
  • L’état de la table, y compris toutes les mains des joueurs (y compris les joueurs qui ont divisé leur main initiale), peut-être un sabot à six ponts, la défausse, etc.

Le modèle d'application global et les objectifs de l'application en général détermineront dans une large mesure les types de structures de données les mieux adaptés.

Amusez-vous !!!

Utilisez "T" au lieu de 10.

Avez-vous essayé de remplacer J par 11, Q par 12 et K par 13? Ensuite, vous pouvez utiliser int egers plutôt que char acteurs. Remplacez 11-13 par la lettre appropriée plus tard.

Eh bien, tout d’abord, le pont [0] est un caractère, et pourtant vous essayez de fourrer & "2h &"; dans ça. (Pour le moment, nous ne tiendrons pas compte de la situation.)

En gros, vous devez faire de la plate-forme un vector<std::string>. Faites de la carte un tableau de const char * s et convertissez les éléments en chaîne.

puis utilisez:

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

Comme mentionné par d’autres, vous pouvez utiliser «T» pour dix, J, Q et K pour les figures. En ce qui concerne push_back .., étant donné que deck est un vecteur de caractères, vous ne pouvez transmettre qu’un seul caractère à push_back en tant qu’argument. Passer la valeur de la carte (1 ... 9, T, J, Q, K) et sa suite ne fonctionne pas.

Personnellement, je créerais une petite structure, pour représenter une carte, avec une propriété Value et une propriété Suite. Ensuite, vous pouvez faire de votre deck un vecteur de cartes.

Modifié: fixant le dernier mot puisque le vecteur (inférieur à) Carte (supérieur) a été rendu sous forme de vecteur (rien).

Cela pourrait ne pas compiler, mais voici l’approche que j’aimerais (et que j’ai utilisée). Vous allez vouloir utiliser ints pour représenter vos cartes, mais vous pouvez facilement le résumer en classe. Ce que je vais écrire pour vous.

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

Maintenant, il est très simple d’ajouter à cette classe tout ce que vous voulez. Pour générer la liste, c’est aussi simple que ci-dessous.

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

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

Avez-vous besoin de mélanger?

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

Pourquoi ne pas voir quelle est la valeur de la première carte?

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

Je n'ai pas compilé cela, mais ça devrait être proche.

Comme il s'agit d'un programme de blackjack, vous allez ajouter et comparer la valeur des cartes.

Cela étant le cas, vous pouvez économiser de la programmation supplémentaire en donnant aux cartes les valeurs int (1-13) au lieu des valeurs char .

Lorsque j'ai créé ma classe de jeu de cartes C ++ , J'ai rencontré quelques problèmes personnels. Tout d'abord, j'essayais de convertir ma classe de jeu de cartes PHP en C ++, avec un minimum de chance. J'ai décidé de m'asseoir et de simplement le mettre sur du papier. J'ai décidé de choisir une configuration orientée objet, principalement parce que je pense que c'est la plus facile à utiliser pour l'expansion. J'utilise les objets Carte et Deck . Par exemple, si vous souhaitez placer 10 decks dans la chaussure de votre jeu de blackjack, vous pourrait créer 10 jeux, ce qui serait assez simple, car j'ai décidé de tout rendre autonome. En fait, il est tellement autonome que pour créer votre chaussure, le code serait:

#include "AnubisCards.cpp"

int main() {

    Deck *shoe = new Deck(10);

}

Mais, pour des raisons de simplicité, cela n’est pas vraiment nécessaire dans les petits jeux où vous n’avez besoin que d’un seul jeu.

ANYWAY, comment J'ai créé le deck en créant un tableau de 52 objets Card. Les decks sont assez faciles, car vous savez que vous avez 4 costumes et 13 cartes dans chaque costume , vous savez également que vous avez 2,3,4,5 , 6,7,8,9,10, Jack, reine, roi, as dans chaque costume . Ceux-ci ne changeront jamais. J'ai donc utilisé deux boucles, l'une pour le costume et l'autre pour la valeur .

C'était à peu près comme ça:

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

Maintenant, vous remarquerez que dans chacune de ces boucles, j'utilise une valeur entière. La raison est simple, les cartes sont des nombres. 4 costumes. 13 valeurs. Même la valeur numérique dans le jeu de Blackjack. Valeur faciale, jusqu'à ce que vous frappiez les cartes de visage, qui sont la valeur numérique 10 jusqu'à ce que vous frappiez As, qui est la valeur numérique 1 ou 11. Tout est composé de chiffres. Vous pouvez donc utiliser ces chiffres non seulement pour attribuer la valeur de la carte, mais également la couleur de la carte et le numéro de la séquence numérique.

Une idée serait de stocker une carte dans la classe Card, avec les noms de caractère ou de chaîne des cartes, 1,2,3 ... constituant les index de chacune.

J'irais avec la suggestion de Ross d'utiliser des nombres entiers. La plupart des jeux de cartes impliquent des calculs mathématiques, ce qui en fait une meilleure représentation.

Convertissez en 'A' ou 'ACE' etc. à la sortie.

Comme il s’agit d’un devoir pour C ++, je suppose que vous êtes censé utiliser des classes. Sinon, utilisez les enums, et si c était C, utilisez une structure ou quelque chose comme ça.

Et pour certains jeux, mis à part la valeur en points, vous souhaitez stocker une sorte de classement pour la carte, qui dépend du mode de jeu actuel.

Je n'ai pas fait de plaine C depuis toujours, mais je veux dire quelque chose comme ceci:

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 sortie ressemble à:

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

Le Blackjack est ennuyeux. Ce code est compilé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top