C++ 生成一副纸牌

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/234388/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:56:07  来源:igfitidea点击:

Generating a Deck of Cards

c++

提问by Ian Burris

I'm trying to make a simple blackHyman program. Sadly, I'm having problems right off the bat with generating a deck of cards.

我正在尝试制作一个简单的二十一点程序。可悲的是,我在生成一副纸牌时遇到了问题。

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

I know my problem begins with me trying to assign the value '10' to a char. Obviously I couldn't get this to compile but I'm sure when I try to assign the card values to the vector deck I'll also get an error since I used variable type 'char'. Knowing what kind of variable type to use seems to be killing me. Also, would 'deck.push_back(card[j] suit[i]);' be the correct code to combine the card and suit, or do you have to put something between card[j] and suit[i]? I'd appreciate it if any of you could lead me in the right direction. Also as a little side note, this is part of a homework assignment so please don't just give me entire blocks of code. Thanks for your help.

我知道我的问题始于我试图将值“10”分配给一个字符。显然我无法编译它,但我确信当我尝试将卡片值分配给向量组时,我也会收到错误,因为我使用了变量类型“char”。知道使用什么样的变量类型似乎让我很沮丧。另外,'deck.push_back(card[j]suit[i]);' 是组合卡片和花色的正确代码,还是必须在卡片 [j] 和花色 [i] 之间放一些东西?如果你们中的任何人能引导我走向正确的方向,我将不胜感激。还有一点要注意的是,这是家庭作业的一部分,所以请不要只给我完整的代码块。谢谢你的帮助。

回答by Kevin

I think what you are looking to use is an enumeration. It will make your code clearer and resolve your problem.

我认为您要使用的是枚举。它将使您的代码更清晰并解决您的问题。

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

回答by JtR

Try to create class of Card with suit and card as a member and set it as a type of vector. Like

尝试创建以花色和卡片为成员的卡片类,并将其设置为向量类型。喜欢

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

also using enums instead of chars in suit and card would make it clearer.

在花色和卡片中使用枚举而不是字符会使它更清晰。

回答by benjismith

The way you model it really depends on what you're trying to do.

您对其建模的方式实际上取决于您要尝试做什么。

Are you creating an actual game, and the data structures just need to support the gameplay?

您是否正在创建一个真正的游戏,而数据结构只需要支持游戏玩法?

If so, I'd create a card class, with an enum field for the suit and a numeric type (with values 1 - 13) for the face value.

如果是这样,我将创建一个卡片类,其中包含一个用于西装的枚举字段和一个用于面值的数字类型(值为 1 - 13)。

On the other hand, if you're building an analysis application or an AI player, then the model might be a little bit different.

另一方面,如果您正在构建分析应用程序或 AI 播放器,那么模型可能会有所不同。

A few years ago, I wrote a simulator to calculate probabilities in various Texas Holdem scenarios, and I wanted it to crunch numbers REALLY quickly. I started out with a very straightforward model (card class, suit enum, etc) but after a lot of profiling and optimization, I ended up with a bitwise representation.

几年前,我编写了一个模拟器来计算各种德州扑克场景中的概率,我希望它能够非常快速地处理数字。我从一个非常简单的模型(卡片类、套装枚举等)开始,但经过大量的分析和优化,我最终得到了一个按位表示。

Each card was a sixteen-bit value, with the thirteen high-order bits representing the face value, the two low order bits representing the suit, and with bit[2] as a special flag indicating an ace (used only in cases where the ace might appear in an A2345 straight).

每张牌都是一个 16 位的值,高 13 位代表面值,低 2 位代表花色,位 [2] 作为特殊标志表示 A(仅在以下情况下使用) ace 可能出现在 A2345 顺子中)。

Here are a few examples:

这里有一些例子:

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

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

You can imagine how, with a design like this, it's lighting fast to look for pairs, threes-of-a-kind, and straights (flushes are slightly more tricky).

您可以想象,在这样的设计中,寻找对子、同类三分和顺子(同花稍微有点棘手)是如何快速发光的。

I won't go into all the particular operations, but suffice it to say that this kind of model supports millions of operations per second...

我不会介绍所有特定的操作,但可以说这种模型每秒支持数百万次操作......

Of course, keep in mind, I'm not actually advocating that you use a design like this in a straightforward game implementation. The only reason I ended up with this design is because I needed to conduct massive statistical simulations.

当然,请记住,我实际上并不是提倡您在简单的游戏实现中使用这样的设计。我最终采用这种设计的唯一原因是因为我需要进行大量的统计模拟。

So think carefully about how you want to model:

因此,请仔细考虑您要如何建模:

  • Each card
  • A player's hand
  • The entire deck
  • The state of the table... including all player hands (including players who have split their initial hand), maybe a six-deck shoe, the discard pile, etc
  • 每张卡
  • 一个玩家的手
  • 整个甲板
  • 牌桌的状态……包括所有玩家的手牌(包括分手的玩家),可能是六副牌的鞋子,弃牌堆等

The overall application model, and the goals of the application in general, will determine to a large extent the types of data structures that'll be most appropriate.

整个应用程序模型以及应用程序的总体目标将在很大程度上决定最合适的数据结构类型。

Have fun!!!

玩得开心!!!

回答by Dave

Use 'T' instead of 10.

使用“T”而不是 10。

回答by Ross

Have you tried replacing J with 11, Q with 12 and K with 13? Then you could use integers rather than characters. Replace 11-13 with the appropriate letter later on.

你有没有试过用 11 代替 J,用 12 代替 Q,用 13 代替 K?然后你可以使用integers 而不是acters char。稍后用适当的字母替换 11-13。

回答by James Curran

