我有9个标有1-9的图块,带有相应的值。图块1 = 1,图块6 = 6等。用户可以按下等于骰子总和的图块。当他们按下确认移动时,这些故事就不能再使用了。
我需要计算每种可能的数字组合,以检查用户是否可以再次使用。目前我正在计算它,但我确信必须有更好的方法。
allTiles
包含仍可用于计算的切片。
检查所有组合的最佳方法是什么?
- (void) getCombinations {
NSMutableArray *combinations = [[NSMutableArray alloc] init];
for (int i = 0; i < [allTiles count]; i++) {
for (int j = i + 1; j < [allTiles count]; j++) {
for (int k = i+2; k < [allTiles count]; k++) {
TileView *first = [allTiles objectAtIndex:i];
TileView *second = [allTiles objectAtIndex:j];
TileView *third = [allTiles objectAtIndex:k];
NSNumber *total = [NSNumber numberWithInt:first.getTileValue + second.getTileValue];
NSNumber *total2 = [NSNumber numberWithInt:
first.getTileValue +
second.getTileValue +
third.getTileValue];
[combinations addObject:[NSNumber numberWithInt:first.getTileValue]];
[combinations addObject:[NSNumber numberWithInt:second.getTileValue]];
[combinations addObject:[NSNumber numberWithInt:third.getTileValue]];
[combinations addObject:total];
[combinations addObject:total2];
}
}
}
if ([combinations containsObject:[NSNumber numberWithInt:[self diceTotal]]]) {
NSLog(@"STILL COMBINATION AVAILABLE");
}
else {
NSString *message = [NSString stringWithFormat:@"Your score: %i", player1Score];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@"No more combinations left."
message: message
delegate:self
cancelButtonTitle:@"Go to player2"
otherButtonTitles: nil];
[alert show];
[alert release];
}
}
以下是我的方法不起作用的方案之一的屏幕截图。
答案 0 :(得分:4)
在您的示例中,播放器有四个可用的磁贴。是否包括瓦片是二元选择(是或否),并且在该示例中有4个这样的选择,因此存在2×2×2×2 = 2 4 可能的组合瓷砖。一般来说,有2个 n 组合,其中有 n 个瓷砖。
检查与目标相加的组合的最简单方法是枚举0到2 n 中的整数。对于每个整数 i ,用二进制写 i 并将与二进制表示的1对应的图块的图块值相加。
我们会将切片值缓存在本地数组中,以避免反复发送tileValue
消息。
static int selectedNumbersSum(unsigned int selector, int const *numbers) {
int sum = 0;
for (int i = 0; selector != 0; i += 1, selector >>= 1) {
if (selector & 1) {
sum += numbers[i];
}
}
return sum;
}
static BOOL tilesCanMakeTarget(NSArray *tiles, int target) {
NSUInteger count = tiles.count;
int numbers[count];
for (int i = 0; i < count; ++i) {
numbers[i] = [tiles[i] tileValue];
}
for (unsigned int step = 0, maxStep = 1 << count; step < maxStep; ++step) {
if (selectedNumbersSum(step, numbers) == target)
return YES;
}
return NO;
}
- (void)checkForEndOfPlayer1Turn {
if (tilesCanMakeTarget(allTiles, self.diceTotal)) {
NSLog(@"STILL COMBINATION AVAILABLE");
} else {
NSString *message = [NSString stringWithFormat:@"Your score: %i",
player1Score];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@"No more combinations left."
message:message delegate:self cancelButtonTitle:@"Go to player 2"
otherButtonTitles:nil];
[alert show];
[alert release];
}
}
顺便说一下,我们通常不会使用get
启动我们的getter方法名称。您的getCombinations
方法应该被称为checkCombinations
(或类似的东西),因为它甚至不是一个吸气剂。您的getTileValue
方法应该被称为tileValue
。