要求是您要模拟一副标准的扑克牌,而 cmets 表示您要跟踪花色和价值。您还声称您只想使用一个整数数组来执行此操作。
这是可能的,但可能不是你真正想要的。更简单的解决方案已作为答案发布,但我将尝试提供满足所述要求的答案。
我只是先说这可能是一个 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,然后是红桃,然后是方块。
因此,例如,3 个梅花的值为 235 (5 * 47)。红心 3 的值为 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。