将对象引用传递给overloader

时间:2015-09-17 06:04:17

标签: c++ reference scope

当我运行ComputerVsComputer时,tic-tac-toe板都是空的。我研究过像试图找出原因一样。我怀疑它与范围有一些关系;但是,我迷失在C ++中并且无法理解它。帮助

TicTacToe.h

#include <iostream>

using namespace std;

class TicTacToeBoard{
    public:
        TicTacToeBoard(){
            for(int x=0; x<9; x++){
                board[x]='\0';
            }
        }

        void printBoard(){
            cout << endl << board[0] << " |" << board[1] << " |" << board[2] << endl;
            cout << "--"<< "|--|" << "--" << endl;
            cout << board[3] << " |" << board[4] << " |" << board[5] << endl;
            cout << "--" << "|--|" << "--" << endl;
            cout << board[6] << " |" << board[7] << " |" << board[8] << endl << endl;
        }

        char board[9];

        string name;
};

class TicTacToePlayer
{
    public:


        TicTacToePlayer(int isFirstPlayer, TicTacToeBoard& newboard)
        : board(newboard)
        {

            if(isFirstPlayer)
                symbol = 'X';
            else
                symbol = 'O';                 
        }

        /* user made move */
        void makeMove(int m, int n){     

            board.board[getIndexRef(m,n)] = symbol;

            board.printBoard();
        };

        /* computer made move */
        void automateMove(){
            for(int x=0; x<9; x++){
                if(board.board[x]=='\0'){
                    board.board[x]=OpponentSymbol();
                    break;
                }
            }
        };

        /* checks if position in the board is ocupied, 
           returns 1 for occupied
           0 for not occupied */
        int checkPoss(int m, int n){
            int indexRef;

            //if((m>=0 && m<4) && (n>=0 && n<4)){
                indexRef = getIndexRef(m,n);

                if( board.board[indexRef]=='X' || board.board[indexRef]=='O' ){
                    return 1;
                } else {
                    return 0;
                }
            //}
        };

        /* checks and prints the status of game,
        with the help of checkWin()
        retuns  0 for inprogress
            1 for end of game */

        int checkGameStatus(){
            int privateStatus = checkWin();

            if(privateStatus==0){
                if(symbol=='X'){
                    cout << endl << "You win!" << endl;
                } else {
                    cout << endl << "You lose :(" << endl;
                }
                return 1;
            } else if(privateStatus==1){
                if(symbol=='O'){
                    cout << endl << "You win!" << endl;
                } else {
                    cout << endl << "You lose :(" << endl;
                }
                return 1;
            } else if(privateStatus==2){
                cout << endl << "Draw!" << endl;
                return 1;
            } else {
                cout << endl << "The game is in progress!  Continue." << endl;
                return 0;
            }
        };

    private:
        /* Use an appropriate data structure
        for storing the board */

        TicTacToeBoard board;

        char symbol;

        /* Checks who won
        returns 0 for X win
            1 for O win
            2 for draw */
        int checkWin(){
            // check the verticals

            if((checkSlots(1,1,'X') && checkSlots(2,1,'X') && checkSlots(3,1,'X')) || (checkSlots(1,2,'X') && checkSlots(2,2,'X') && checkSlots(3,2,'X')) || (checkSlots(1,3,'X') && checkSlots(2,3,'X') && checkSlots(3,3,'X'))){
                return 0;
            }

            // check horizontals
                if((checkSlots(1,1,'X') && checkSlots(1,2,'X') && checkSlots(1,3,'X')) || (checkSlots(2,1,'X') && checkSlots(2,2,'X') && checkSlots(2,3,'X')) || (checkSlots(3,1,'X') && checkSlots(3,2,'X') && checkSlots(3,3,'X'))){
                return 0;
            }           

            // check diagonals
            if((checkSlots(1,1,'X') && checkSlots(2,2,'X') && checkSlots(3,3,'X')) || (checkSlots(3,1,'X') && checkSlots(2,2,'X') && checkSlots(3,1,'X'))){
                return 0;
            }


            // check verticals
            if((checkSlots(1,1,'O') && checkSlots(2,1,'O') && checkSlots(3,1,'O')) || (checkSlots(1,2,'O') && checkSlots(2,2,'O') && checkSlots(3,2,'O')) || (checkSlots(1,3,'O') && checkSlots(2,3,'O') && checkSlots(3,3,'O'))){
                return 1;
            }

            // check horizontals
            if((checkSlots(1,1,'O') && checkSlots(1,2,'O') && checkSlots(1,3,'O')) || (checkSlots(2,1,'O') && checkSlots(2,2,'O') && checkSlots(2,3,'O')) || (checkSlots(3,1,'O') && checkSlots(3,2,'O') && checkSlots(3,3,'O'))){
                return 1;
            }           

            // check diagonals
            if((checkSlots(1,1,'O') && checkSlots(2,2,'O') && checkSlots(3,3,'O')) || (checkSlots(3,1,'O') && checkSlots(2,2,'O') && checkSlots(3,1,'O'))){
                return 1;
            }

            // to check if it is a draw, confirm that all slots are filled
            for(int x=0; x<9; x++){
                if(board.board[x]=='\0'){
                    return 3; // 3 is neither a win nor a draw
                }
            }

            // if the function hasn't returned by this point, it's a draw
            return 2;
        }

        bool checkSlots(int m, int n, char testSymbol){
            return board.board[getIndexRef(m,n)]==testSymbol;
        }

        int getIndexRef(int row, int col){
            int indexRef;

            if((row>=0 && row<4) && (col>=0 && col<4)){
                if(row==1) {
                    indexRef = col-1; // col is always 1, 2, or 3, so get board[0], board[1], or board[2]
                } else if(row==2) {
                    indexRef = row+col; // always 2+1, 2+2, or 2+3, or boards 3,4,5
                } else if(row==3) {
                    indexRef = row+col+2;     // always 3+1+2, 3+2+2, or 3+3+2, or 6,7,8
                }

                return indexRef;
            } else {
                return 99; // error
            }
        }

        char OpponentSymbol(){
            if(symbol=='X'){
                return 'O';
            } else {
                return 'X';
            }
        }
};

现在是ComputerVsComputer

#include <iostream>
#include "TicTacToe.h"

using namespace std;

int main()
{
    TicTacToeBoard gameboard;
gameboard.name = "Boo"; 
    TicTacToePlayer player1(true, gameboard);
    TicTacToePlayer player2(false, gameboard);
    gameboard.printBoard();

    while (1)
    {
        player1.automateMove();
        if (player1.checkGameStatus())
        {
            gameboard.printBoard();
            break;
        }
        gameboard.printBoard();
        player2.automateMove();
        if (player2.checkGameStatus())
        {
            gameboard.printBoard();
            break;
        }
        gameboard.printBoard();
    }

    return 0;
}

1 个答案:

答案 0 :(得分:1)

TicTacToePlayer获取TicTacToeBoard 按值,这意味着它会在每个TicTacToePlayer对象中复制。当您修改副本时,只修改副本而不是原始副本。

您需要通过引用传递它:

TicTacToePlayer(int isFirstPlayer, TicTacToeBoard& newboard);

并且还要将成员board作为参考:

TicTacToeBoard& board;

但是,您无法分配引用,需要对其进行初始化,而使用构造函数初始化列表进行初始化:

TicTacToePlayer(int isFirstPlayer, TicTacToeBoard& newboard)
    : board(newboard)
{
    ...
}

现在player1player2都会引用gameboard变量,而一个玩家对象的更改会更改gameboard对象。