Vla*_*mir 0 c++ random algorithm numbers
我正在为纸牌游戏写一个程序.可以有几个游戏玩家(比如,从2到7).一副牌组由54张牌组成.我需要随机向玩家分发/发牌.
我们可以将54张牌的牌组视为54个元素的char数组.让我们假设在某个游戏中,每个玩家必须获得6张牌.玩家的数量是2.因此,有必要生成两个阵列,每个阵列由从54个元素的"大"数组中选择的6个元素组成.而且,在这两个生成的数组中,不应该有共享/重复元素.
我尝试了一种递归算法来获得从0到(m-1)的m个唯一随机数序列.
X(n + 1)=(a*X(n)+ c)mod m
您需要设置参数:
这是此算法的代码.如您所见,参数a,c,m和X(0)满足上述条件.
int a = 13,
c = 11,
m = 54, // because the total number of cards is 54
x0 = 1;
int x[100];
x[0] = x0;
cout << x[0] << " ";
for (int i = 1; i < m; i++)
{
x[i] = (a * x[i - 1] + c) % m;
cout << x[i] << " ";
}
Run Code Online (Sandbox Code Playgroud)
其结果是:1 24 53 52 39 32 49 0 11 46 15 44 43 30 23 40 45 2 37 6 35 34 21 14 31 36 47 28 51 26 25 12 5 22 27 38 19 42 17 16 3 50 13 18 29 10 33 8 7 48 41 4 9 20.你认为它是随机的吗?
你能对这个算法说些什么?一般来说,每个玩家随机分配卡片的想法应该是什么?
你看,如果我将这个算法集成到我的程序中,它将处理每次启动程序时上面显示的相同序列的卡(因为参数不会改变).所以我需要在我的程序启动之间更改a,m,c和X(0).然后我会遇到另一个问题:如何自动设置这些参数(也是随机设置),以便它们满足必要条件(参见上面的项目符号列表).
在我看来,你正在制造一个不必要的复杂系统.
一种更简单的方法是创建一个包含所有元素的数组,将其随机化,然后一次删除一个元素.
一种简单而有效的改组方式是使用Fisher-Yates shuffle:
//Initialize an array/vector/etc. with all the possible values
for (int i = NUMBER_OF_ELEMENTS-1; i >= 0; i--)
{
//Pick a random integer j between 0 and i (inclusive)
//Swap elements i and j
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以遍历洗牌数组,每次需要新卡时选择下一个元素.
int pos = 0; //The position of the next card in the deck
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < NUMBER_OF_PLAYERS; j++)
{
player[j].addCard(deck[pos++])
}
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,您可能希望将其中的一部分包装到类中,但为了简洁起见,我将其留下了.