在数组中将值声明为int



我正在尝试制作一副只使用数组而不使用类的牌。

如何为每张卡申报价值?尝试这样写,然后尝试给每个索引位置一个值,这似乎效率很低:

int deckOfcards[52]{ 1,2,3,4,5,6,7,8,9,10.......... };

然后,我将随机抽取2张牌,宣布获胜。在数组中可以使用rand((函数吗?

您可以创建一个循环来为您填充数组。。

int deckOfCards[52]{};
for (int i = 0; i < 52; i++)
{
deckOfCards[i] = i+1;
}

这对于这个特定的实例来说很好,但您可能需要使用循环中的std::size(deckOfCards),因为数组的大小可能并不总是已知的。

int deckOfCards[52]{};
for (int i = 0; i < std::size(deckOfCards); i++)
{
deckOfCards[i] = i+1;
}

请记住,数组索引从0开始,因此i将从0变为51。这就是为什么我们将deckOfCards[i]设置为等于i + 1

还有一种更好的方法可以将随机性引入卡片,使用std::shuffle。通过使用此函数,您可以获得自我解释。它还将介绍你正在寻找的一副牌。

#include <algorithm>
#include <array>
#include <random>
#include <iostream>
//-----------------------------------------------------------------------------
struct card_t
{
// each new instance gets a number which is then increased
// ++ at the end is important.
card_t() :
number{ g_card_number++ }   
{
}
std::size_t number;
static std::size_t g_card_number;
};
std::size_t card_t::g_card_number = 1;
//-----------------------------------------------------------------------------
int main()
{
// setup random generation c++ style
std::random_device rd;
std::default_random_engine random_generator{ rd() };
// create a deck of 52 cards
// this will call the constructor for each of them so they all get
// a unique number
std::array<card_t, 52> cards;
// shuffle the cards using the random generator
std::shuffle(cards.begin(), cards.end(), random_generator);
std::cout << "first card has number : " << cards[0].number << "n";
std::cout << "second card has number : " << cards[1].number << "n";
return 0;
}

要求是要模拟一副标准的扑克牌,注释表示要跟踪花色和价值。您还声称您只想使用一个整数数组来完成此操作。

这是可能的,但可能不是你真正想要的。更简单的解决方案已经作为答案发布,但我将尝试提供一个满足所述要求的答案。

我只想提前说,这可能是一个XY问题,这意味着你所说的问题不是你真正遇到的问题。您将在代码中看到同样多的内容。

要将两条信息唯一地编码到一个int中,您需要一种编码和解码的方法。最简单的方法是素数乘法。这是因为只有两个除数可以是素数。这也是许多现代密码学的基础。

你需要17个素数(4个套和13个值(。我选择"第一个"17,从3开始。它们是:3、5、7、11、13、17、19、23、29、31、37、41、43、47、53、59和61。

我将任意使用最后4个来代表诉讼。所以对我来说,球杆是47,黑桃是53,然后是红心,然后是钻石。

例如,三个俱乐部的价值为235(5*47(。三颗红心的值为295(5*59(。每张卡都是唯一可识别的,你可以知道价值和套装。

你可能只需要素数就可以了,但我知道,如果我们使用两个素数,它的唯一性是有保证的。

要随机挑选两张牌,您实际上需要洗牌整个牌组,只需查看阵列的前两个元素。这是因为,如果你试图只选择[0,51]范围内的两个随机数([]表示它包含在内(,那么你就有可能两次选择同一个数字,这在真实的套牌中是不可能的。

这是我试图保持尽可能简单的代码(即,在理智异常的情况下,尽量减少标准库的使用(

#include <algorithm>
#include <iostream>
#include <iterator>
#include <random>
void create_deck(int deck[], int deckSize) {
//          cl  sp  he  di
int suits[]{47, 53, 59, 61};
//           2  3  4   5   6   7   8   9  10   J   Q   K   A
int values[]{3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43};
int idx = 0;
for (std::size_t s = 0; s < sizeof(suits) / sizeof(suits[0]); ++s) {
for (std::size_t v = 0;
v < sizeof(values) / sizeof(values[0]) && idx < deckSize; ++v) {
deck[idx] = suits[s] * values[v];
++idx;
}
}
}
// Prints the name of the card and returns the value
int decode_card(int val) {
//          cl  sp  he  di
int suits[]{47, 53, 59, 61};
std::string suitNames[]{"clubs", "spades", "hearts", "diamonds"};
//           2  3  4   5   6   7   8   9  10   J   Q   K   A
int values[]{3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43};
std::string valueNames[]{"two",   "three", "four", "five", "six",
"seven", "eight", "nine", "ten",  "jack",
"queen", "king",  "ace"};
int realValues[]{2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
std::string suit;
std::string value;
for (std::size_t i = 0; i < sizeof(suits) / sizeof(suits[0]); ++i) {
if (val % suits[i] == 0) {
suit = suitNames[i];
val /= suits[i];
for (std::size_t v = 0; v < sizeof(values) / sizeof(values[0]); ++v) {
if (values[v] == val) {
value = valueNames[v];
std::cout << value << " of " << suit << ".n";
return realValues[v];
}
}
}
}
return -1;
}
int main() {
const int deckSize = 52;
int deck[deckSize];
create_deck(deck, deckSize);
std::shuffle(std::begin(deck), std::end(deck),
std::mt19937(std::random_device{}()));
int playerOneDraw = deck[0];
int playerTwoDraw = deck[1];
std::cout << "Player 1: ";
int playerOneValue = decode_card(playerOneDraw);
std::cout << "Player 2: ";
int playerTwoValue = decode_card(playerTwoDraw);
if (playerOneValue > playerTwoValue) {
std::cout << "Player 1 wins.n";
} else if (playerOneValue == playerTwoValue) {
std::cout << "It's a draw.n";
} else {
std::cout << "Player Two wins.n";
}
}

一次运行的输出:

Player 1: ace of spades.
Player 2: three of diamonds.
Player 1 wins.

我希望您马上看到,这是一个比其他使用类的解决方案更长、更复杂的代码。从长远来看,这使得这些代码更难维护。

这正是因为你给出的要求使任务变得比需要的更难。我选择不使用全局变量,因为你真的不应该这样做,但我也选择不使用namespace,因为我假设如果你不想要类,你可能也不想要namespace

最新更新