簡體   English   中英

Objective-C循環問題

[英]Problem with Objective-C for loop

我有兩個方法,在testMethod中調用generateRandomCard方法,其中有一個運行100次的for循環。 這樣它的工作完美,但是如果我將for循環限制設置為1000或任何其他大於100的數字,它就會崩潰。 你能看出什么問題嗎?

- (void)testMethod {

    Globals *myGlobals = [Globals sharedInstance];
    int rankOfFirst = 0;
    int rankOfSecond = 0;
    int playerOneWin = 0;
    int playerTwoWin = 0;
    int ties = 0;
    float firstPercent = 0;
    float secondPercent = 0;
    float tiePercent = 0;
    FiveEval *evaluator = [FiveEval theEvaluator];

    for (int i = 0; i < 100; i++) {
        short fPF = [self generateRandomCard];
        short fPS = [self generateRandomCard];
        short sPF = [self generateRandomCard];
        short sPS = [self generateRandomCard];
        short fFlop = [self generateRandomCard];
        short sFlop = [self generateRandomCard];
        short tFlop = [self generateRandomCard];
        short tur = [self generateRandomCard];
        short riv = [self generateRandomCard];

        rankOfFirst = [evaluator getRankOfSeven:fFlop 
                                               :sFlop 
                                               :tFlop
                                               :tur 
                                               :riv 
                                               :fPF 
                                               :fPS];

        rankOfSecond = [evaluator getRankOfSeven:fFlop 
                                             :sFlop 
                                             :tFlop 
                                             :tur 
                                             :riv 
                                             :sPF 
                                             :sPS];

        if (rankOfFirst > rankOfSecond) {
            playerOneWin++;
        } else if (rankOfSecond > rankOfFirst) {
            playerTwoWin++;
        } else {
            ties++;
        }

        [myGlobals.alreadyPickedCards removeAllObjects];
    }

    firstPercent = ((float)playerOneWin/(float)10000)*100;
    secondPercent = ((float)playerTwoWin/(float)10000)*100;
    tiePercent = ((float)ties/(float)10000)*100;

    NSLog(@"First Player Equity: %f", firstPercent);
    NSLog(@"Second Player Equity: %f", secondPercent);
    NSLog(@"Tie Equity: %f", tiePercent);
}


- (short)generateRandomCard {

    Globals *myGlobals = [Globals sharedInstance];
    short i = arc4random()%51;
    for (int j = 0; j < [myGlobals.alreadyPickedCards count]; j++) {
        if (i == [[myGlobals.alreadyPickedCards objectAtIndex:j] shortValue]) {
            [self generateRandomCard];
        }
    }
    [myGlobals.alreadyPickedCards addObject:[NSNumber numberWithShort:i]];
    return i;
}

您可能在遞歸調用-generateRandomCard 溢出堆棧 如果你生成一張已經被挑選過的卡片,你會遞歸地調用自己(並忽略結果,這是一個不同的錯誤)。 所以,如果你的隨機數流給你一個不幸的序列,讓你已經選擇了你已經選擇的牌,那么你將無限地遞歸,直到堆棧溢出。

更改您的卡片選擇算法,以便不使用具有無限循環/遞歸潛力的拒絕采樣 ,而是使用具有有界運行時間的算法,例如Fisher-Yates shuffle

不確定這是否會以任何方式導致崩潰 - 它可能是無關的。 但是,當在alreadyPickedCards數組中找到卡時,看起來你在遞歸調用generateRandomCard的方式上有一個錯誤。 代替

[self generateRandomCard];

我想你應該有

return [self generateRandomCard];

你有-testMethod: [myGlobals.alreadyPickedCards removeAllObjects];

和ingenerateRandomCard你有:

for (int j = 0; j < [myGlobals.alreadyPickedCards count]; j++) {
    if (i == [[myGlobals.alreadyPickedCards objectAtIndex:j] shortValue]) {
        [self generateRandomCard];
    }
}

我不能肯定地下注,但這看起來像是在一個循環中刪除AllObjects並在另一個循環中訪問一個out of bound索引的情況。

如果你想用數組這樣玩,我建議你制作數組的副本並從那些復制的數組中刪除項目。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM