我有两个方法,在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;
}
答案 0 :(得分:3)
在-generateRandomCard
的递归调用中,您可能overflowing your stack。如果你生成一张已经被挑选过的卡片,你会递归地调用自己(并忽略结果,这是一个不同的错误)。所以,如果你的随机数字流给你一个不幸的序列,让你已经选择了返回的牌,那么你将无限地递归,直到堆栈溢出。
更改您的卡片选择算法,以便不使用具有无限循环/递归潜力的rejection sampling,而是使用具有有界运行时间的算法,例如Fisher-Yates shuffle。
答案 1 :(得分:1)
不确定这是否会以任何方式导致崩溃 - 这可能是无关的。但是,当在alreadyPickedCards数组中找到卡时,看起来你在递归调用generateRandomCard的方式上有一个错误。而不是
[self generateRandomCard];
我认为你应该
return [self generateRandomCard];
答案 2 :(得分:0)
你有-testMethod:
[myGlobals.alreadyPickedCards removeAllObjects];
和in -generateRandomCard你有:
for (int j = 0; j < [myGlobals.alreadyPickedCards count]; j++) {
if (i == [[myGlobals.alreadyPickedCards objectAtIndex:j] shortValue]) {
[self generateRandomCard];
}
}
我不能肯定地下注,但这看起来像是在1循环中删除AllObjects并在另一个循环中访问out of bound索引的情况。
如果您想使用数组播放,我建议您复制数组并从复制的数组中删除项目。