我正在尝试在我的应用中随机播放一副牌,我使用以下代码。这会使甲板充分随机化吗?我几乎肯定会只是想要另一种意见。谢谢!
for (int i = 0; i < 40000; i++) {
int randomInt1 = arc4random() % [deck.cards count];
int randomInt2 = arc4random() % [deck.cards count];
[deck.cards exchangeObjectAtIndex:randomInt1 withObjectAtIndex:randomInt2];
编辑:如果有人想知道或将来会遇到这个问题。这就是我用去洗牌的方式,它是Fisher-Yates算法的一个实现。我从下面提到的@MartinR帖子中找到了它,可以在这里找到:What's the Best Way to Shuffle an NSMutableArray?
NSUInteger count = [deck.cards count];
for (uint i = 0; i < count; ++i)
{
// Select a random element between i and end of array to swap with.
int nElements = count - i;
int n = arc4random_uniform(nElements) + i;
[deck.cards exchangeObjectAtIndex:i withObjectAtIndex:n];
}
答案 0 :(得分:7)
如果[deck.cards count]&lt;你的代码应该工作得相当好40000但是追随更好
for (int i = [deck.cards count] - 1; i > 0 ; i--) {
int randomInt1 = arc4random_uniform(i + 1);
[deck.cards exchangeObjectAtIndex:randomInt1 withObjectAtIndex:i];
}
来自docs:
arc4random_uniform()将返回均匀分布的随机数 小于upper_bound。 arc4random_uniform()建议使用像``arc4random()%upper_bound''这样的结构,因为它避免了 当上限不是2的幂时,“模偏”。
答案 1 :(得分:3)
这是正确实施的Fisher-Yates算法。是的,它会使你的阵列充分随机化,我已经多次使用它并且它非常好!
NSUInteger count = [deck.cards count];
if (count > 0) {
for (NSUInteger i = count - 1; i > 0 ; --i) {
[deck.cards exchangeObjectAtIndex:i
withObjectAtIndex:arc4random_uniform(i + 1)];
}
}
答案 2 :(得分:0)
根据甲板的实现方式,您可以简单地使用Collections.sort()
,也可以使用ArrayList,前提是您的实现类似于以下内容
ArrayList<Integer> originalDeck = new ArrayList<Integer>();
ArrayList<Integer> randomDeck = new ArrayList<Integer>();
//Initalize array
for (int i = 0; i < 52; i++) {
originalDeck.add(i, i);
}
//Smart Implementation
Collections.shuffle(originalDeck);
Collections.sort(originalDeck);
//Long Implementation
int i=0, max = 0;
while (originalDeck.size() != 0) {
max = originalDeck.size();
i = (int) (Math.random() * max); // goes from 0 to size-1 so always in bounds
randomDeck.add(originalDeck.remove(i));
}