Objective-C中的可变数组。如何更改/操作数组元素?

时间:2012-09-25 14:29:55

标签: objective-c arrays minesweeper

我正在尝试构建一个包含400个整数的数组(在20 x 20矩阵的上下文中处理)。将所有元素初始化为0,然后选择40个随机点以具有整数9(在扫雷上下文中指定为我的)。由于某种原因,我的程序挂起了:

[map replaceObjectAtIndex:mine_placement withObject:[NSNumber numberWithInt:9]];

在此之后,我有一个例程,它累积每个元素的地雷接近度,最后一个比特创建字符串对象以发送到控制台(日志)。我很乐意听到Objective-C专业人员关于我做错了什么,以及为什么这不正确输出。它构建良好,没有输出。我得到一些关于线程启动的消息。我是Obj-C的新手,所以对此事的任何想法都会很棒。

这是main中的内容:

@autoreleasepool
{

    int number_of_mines = 40;
    int mine_placement;

    // create map of 400 char elements
    NSMutableArray* map = [[NSMutableArray alloc] init];

    // char map[400];
    // build array with zeros everywhere
    for(int i = 0; i < 400; i++)
        [map addObject:[NSNumber numberWithInt:0]];

    // add randomly placed mines

    for(int i = 0; i < number_of_mines; i++) // loop for 40 mines
    {
        mine_placement = arc4random() % 400;
        while([map objectAtIndex: mine_placement] == [NSNumber numberWithInt:9]) // if we are already on a mine, repeat
            {
                mine_placement = arc4random() % 400;
            }
        [map replaceObjectAtIndex: mine_placement withObject:[NSNumber numberWithInt:9]];
    }

    // proximity accumulator (an iterative approach)
    for(int i = 0; i < 400; i++)
    {
        if([map objectAtIndex: i] != [NSNumber numberWithInt:9])
        {
            int accumulator = 0;

            // check top three neighbors
            if(i >= 20) // past first row
            {
                if(i % 20 != 0) // past first column
                    if([map objectAtIndex: (i-21)] == [NSNumber numberWithInt:9]) // top-left
                        accumulator++;

                if((i+1) % 20 != 0) // before last column
                    if([map objectAtIndex: (i-19)] == [NSNumber numberWithInt:9]) //top-right
                            accumulator++;

                if([map objectAtIndex: (i-20)] == [NSNumber numberWithInt:9]) // top
                    accumulator++;
            }

            // check bottom three neighbors
            if(i < 380) // before last row
            {
                if(i % 20 != 0) // past first column
                    if([map objectAtIndex: (i+19)] == [NSNumber numberWithInt:9]) // bottom-left
                        accumulator++;

                if((i+1) % 20 != 0) // before last column
                    if([map objectAtIndex: (i+21)] == [NSNumber numberWithInt:9]) // bottom-right
                            accumulator++;

                if([map objectAtIndex: (i+20)] == [NSNumber numberWithInt:9]) // bottom
                    accumulator++;
            }

            // left neighbor
            if(i % 20 != 0) // past first column
                if([map objectAtIndex: (i-1)] == [NSNumber numberWithInt:9]) // left
                    accumulator++;

            // right neighbor
            if((i+1) % 20 != 0) // before last column
                if([map objectAtIndex: (i+1)] == [NSNumber numberWithInt:9]) // right
                    accumulator++;

            if(accumulator > 0)
                [[map objectAtIndex: i] replaceObjectAtIndex: i withObject:[NSNumber numberWithInt:accumulator]];
        }
    }


    // output map of 400 char elements
    // build string rows

    NSMutableString* string_row = [[NSMutableString alloc] init];
    for(int row = 0; row < 20; row++)
    {
        for(int s = 0; s < 20; s++)
        {
            [string_row insertString:[map objectAtIndex: s] atIndex:s];
        }
        NSLog(@"%@", string_row);
        [string_row setString:@""]; // clear string_row for next row pass
    }
}

3 个答案:

答案 0 :(得分:1)

您的程序可能会挂起

while([map objectAtIndex: mine_placement] == [NSNumber numberWithInt:9])

您在此处比较指针(地址),但您想要比较值。试试这个:

while ([[map objectAtIndex:mine_placement] isEqualTo:[NSNumber numberWithInt:9]])

顺便说一下,如果您使用的是Xcode 4.5,现在可以使用@9代替[NSNumber numberWithInt:9]。如果您正在使用iOS 6 SDK进行编译,也可以使用map[mine_placement],因此它应该会缩短您的代码。

答案 1 :(得分:0)

您的计划也依赖于:

[[map objectAtIndex: i] replaceObjectAtIndex: i withObject:[NSNumber numberWithInt:accumulator]];

因为 [map objectAtIndex:i] 是NSNumber,它没有replaceObjectAtIndex方法。您可能应该检查数组的逻辑。这就是问题所在。

答案 2 :(得分:0)

我把你的代码放到了测试应用程序的applicationDidFinishLaunching方法中,并且我没有得到你所说的任何挂起 - 我不知道它为什么会出现与主要不同的行为。我在这一行上确实收到了错误:

[[map objectAtIndex: i] replaceObjectAtIndex: i withObject:[NSNumber numberWithInt:accumulator]];

我认为你希望这样:

[map replaceObjectAtIndex: i withObject:[NSNumber numberWithInt:accumulator]];

您创建可变字符串的代码的最后一部分也不起作用,因为您尝试将NSNumber插入字符串中。这可以修复如下:

[string_row insertString:[NSString stringWithFormat:@"%@",[map objectAtIndex: s]] atIndex:s];