0

だから私は三目並べゲームに取り組んでいて、私の入力関数のために、プレーヤーが2次元配列に整数として格納するために行った動きを取得していました。入力は、位置へのポインタの1D配列への参照を使用して取得されます2D配列で。

しかし、私の問題は、ポインターを使用して多次元配列の正方形の値を何かに設定したように見える場合、何も起こらないことです。

入力関数は次のとおりです。

void Game::input(Board b){
int *spots[9]; // Possible spots for the input
bool validInput = false;
spots[0] = &b.board[2][0];
spots[1] = &b.board[2][1];
spots[2] = &b.board[2][2];
spots[3] = &b.board[1][0];
spots[4] = &b.board[1][1];
spots[5] = &b.board[1][2];
spots[6] = &b.board[0][0];
spots[7] = &b.board[0][1];
spots[8] = &b.board[0][2];
redo:
    cout << ">> " << endl;
    int input; // Input
    cin >> input; // Get the input
    validInput = cin;
    if(!validInput){
        cout << "Numbers only please!" << endl;
        cin.clear();
        while(cin.get() != '\n');
        goto redo;
    }
    if(input > 9 || input <= 0){
        cout << "Invalid move!" << endl;
        goto redo;
    }
    input--; // Subtract 1 for array location
    if(*spots[input] != 0){
        cout << "Square is already being used!" << endl;
        goto redo;
    }
    *spots[input] = 1;
}

ここで、数字 7 を入力するとします。b.board[0][0] を 1 に設定する必要があります。ただし、これは発生しないようです。後でユニットケースを実行すると、board[0][0] が 1 に設定されていないようで、配列に反映されません。ここでポインターについて何かを台無しにしていますか?

4

5 に答える 5

6

関数への引数は値で渡されるため、値で渡すと引数のコピーが作成されるため、関数に加えた変更は認識されません。代わりに、ポインターまたは参照による受け渡しを検討してください。

于 2012-07-27T20:41:33.673 に答える
3

ポインター/参照ではなく、Board値でインスタンスを渡しています。input()そのインスタンスに加えた変更は、 に渡されBoardた元のインスタンスには反映されません。Boardinput()

ところで、括弧とループはあなたの友達です:

void Game::input(Board &b)
{ 
    int* spots[9]; // Possible spots for the input 
    bool validInput; 
    int input;
    spots[0] = &(b.board[2][0]);
    spots[1] = &(b.board[2][1]); 
    spots[2] = &(b.board[2][2]); 
    spots[3] = &(b.board[1][0]); 
    spots[4] = &(b.board[1][1]); 
    spots[5] = &(b.board[1][2]); 
    spots[6] = &(b.board[0][0]); 
    spots[7] = &(b.board[0][1]); 
    spots[8] = &(b.board[0][2]); 
    do
    {
        std::cout << ">> " << std::endl; 
        std::cin >> input; // Get the input 
        validInput = std::cin; 
        if (!validInput)
        { 
            std::cout << "Numbers only please!" << std::endl; 
            std::cin.clear(); 
            while (std::cin.get() != '\n'); 
            continue; 
        } 
        if ((input > 9) || (input <= 0))
        { 
            std::cout << "Invalid move!" << std::endl; 
            continue; 
        } 
        --input; // Subtract 1 for array location 
        if (*spots[input] != 0)
        { 
            std::cout << "Square is already being used!" << std::endl; 
            continue; 
        } 
        *spots[input] = 1; 
        break;
    }
    while (true);
}
于 2012-07-27T20:46:13.127 に答える
2

メソッドのシグネチャを次のように変更します

void Game::input(Board& b) 

そうすれば、実際に行った変更が反映されていることがわかります。現時点では、メソッドを値で呼び出しています。

于 2012-07-27T20:43:23.713 に答える
2

あなたが試すことができるもう1つのことは、動きを選ぶためのちょっとした数学です. ユーザーが 7 を入力したとします。7/3 = 2、行です。7 % 3 = 1、列。したがって、7 は を指しboard[2][1]、これが正しい場所です。

于 2012-07-27T20:43:48.430 に答える
0

入力関数は次のように宣言されています。

void Game::input(Board b)

次のような別の関数からこれを呼び出すと、

Board tictactoe;
Game g;

g.input(tictactoe);

bのコピーを取得しますtictactoeinput()関数で行った変更は、 にはb反映されませんtictactoe

少なくとも 2 つの解決策があります。

1) 参照によってボードを渡す:

void Game::input(Board& b)

2) または、ボードへのポインターを渡します。

void Game::input(Board* b)

コードの再設計が必要な他のソリューションもあります。これら 2 つは、おそらく現在の問題を解決するための最も簡単で直接的な方法です。

また、インデックスを 1D 配列から 2D 配列にマップする方法は、私には少し奇妙に思えます。持っていれば、何が起こっているのかを追跡しやすくなると思います

spots[0] = &(b.board[0][0]); 
spots[1] = &(b.board[0][1]);  
spots[2] = &(b.board[0][2]);  
spots[3] = &(b.board[1][0]);  
spots[4] = &(b.board[1][1]);  
spots[5] = &(b.board[1][2]);  
spots[6] = &(b.board[2][0]);  
spots[7] = &(b.board[2][1]);  
spots[8] = &(b.board[2][2]);

実際、他の人が指摘したように、入力から行と列のインデックスを計算できるため、これは不要です。または、ユーザーに 1 つではなく 2 つの数字を入力するように求めることもできます。

于 2012-07-27T20:45:52.510 に答える