1

400 個の整数の配列を作成しようとしています (20 x 20 行列のコンテキストで処理されます)。すべての要素が 0 に初期化され、40 個のランダム スポットが整数 9 を持つように選択されます (掃海艇のコンテキストで地雷として指定されます)。何らかの理由で、私のプログラムは次の行でハングします。

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

これに続いて、各要素ごとに地雷の近接度を蓄積するルーチンがあり、最後のビットはコンソール (ログ) に送信する文字列オブジェクトを作成します。Objective-C の専門家から、私が間違っている点と、これが正しく出力されない理由について聞きたいです。それはうまくビルドされますが、出力はありません。スレッドが開始されているというメッセージが表示されます。私は Obj-C を初めて使用するので、この問題についての考えは素晴らしいでしょう。

メインの内容は次のとおりです。

@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
    }
}
4

3 に答える 3

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]ため、コードが少し短くなります。

于 2012-09-25T14:32:50.427 に答える
0

あなたのプログラムもハングします:

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

[map objectAtIndex: i]は NSNumber であるため、replaceObjectAtIndex メソッドはありません。おそらく、配列のロジックを確認する必要があります。それが問題です。

于 2012-09-25T14:39:43.470 に答える
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];
于 2012-09-25T15:45:16.690 に答える