2013-12-14 3 views
0

나는 학교를 위해 만든 Tic Tac Toe 게임에서 Game (게임용 컨트롤러로 작동), Player (기본 클래스), HumanPlayer 및 AIPlayer (플레이어에서 파생 됨) 및 게시판이라는 다섯 가지 수업을 운영합니다.C++ 객체 또는 2 차원 배열을 매개 변수로 사용 하시겠습니까?

보드에는 2D 어레이와 어레이를 표시하고 작업하기위한 몇 가지 기능이 포함되어 있습니다. 세 선수의 클래스는 보드의 위치를 ​​선택하고 makeAMove이 매개 변수로 Board 객체를 받아 볼 수 있듯이은 X 또는 O를

를 배치하는 함수 makeAMove(Board &board) 있습니다. 그런 다음 함수는 이동을 결정하고 Board 객체의 보드 배열을 변경합니다. 내가 올바르게 이해하고 있다면, 전달 된 실제 객체가 변경 될 것이고, 아무것도 반환 할 필요가 없을 것입니다.

이 내용을 올바르게 이해하고 있습니까? 대신 매개 변수로 2d 배열을 사용하는 것이 좋을까요?

여기 내 코드가 응축 된 버전입니다.

#include <iostream> 
#include <memory> // auto_ptr 

class Board 
{ 
    public: 
     Board() 
     { 
      for (int row = 0; row < 3; row++) 
      { 
       for (int column = 0; column < 3; column++) 
        board[row][column] = ' '; 
      } 
     } 

     void displayBoard() 
     { 
      std::cout << "\n-------------" << std::endl; 

      for (int row = 0; row < 3; row++) 
      { 
       std::cout << "| " ; 
       for (int column = 0; column < 3; column++) 
        std::cout << board[row][column] << " | "; 
       std::cout << "\n-------------" << std::endl; 
      } 
     } 

/*  My thought was to use getBoard to return the array rather than using the 
     object as a parameter  
     char getBoard() 
     { 
      return board[][3]; 
     }  
*/ 

    char getCell(int row, int column) 
    { 
     return board[row][column]; 
    } 

    void setCell(int row, int column, char player) 
    { 
     board[row][column] = player; 
    } 

    private: 
     char board[3][3]; 

}; 

class Player 
{ 
    public: 
     virtual void makeAMove(Board &board) = 0; 
}; 

class AIPlayer : public Player 
{ 
    virtual void makeAMove(Board &board) 
    { 
     // do some work ont the board array 
    } 
}; 

class HumanPlayer : public Player 
{ 
    virtual void makeAMove(Board &board) 
    { 
     // do some work on the board array 
    } 
}; 

class Game 
{ 
    public: 
     Game(unsigned int players) 
     { 
      if (players == 1) 
      { 
       player1.reset (new HumanPlayer()); 
       player2.reset (new AIPlayer()); 
      } 
      else 
      { 
       player1.reset (new HumanPlayer()); 
       player2.reset (new HumanPlayer()); 
      } 
     } 

     void playGame() 
     { 
      player1->makeAMove(myBoard); 
     } 

    private: 
     std::auto_ptr<Player> player1; // pointer to a Player object (C++11 has more secure unique_ptr) 
     std::auto_ptr<Player> player2; // pointer to a Player object 
     Board myBoard; 
}; 

int main() 
{ 
    Game myGame(1); 
    myGame.playGame(); 

    return 0; 
} 

답변

1

makeAMoveboard에 속한다. 플레이어 개체는 이동을 결정한 다음 board::makeAMove으로 전화하여 이동하십시오. 그런 식으로 플레이어 오브젝트는 보드의 내부 표현이 무엇인지 신경 쓰지 않습니다.

2

예, 참조로 Board 개체를 전달하기 때문에 함수에서이 개체를 변경하면 실제 Board 개체가 변경됩니다. 나는 Board 객체를 전달하는 것이 더 좋은 아이디어라고 생각한다. 게임의 실제 구현 (이 경우 2D 배열)을 사용자에게 노출하지 않는 것이 더 낫다. 따라서 Board 객체로 전달하면 추상화가 더 잘됩니다.

0

배열 대신 개체를 참조로 전달하십시오. 플레이어가 보드에서 변경 한 사항은 계속 유지됩니다.

boardBoard의 개인 회원입니다. 그것은 참조가 아닌 값으로 반환되어야합니다. Value에 의해 2D 배열을 플레이어에 전달하면 보드에 대한 변경 사항이 유지되지 않습니다.

Player 클래스는 makeAMove(Board &board) 함수에서 Board.setCell(int, int)에 액세스해야하며이를 수행하려면 보드 객체가 필요합니다.

그러나 Players 클래스는 보드를 읽어야합니다. 움직이기 위해서. getCell(int,int) 함수로도 충분할 수 있지만 모든 셀을 통해 중첩 루프가 지루할 수도 있습니다. getBoard은 가능한 decideMove 기능에 유용 할 수 있습니다.

+0

네, 맞을 수도 있습니다. 하지만 getter에서 2 차원 배열을 반환하는 방법을 잘 모르겠습니다. – navig8tr

+0

배열이'std :: vector '또는 C++ 11에서'std :: array '이 아니면 정말 안됩니다. 그렇지 않으면 플레이어가 배열의 길이를 알 수 없습니다. 아마 2D 배열 대신'char [9]'를 가질 수 있을까요? 실제로 2D 배열 일 필요가 있습니까? – cheezsteak

+0

아니요. 단지 사용자 입력을 더 쉽게 만듭니다. 사용자는 먼저 행을 입력 한 다음 열을 입력합니다. 그런 다음이 숫자를 2 차원 배열에 직접 적용합니다 (유효성 검사 후). 1d 배열을 사용했다면 각 행과 열을 단일 인덱스로 변환해야합니다. 물론 불가능하지는 않지만 가능한 한 간단하게 유지하려고합니다. – navig8tr

관련 문제