1

I am currently trying to make a tic-tac-toe AI in C++. I am currently making a function to check if the winstate of the game, but when I try to run it, I get this error:

61:34: error: cannot convert ‘std::string’ {aka ‘std::__cxx11::basic_string’} to ‘std::string (*)[3]’ {aka ‘std::__cxx11::basic_string (*)[3]’}
   61 |         cout << HasWon(Board[3][3], Length);
      |                        ~~~~~~~~~~^
      |                                  |
      |                                  std::string {aka std::__cxx11::basic_string<char>}
main.cpp:6:19: note:   initializing argument 1 of ‘int HasWon(std::string (*)[3], int)’
    6 | int HasWon(string GameBoard[3][3], int boardLength);
      |            ~~~~~~~^~~~~~~~~~~~~~~

I know that it has to do with char and strings, but I don't have any idea how to implement it in my current program. Here’s the code:

#include <iostream>

using namespace std;

int AIMove(int PlayerMove);
int HasWon(string GameBoard[3][3], int boardLength);
int main () {
    int Length = 3;
    string Board[Length][Length] = {
        {" ", " ", " "},
        {" ", " ", " "},
        {" ", " ", " "},
    };
    int NodeMap[Length][Length] = {
        {0, 0, 0},
        {0, 0, 0},
        {0, 0, 0},
    };
    int NodeNumber = 1;
    for(int h = Length - 1; h >= 0;h--) {
        for(int d = 0; d < Length; d++) {
            NodeMap[h][d] = NodeNumber;
            NodeNumber++;
        }
    }

    int Player;
    bool HasMoved = false;
    bool run = true;
    while(run) {
        // Prints Tic Tac Toe board to the screen
        for(int h = 0; h < Length; h++) {
            cout << " ";
            for(int d = 0; d < Length; d++) {
                cout << Board[h][d];
                if(d < Length - 1) {
                    cout <<"||";
                }
            }
            if(h < Length - 1) {
                cout << "\n---------\n";
            }
        }
        // Gets player input
        cout << "\n choose a number 1-9 to place an X: ";
        cin >> Player;

        // Adds it to the board
        HasMoved = false;
        while(!HasMoved) {
            for(int h = 0; h < Length; h++) {
                for(int d = 0; d < Length; d++) {
                    if(NodeMap[h][d] == Player && Board[h][d] == " ") {
                        Board[h][d] = "X";
                        HasMoved = true;
                    }
                }
            }
            if(!HasMoved) {
                cout << "\n choose a number 1-9 to place an X: ";
                cin >> Player;
            }
        }
        cout << HasWon(Board[3][3], Length);
    }
}

int AIMove(int PlayerMove, int boardLength);

// Checks if anyone has won yet. 0: nothing has happend, 1: tie, 2: X win, 3: O win.
int HasWon(string GameBoard[3][3], int boardLength) {
    int xNumber = 0;
    int oNumber = 0;

    // Checks for vertical wins
    for(int d = 0;d < boardLength; d++) {
        xNumber = 0;
        oNumber = 0;
        for(int h = 0;h < boardLength; h++) {
            if(GameBoard[h][d] ==  "X") {
                xNumber++;
            }
            if(GameBoard[h][d] ==  "O") {
                oNumber++;
            }

            if(xNumber == boardLength ) {
                return 2;
            }
            if(oNumber == boardLength ) {
                return 3;
            }
        }
    }

    // Checks for horizontial wins
    for(int h = 0;h < boardLength; h++) {
        xNumber = 0;
        oNumber = 0;
        for(int d = 0;d < boardLength; d++) {
            if(GameBoard[h][d] ==  "X") {
                xNumber++;
            }
            if(GameBoard[h][d] ==  "O") {
                oNumber++;
            }

            if(xNumber == boardLength ) {
                return 2;
            }
            if(oNumber == boardLength ) {
                return 3;
            }
        }
    }

    // Checks for diagonal wins
    xNumber = 0;
    oNumber = 0;
    for(int i = boardLength - 1; i >= 0; i--) {
        if(GameBoard[i][i] == "X") {
            xNumber++;
        }
        if(GameBoard[i][i] == "O") {
            oNumber++;
        }

        if(xNumber == boardLength ) {
            return 2;
        }
        if(oNumber == boardLength ) {
            return 3;
        }
    }

    xNumber = 0;
    oNumber = 0;
    for(int i = 0;i < boardLength; i++) {
        if(GameBoard[i][i] == "X") {
            xNumber++;
        }
        if(GameBoard[i][i] == "O") {
            oNumber++;
        }

        if(xNumber == boardLength ) {
            return 2;
        }
        if(oNumber == boardLength ) {
            return 3;
        }
    }

    // Checks for a tie
    xNumber = 0;
    oNumber = 0;
    for(int h = 0;h < boardLength; h++) {
        for(int d = 0;d < boardLength; d++) {
            if(GameBoard[h][d] ==  "X") {
                xNumber++;
            }
            if(GameBoard[h][d] ==  "O") {
                oNumber++;
            }

            if(xNumber+oNumber == boardLength*boardLength) {
                return 1;
            }
        }
    }
    return 0;
}
1
  • HasWon(Board[3][3], Length) -> HasWon(Board, Length) and int Length = 3; -> const int Length = 3;. I don't know what your intention with the [3][3] indices is and array sizes must be compile-time constants in standard C++. int without const cannot be a constant at all. Commented Mar 26, 2022 at 5:16

1 Answer 1

2

The problem is that the type of the expression Board[3][3] when passing as a call argument is std::string while the type of the function parameter GameBoard is actually ‘std::string (*)[3]. This is because of string [3][3] decays to string (*)[3] due to type decay.

Thus there is mismatch in the type of the parameter of the function HasWon and the argument passed.

Also note that in standard C++, the size of an array must be a compile time constant. So in you code:

int Length = 3;
string Board[Length][Length]; // This is not standard C++

The statement string Board[Length][Length]; is not standard C++ because Length is not a constant expression.

To solve this you should add a top-level const to Length and pass the argument Board instead of Board[3][3] as shown below:

//-vvvvv---------------------------> const added here
   const int Length = 3;
//----------------vvvvv------------> Changed to Board instead of Board[3][3]
   cout << HasWon(Board, Length);

Demo.

Another alternative (better) would be to use std::vector.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.