3

我正在使用 CPP 制作二十一点游戏,但我一直坚持如何从我的 [4][13] 数组中随机选择一个元素而不重复它并且不打乱数组的顺序。在 VisualStudio 中工作。到目前为止,我只能找到有关如何使用一维数组执行此操作的答案。有人有建议吗?

4

8 回答 8

3

二维数组很容易被认为是一维数组。你只需要做一点数学。

如果您有一个适用于 52 元素一维数组的解决方案(一个随机排序的值 0-51 的新数组)。请执行下列操作:

  1. 生成你的随机元素,我们称之为 R(0 到 51 之间)。
  2. 现在,将该数字转换为您的二维阵列系统。(x,y 的形式)
    1. x = R / 13
    2. y = R % 13
于 2013-09-06T19:04:18.510 回答
2

用于std::random_shuffle从 中随机打乱一个向量(比如vector<int> v0-51。由于打乱random_shuffle了给定的向量,v现在是你随机打乱的向量。

v.back()返回向量中的最后一个元素。因此,以下代码k从向量中返回最后一个元素 ( ),然后将其删除。它还将其转换为 adouble以便您可以计算k/13.

double k = static_cast<double>(v.back());
v.pop_back();

现在,由于您的矩阵是 4x13,因此k第 th 元素(行主要)位于 rowfloor(k/13)和 column k%13

于 2013-09-06T20:19:36.080 回答
1

我建议你强烈考虑使用std::deque<T>容器。一个代表牌组本身的双端队列,然后您可以在发牌时将“牌”推出并弹出。

于 2013-09-06T19:45:37.133 回答
1

好吧,这样做的一种方法是向bool数组的元素添加一个字段,并且当数组的该元素被选中时,将其设置为 true。然后在未来的选择中,检查是否booltrue,如果是,则生成另一个随机元素。可能不是最有效的,但它很简单。

有了这个,您还可以轻松地创建一个方法来遍历数组并将所有 bool 字段设置为 false 以模拟随机播放。

于 2013-09-06T19:00:57.990 回答
1

附注:不要对数字 52 进行硬编码:您可能希望在同一个数组中洗牌多个牌组。在二十一点赌场的游戏中,经常在二十一点“鞋”中使用多副牌,特别是每张鞋有 4 副牌是很常见的。这对条件概率具有重要意义:正面朝上的牌和正面朝下的牌之间的相关性较小。你不想单独洗 52 张牌,你需要洗整个 N*52 张牌的鞋子。其他答案中提出的算法适用于 3-D 数组和 2-D 数组,只需稍作修改。

于 2013-09-06T20:45:18.487 回答
0

我一直喜欢的一种方法是获取 2d 数组,然后生成 2 个坐标进行交换。执行该n次数,然后您可以使用 some 遍历 2D 数组for loops

于 2013-09-06T19:23:00.700 回答
0

有一个简单的解决方案涉及使用素数。如果你在你的数组中取一个随机的初始索引(为简单起见,让它是一个一维数组),然后将该索引增加一个大于数组长度的素数,并且只取除以数组长度后的提示,你将获得一个随机非重复索引的序列。

像这样的东西:

#include <cstdlib>
#include <iostream>
#include <time.h>

const int Cols = 4;
const int Rows = 13;
const int N = Cols * Rows;

const int NPrimes = 12;
const int primes[NPrimes] = {59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107};

int prime = primes[0];
int index = 0;

void shuffle()
{
    srand(time(NULL)); // Random seed
    prime = primes[rand() % NPrimes]; // Get random prime number
    index = rand() % N; // Get random first index
}

// Compute next index in sequence
int nextIndex(int index)
{
    return (index + prime) % N;
}

int _tmain(int argc, _TCHAR* argv[])
{
    shuffle();

    for (int i = 0; i < N; i++) {
        int col = index / Rows;
        int row = index % Rows;
        std::cout << "[" << col << ", " << row << "] ";
        index = nextIndex(index);
    }
    std::cout << std::endl;
    return 0;
}

在 N 次迭代之后,该序列显然会重复自身。

于 2013-09-11T13:21:52.997 回答
0

我宁愿使用包含所有卡片的列表。如果您坚持使用 [4] 为套件 [13] 为数字的 2d 数组,则答案很简单,使甲板就位并且永不改变值,但是,使数组变量为布尔值。

生病写伪代码。

initialize cardsselected to zero

Choose Card
        Randomly select 2 numbers 1 will be 0-3 and the other 0-12. 
        If the array at [random suite][random number] is not false 
             choose it 
             increment cardsselected 
             set value to false
             return true
        else if cardsselected  equals 52 return false
        else 
            run chooseCard() 
            return true

这只是一个解决方案。它不是很优化,可能需要很长时间。

对其进行优化。

您可以保留您的二维数组以将卡片固定在适当的位置,从而生成随机数。要优化随机数生成,您可以创建一个随机数列表 1-52 并从中随机选择。然后删除从列表中选择的号码。

于 2013-09-06T19:29:16.747 回答