Well, first of all, deck[0] is one char, yet you are trying, to stuff "2h" into it. (for the moment, we'll ignore that how you are doing that is wrong.)

好吧,首先,deck[0] 是一个字符,但您正在尝试将“2h”塞入其中。(目前,我们将忽略您的做法是错误的。)

Basically, you'll need to make deck a vector<std::string>. Make card an array of const char*s, and convert the elements to string.

基本上,你需要让deck a vector<std::string>. 使 card 成为 const char*s 的数组,并将元素转换为字符串。

then use:

然后使用:

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

回答by James Curran

This might not compile, but here is the approach I would (and have used). You're going to want to use ints to represent your cards, but you can easily abstract this in a class. Which I'll write for you.

这可能无法编译,但这是我会(并已使用)的方法。您将要使用整数来表示您的卡片,但您可以轻松地在类中抽象它。我会为你写的。

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

Now its very simple to add to this class to get everything you want out of it. To generate the list its as simple as below.

现在很容易添加到这个类中以获得你想要的一切。生成列表就像下面一样简单。

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

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

Do you need to shuffle?

你需要洗牌吗?

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

How about see what the value of the first card is?

看看第一张卡的价值如何?

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

I didn't compile any of this, but it should be close.

我没有编译任何这些,但它应该很接近。

回答by FOR

As mentioned by others, you can use 'T' for ten, J, Q, and K for the figures. As far as push_back.. since deck is a vector of chars, you can pass only one char to push_back as argument. Passing both the card value (1...9, T, J, Q, K) and its suite doesn't work.

正如其他人所提到的,您可以使用“T”表示十,J、Q 和 K 表示数字。至于push_back .. 因为deck 是一个字符向量,你只能将一个字符作为参数传递给push_back。传递卡值(1...9、T、J、Q、K)及其套件不起作用。

I personally would create a little struct, to represent a Card, with a Value and a Suite property. Then, you can make your deck a vector of Cards .

我个人会创建一个小结构来表示一张卡片,它带有一个 Value 和一个 Suite 属性。然后,您可以使您的牌组成为 Cards 的向量。

Edited: fixing last word since vector (less-than) Card (greater-than) was rendered as vector (nothing).

编辑:修复最后一个词,因为矢量(小于)卡(大于)被渲染为矢量(无)。

回答by Drek

Since this is a blackHyman program, you will be adding and comparing the value of the cards.

由于这是一个二十一点程序,您将添加和比较卡片的价值。

That being the case, you can save yourself some additional programming and pain by giving the cards intvalues (1-13) instead of charvalues.

在这种情况下,您可以通过为卡片提供int值 (1-13) 而不是char值来节省一些额外的编程和痛苦。

回答by Travis Weston

When I created my C++ Deck of cards class, I ran into a few problems of my own. First off I was trying to convert my PHP deck of cards classto C++, with minimal luck. I decided to sit down and just put it on paper. I decided to go with an Object Oriented setup, mostly because I feel it's the easiest to use for expansion. I use the objects Cardand Deck, so, for instance, if you want to put 10 decks into the Shoeof your blackHyman game, you could create 10 decks, which would be simple enough, because I decided to make everything self contained. In fact, it's so self contained, to create your shoe the code would be:

当我创建我的 C++ Deck of card 类时,我遇到了一些我自己的问题。首先,我试图将我的 PHP 纸牌类转换为 C++,但运气不佳。我决定坐下来,把它写在纸上。我决定使用面向对象的设置,主要是因为我觉得它最容易用于扩展。我使用对象CardDeck,因此,例如,如果您想将 10 副套牌放入21 点游戏的Shoe中,您可以创建 10 副套牌,这很简单,因为我决定让所有内容都独立。事实上,它是如此独立,创建你的鞋子的代码是:

#include "AnubisCards.cpp"

int main() {

    Deck *shoe = new Deck(10);

}

But, that was for simplicity, not exactly necessary in smaller games where you only need a single deck.

但是,这只是为了简单起见,在您只需要一副套牌的小型游戏中并不完全必要。

ANYWAY, How Igenerated the deck was by creating an array of 52 Card objects. Decks are easy enough, because you know that you have 4 Suitsand 13 Cards in each suit, you also know that you have 2,3,4,5,6,7,8,9,10,Hyman,Queen,King,Ace in every single suit. Those will never change. So I used two loops, one for the Suitand the other for the Value.

无论如何,是通过创建一个包含 52 个 Card 对象的数组来生成牌组的。套牌很容易,因为你知道你有4套花色13 张卡片,你也知道你有2、3、4、5、6、7、8、9、10,Hyman,皇后,国王,每套西装的王牌。这些永远不会改变。所以我使用了两个循环,一个用于Suit,另一个用于Value

It was something like this:

它是这样的:

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

Now, you'll notice in every single one of those loops, I use an integer value. The reason is simple, cards are numbers. 4 suits. 13 values. Even the numerical value in the game of BlackHyman. Face value, until you hit Face cards, which are numerical value 10 until you hit Ace which is numerical value 1 or 11. Everything is numbers. So you can use those numbers to not only assign the value of the card, but the suit of the card, and the number in the numerical sequence.

现在,您会注意到在这些循环中的每一个循环中,我都使用了一个整数值。原因很简单,卡片就是数字。4套。13 个值。甚至是二十一点游戏中的数值。面值,直到您击中数值为 10 的面牌,直到您击中数值为 1 或 11 的 A 为止。一切都是数字。因此,您不仅可以使用这些数字来分配卡片的价值,还可以使用卡片的花色以及数字序列中的数字。

One idea would be to store a map in the Card class, with the char or String names of the cards, with 1,2,3... being the indexes for each.

一个想法是在 Card 类中存储一张地图,使用卡片的字符或字符串名称,其中 1,2,3... 是每个的索引。