2012-07-27 87 views
0

所以我工作的一个井字棋游戏,我输入功能我得到的球员作出存储在一个二维数组的整数的举动,输入使用参考指针的一维数组得到到二维数组中的位置。使用指向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

你应该养成使用遍历'goto'的习惯。此外,你没有通过参考通过董事会,你传递了一些随机副本。 – chris 2012-07-27 20:38:56

+1

您可以选择使用矢量,地图还是for-loop? – andre 2012-07-27 20:41:04

+0

不要紧,这已经解决了,不敢相信我错过了参考。 – Annabelle 2012-07-27 20:41:38

回答

6

的参数给你的函数是按值,因此,你做的任何变化都传递不承认,因为按值传递创建参数的副本。考虑通过指针或引用传递。

+0

不能相信我错过了:p非常感谢!公认。 (在5分钟内) – Annabelle 2012-07-27 20:42:25

+0

至少它很容易修复! – mathematician1975 2012-07-27 20:51:08

2

你的方法的签名更改为

void Game::input(Board& b) 

这样你会真正看到你做出它反映的变化。 目前您正在按值调用该方法。

+0

感谢您的代码,它解决了我的问题。 – Annabelle 2012-07-27 20:43:57

2

你可以尝试的另一件事是一些数学挑举动。假设用户输入7. 7/3 = 2,该行。 7%3 = 1,列。所以7指的是board[2][1],这是正确的位置。

+0

试过了,没有工作,谢谢你尝试。哦,并且board [0] [0]是#7,因为数组指针从输入减1。 – Annabelle 2012-07-27 20:44:14

+0

+1为优雅 – 2012-07-27 20:49:48

+0

其实,我会试试这个,因为它看起来更容易和更优雅。 – Annabelle 2012-07-27 20:55:11

0

你输入函数声明为:

void Game::input(Board b) 

当你从另一个函数调用此方法,如

Board tictactoe; 
Game g; 

g.input(tictactoe); 

b得到了副本tictactoe。您在input()功能中对b所做的任何更改都不会反映在tictactoe中。

您至少有两种解决方案:

1)按引用传递板:

void Game::input(Board& b) 

2)或传递一个指针板:

void Game::input(Board* b) 

也有其他解决方案需要重新设计您的代码。这两个可能是解决当前问题的最简单和最直接的方法。

此外,你从一维数组的二维数组映射你的索引的方式似乎有点怪我。我认为它会更容易跟踪正在发生的事情。如果你也

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]); 

事实上,正如其他人指出,这是不必要的,因为你可以计算出从输入行和col指数。或者,您可以要求用户输入两个数字,而不是一个。

3

您正将Board实例的值传递给input()而不是通过指针/引用。对该Board实例所做的任何更改都不会反映在传递给input()的原始Board实例中。

BTW,paranthesis和循环是你的朋友:

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); 
}