Проблема с Objective-C для цикла - PullRequest
1 голос
/ 18 августа 2011

У меня есть два метода, метод generateRandomCard вызывается внутри testMethod, где есть цикл for, который выполняется 100 раз. Таким образом, он отлично работает, но если я установлю ограничение цикла 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;
}

Ответы [ 3 ]

3 голосов
/ 18 августа 2011

Вы, вероятно, переполняете свой стек при рекурсивном вызове -generateRandomCard. Если вы генерируете карту, которая уже была выбрана, вы называете себя рекурсивно (и игнорируете результат, что является другой ошибкой). Таким образом, если ваш поток случайных чисел дал вам неудачную последовательность, которая продолжала возвращать карты, которые вы уже выбрали, то вы будете повторять бесконечно, пока стек не переполнится.

Измените алгоритм выбора карты, чтобы вместо выборки отклонения с возможностью бесконечной цикличности / рекурсии он использовал алгоритм с ограниченным временем выполнения, такой как Fisher-Yates shuffle .

1 голос
/ 18 августа 2011

Не уверен, может ли это каким-либо образом привести к аварии - это может быть не связано.Однако, похоже, у вас есть ошибка в способе, которым вы рекурсивно вызываете generateRandomCard, когда карта найдена в массивеreadyPickedCards.Вместо

[self generateRandomCard];

Я думаю, вы должны иметь

return [self generateRandomCard];
0 голосов
/ 18 августа 2011

У вас есть в -testMethod: [myGlobals.alreadyPickedCards removeAllObjects];

и у вас в -RandomCard:

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

Я точно не могу сделать ставку, но это похоже на ситуацию, когда вы удаляете все объекты в 1 цикле и получаете доступ к индексу с ограниченным доступом в другом цикле.

Если вы хотите так играть с массивами, я предлагаю вам сделать копии массивов и удалить элементы из этих скопированных массивов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...