【问题标题】:iphone Random number issueiphone随机数问题
【发布时间】:2010-11-14 10:26:24
【问题描述】:

我在数据库中有 52 条记录,获取这些记录并存储在一个数组中。现在我想将它们分配到四个数组中,每个数组只有 7 条记录,所以 4 个数组中只有 28 条记录,其余的将在新的临时数组中。实际上这是一个基于纸牌的游戏,有四个玩家,纸牌的分布是这样的:从第一个玩家开始 - 第一个玩家的第一张牌,第二个玩家的第二个,第三个玩家的第三个,第四个玩家的第四个。当每个玩家有 7 张牌时,此过程将重复。

那么我如何分配它们以使相同卡片的可能性最小化。我应该用随机数还是任何新的...请建议

谢谢,

雅利安

【问题讨论】:

    标签: iphone


    【解决方案1】:

    这是一个用于 NSMutableArray 的类别,用于对数组进行适当的洗牌。它在小型数组上做得不错,但请注意,使用的随机数函数mrand48() 不包含足够的随机性位来产生一副牌的所有可能洗牌,因此产生的洗牌有一些偏差。如果您的游戏纯粹是为了娱乐,这可能就足够了。如果没有,您可以将mrand48() 替换为更好的生成器。

    不要忘记在启动时使用 srand48() 播种随机数生成器。

    // --- NSMutableArray+Random.h ---
    #import <Foundation/Foundation.h>
    
    @interface NSMutableArray (Random)
      /// Shuffle a mutable array in place.  Uses a Fisher-Yates shuffle as described
      /// in http://en.wikipedia.org/wiki/Fisher-Yates_shuffle .
      - (void)shuffle;
    @end
    
    // --- NSMutableArray+Random.m
    #import "NSMutableArray+Random.h"
    
    /// Return a pseudo-random unsigned integer in the range 
    /// [0, exclusiveUpperBound) using the mrand48() function.
    /// Seed the random number state by calling srand48().
    /// See http://developer.apple.com/iphone/library/documentation/System/Conceptual/ManPages_iPhoneOS/man3/rand48.3.html
    static NSUInteger randomUIntegerFromZeroUpTo(NSUInteger exclusiveUpperBound) {
      NSUInteger const maxUInteger = 0xffffffff;
      NSUInteger largestMultipleOfMaxUInteger 
          = maxUInteger - (maxUInteger % exclusiveUpperBound);
      // discard random integers outside the range [0, largestMultipleOfMaxUnsignedInteger)
      // to eliminate modulo bias
      NSUInteger randomUInteger;
      do {
        randomUInteger = (NSUInteger) mrand48();
      } while (randomUInteger >= largestMultipleOfMaxUInteger);
      return randomUInteger % exclusiveUpperBound;
    }
    
    @implementation NSMutableArray (Random)
    - (void)shuffle {
      for (NSUInteger unshuffled = self.count; unshuffled > 1; --unshuffled) {
        NSUInteger index1 = unshuffled - 1;
        NSUInteger index2 = randomUIntegerFromZeroUpTo(unshuffled);
        [self exchangeObjectAtIndex:index1 withObjectAtIndex:index2];
      }
    }
    @end
    

    【讨论】:

      【解决方案2】:

      您应该查看this answer about Shuffle Bag

      当您分发卡片时,您会列出 52 张卡片并执行以下操作:

      listOfCards = { /* init, order not important */ }
      cardsToDistribute = []
      
      28.times do
          nextCard = listOfCards[random(0, listOfCards.size)]
      
          listOfCards.remove(nextCard) //side effect: decrement listOfCards.size by 1
      
          cardsToDistribute << nextCard
      end
      
      7.times do
         player1.cards << cardsToDistribute.removeFirst //side effect: decrement cardsToDistribute.size by 1
         player2.cards << cardsToDistribute.removeFirst
         player3.cards << cardsToDistribute.removeFirst
         player4.cards << cardsToDistribute.removeFirst
      end
      

      (抱歉,我不太了解 Objective-C,所以这是 Rubyist 伪代码;)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-07
        相关资源
        最近更新 更多