C ++:使用两个1D字符串数组来模拟一副牌以表示套装和面以及一个用于牌组的2D阵列

时间:2014-10-27 18:27:35

标签: c++ arrays

编写一个程序来模拟一副52张扑克牌。

将您的牌组表示为2D数组,其值为 单元格是卡片中卡片的位置。

将西装和面孔的名称表示为 一系列字符串。

写一个算法来洗牌。

将西装和面孔的名称表示为 一系列字符串。

#include "stdafx.h"
#include <iostream>
#include <string>

using namespace std;

void main()
{
    const int ROWS = 4;
    string suits [ROWS] = 
{
    "Diamonds", "Clubs", "Hearts", "Spades"
};

const int COLS = 13;
string faces [COLS] = 
{
        "Ace", "Deuce", "Three", "Four", "Five", "Six",
    "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King"
};

int deck [ROWS][COLS] =
{
    {1,2,3,4,5,6,7,8,9,10,11,12,13},
    {14,15,16,17,18,19,20,21,22,23,24,25,26},
    {27,28,29,30,31,32,33,34,35,36,37,38,39},
    {40,41,42,43,44,45,46,47,48,49,50,51,52}
};

问题:我正在尝试将1d阵列连接到2d阵列。现在我写的时候: cout&lt;&lt;甲板[3] [5]&lt;&lt; ENDL; 输出答案是45.我如何使用1d数组填充2d数组,以便当我在cout deck [3] [5]时,我得到它说&#34; Six of Spades&#34;?

教师希望我实际做阵列的方式是通过专门为套装使用一维字符串数组和面部的一维字符串数组,最后是甲板的二维整数数组。我仍然无法弄清楚如何用其他两个数组中的字符串填充甲板的单元格。我知道我会使用某种类型的前向循环,但我一直遇到编译器的错误,无法用字符串数组填充整数数组。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

将您的牌组编号设为0而不是1。

face_index = deck[x][y] % COLS
suit_index = deck[x][y] / COLS

然后使用索引打印字符串以访问suit和faces数组。

答案 1 :(得分:0)

因为我真的很喜欢整体概念而且我认为你可能误解了实际的任务(不是100%肯定),我坐下来写了我自己的程序实现。我只是将它们打印到控制台而不是为卡片值构造字符串。

与所有示例一样,不要只是复制和粘贴。请尝试理解。还要考虑到你很可能无法使用这个例子1:1,因为我已经完成/解释了一些不同的东西。尽管如此,请随意使用它。 :)

可以将以下代码段组合在一起以创建独立程序。我已将它们分成几个部分,因此您只能查看您真正感兴趣的部分并使其更清晰一些。

首先,我的程序使用三个包含文件/标题:

// iostream for writing to the console
#include <iostream>

// cstdlib provides the random number generator (RNG)
#include <cstdlib>

// finally, ctime is used to initialize the RNG with the current time
#include <ctime>

与您自己的方法类似,我使用两个常量字符串文字数组。请注意,我只是在这里使用指针而不是std::string。最后,这可以节省一些开销,因为您也可以将这些开销分配给std::string个对象。除此之外,你的版本很好。另请注意,我使用的是缩写名称/标签,因此在没有包裹线的情况下打印所有内容会更容易。

// Suit constants
const char *suits[] = {"D", "C", "H", "S"};

// Face constants
const char *faces[] = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};

我的实际卡片组存储在一维数组中,因为这使得访问更容易在我看来。我稍后将使用一些数学诡计来计算2D偏移量,以便稍后确定卡片名称。

// Deck
// This array is populated below.
unsigned char deck[52];

该程序基本上应该打印卡片和随机播放卡片,因此我将为这些任务转发声明两个函数:

void shuffleDeck();
void printDeck();

现在让我们看看我的程序的main()入口点。我已经在代码中添加了注释,因为这应该更容易阅读,而不是阅读文本墙,然后有一堵代码。

int main(int argc, char **argv) {
    // First, let's put all the cards into the deck, one after the other:
    for (unsigned char c = 0; c < 52; ++c)
        deck[c] = c;

    // Let's print the deck as-is
    std::cout << "Initial deck:" << std::endl;
    printDeck();

    // Shuffle the deck
    shuffleDeck();

    // Print it again
    std::cout << "\nShuffled deck:" << std::endl;
    printDeck();
}

接下来是洗牌功能。这也很简单。我只需在我的deck数组中交换值来模拟混洗。标准RNG并不适用于加密问题等,但对于这个例子来说绰绰有余。

void shuffleDeck() {
    // There are multiple ways to do this.
    // We'll just go through the whole deck
    // and reposition/swap cards at random.

    // Initialize the RNG
    // Since the numbers aren't actually random at all,
    // we'll use the current time as a starting point.
    srand(static_cast<unsigned int>(time(NULL)));

    for (unsigned char c = 0; c < 52; ++c) {
        // Determine the "swap partner"
        // This RNG isn't perfect, but should be fine for us
        unsigned char i = rand() % 52;

        // Now swap them
        unsigned char t = deck[i];
        deck[i] = deck[c];
        deck[c] = t;
    }
}

我程序的最后一部分会将实际卡片打印到控制台。根据每个插槽中的卡号,程序确定与该索引关联的正确套装和面部并打印出来。

void printDeck() {
    // Access all cards of the deck
    for (unsigned char c = 0; c < 52; ++c) {
        // Get the card at index c:
        unsigned char card = deck[c];

        // Now it's going to get a bit complicated.
        // While the card array is 1D and the values are 1D as well,
        // it's still possible to interpret them as 2D: suits and faces.
        // To determine those, you're able to combine division and modulo
        // operations.

        // Determine the suit by (integer) division:
        // 0..12 -> suit 0, 13..25 -> suit 1, etc.
        // Integer division means the result is always rounded down
        unsigned char suit = card / 13;

        // Determine the face using the modulo operand (remainder of an division)
        // If you don't understand this, look it up!
        unsigned char face = card % 13;

        // Print the current card's suit, a separator, and it's face
        std::cout << suits[suit] << "-" << faces[face] << ", ";

        // Print a new line after every 13th card
        // c % 13 will be 12 for those
        if (c % 13 == 12)
            std::cout << std::endl;
    }
}

就是这样。请注意,我把这个例子放在一起就像10分钟一样。可能存在错误,错误或简单的坏风格。仅仅因为我做了这样或那样的事情,并不意味着它是完美的方式(实际上,RNG的使用是一个很好的例子,因为C ++ 11为此引入了一个全新的API)。

示例输出:

Initial deck:
D-A, D-2, D-3, D-4, D-5, D-6, D-7, D-8, D-9, D-10, D-J, D-Q, D-K,
C-A, C-2, C-3, C-4, C-5, C-6, C-7, C-8, C-9, C-10, C-J, C-Q, C-K,
H-A, H-2, H-3, H-4, H-5, H-6, H-7, H-8, H-9, H-10, H-J, H-Q, H-K,
S-A, S-2, S-3, S-4, S-5, S-6, S-7, S-8, S-9, S-10, S-J, S-Q, S-K,

Shuffled deck:
D-9, S-5, D-10, C-4, D-K, S-3, C-2, D-J, H-5, H-2, H-3, S-6, C-K,
C-Q, D-5, S-Q, C-J, S-2, D-7, S-9, H-7, C-10, C-9, S-J, S-8, C-8,
H-K, H-6, D-6, D-Q, D-3, D-2, H-J, S-10, H-8, H-4, D-8, C-3, D-4,
D-A, C-A, H-A, S-A, S-K, S-4, H-9, C-6, H-10, C-5, C-7, S-7, H-Q,