0

我有 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];
}
} 

这是我的方法不起作用的场景之一的屏幕截图。 在此处输入图像描述

4

1 回答 1

4

在您的示例中,玩家可以使用四个图块。是否包含瓦片是二元选择(是或否),在这个例子中有 4 个这样的选择,因此有 2×2×2×2 = 2 4种可能的瓦片组合。通常,有 2 n 个组合,其中有n 个可用的图块。

检查总和为目标的组合的最简单方法是简单地枚举从 0 到 2 n的整数。对于每个整数i,以二进制形式写入i并将对应于二进制表示的 1 的图块的图块值相加。

我们将在本地数组中缓存 tile 值,以避免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. 您的getCombinations方法可能应该被调用checkCombinations(或类似的方法),因为它甚至不是吸气剂。你的getTileValue方法应该被调用tileValue

于 2013-04-13T18:44:12.000 回答