1

I was just wondering if I could get some help with passing an array pointer from One header file to another.

I have Header File for TicTacToe, that contains The game TicTacToe and another Header File that will contain My AI and its methods.

I was just wondering if I can pass back and forward The moves from TicTacToe to AI, so that the ai can make a smart move and return it back into the TicTacToe header for Validation/Updating for gameBoard (or Ill make another validation within AI) Once I have the Idea, Ill start separating Methods from TicTacToe into there own class.

I have included The code for my Main, TicTacToe, and AI If there is any criticism please let me have it

MAIN

#include <iostream>
using namespace std;
#include "TicTacToe.h"
#include "AI.h"
int main()
{
TicTacToe run;
run.Play();
TicTacToeAI Test;
}

TicTacToe.h


//Functional implementation for Tic Tac Toe game (incomplete)

#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

class Game
{

};

class TicTacToe
{
private:
    bool WIN =false;
    bool DRAW = false;
    char board[3][3];
    int noOfMoves = 0;
    char  player = 'X';
    char player2 =' ';
    int row = 0;
    int col =0;

public:

    void PlayerFlick();
    void getXOMove();
    void Play();
    bool addMove();
    bool gameStatus();
    bool isValidMove();



    void displayBored()
{
for (int row = 0; row < 3; row++) {
    cout << row + 1;
    for (int col = 0; col < 3; col++) {
        cout << setw(3) << board[row][col];
        if (col != 2)
            cout << " |";
    }
    cout << endl;
    if (row != 2)
        cout << " ____|____|____" << endl << "     |    |    " << endl;

}
cout << endl;

}
    void ResetBoard()
    {

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                board[i][j] = ' ';
    }


};
// Methods
bool TicTacToe::gameStatus() // Works with cout << board[row][col]<<  endl
{

    bool CONTINUE = false;
    for(int i = 0; i <= 2; i++)
            {
                if ((board[i][0] =='X'   &&  board[i][1] == 'X' && board[i][2]  == 'X') || (board[i][0] ==  'O' &&   board[i][1]==  'O' && board[i][2] == 'O'))
                {
                    cout << " CROSS" << endl; // 3,3 // 1,3
                    WIN = true;
                    return WIN;

                }
            }
        for(int i= 0; i <=2; i++)
        {
            if((board[0][i] == 'X' &&   board[1][i] == 'X' && board[2][i]  == 'X') || (board[0][i] ==  'O' &&  board[1][i]==  'O' && board[2][i] == 'O'))
                {
                        cout << " DOWN" << endl; // 3,1
                        WIN = true;
                        return WIN;
                }
        }

        if((board[0][0]== 'X' &&  board[1][1] == 'X' && board[2][2] == 'X') ||(board[0][0]== 'O' &&  board[1][1] ==  'O'&& board[2][2] == 'O') )
        {
            cout << " RIGHT SIDE" << endl;
            WIN = true;
            return WIN;
        }
        if((board[0][2] == 'X'&& board[1][1] == 'X' && board[2][0] == 'X') || (board[0][2] ==  'O' &&  board[1][1] ==  'O'&& board[2][0] == 'O' ))
        {
            cout << " LEFT SIDE" << endl;
            WIN = true;
            return WIN;
        }

        if(noOfMoves == 9)
            {
               cout<< " DRAW"<< endl;
               DRAW= true;
               return WIN;
            }

        TicTacToe::PlayerFlick();

        CONTINUE = false;
        return CONTINUE;


}
void TicTacToe::getXOMove()//  work with cout << board[row][col]<<  endl
{

    do {
            cout << "Player " << player << " enter move: ";
            cin >> row >> col;
            cout << endl;


        } while (!isValidMove());
            row--;
            col--;
}

bool TicTacToe::addMove() // does work with board[row][col]
{
        bool gStatus = false;
        noOfMoves++;
        board[row][col] = player;


        TicTacToe::displayBored();
        gStatus = TicTacToe::gameStatus();

        if (gStatus == true) {
            cout << "Player " << player << " wins!" << endl;
            return true;
        } else if (noOfMoves >= 9) {
            return true;
        } else
            return false;

}
bool TicTacToe::isValidMove()
{


    if ((row <=3 && col <=3) && (board[row-1][col-1] != 'X' && board[row-1][col-1] != 'O' ) )
    {
        return true;
    }
        else
        {
            return false;
        }
}

void TicTacToe::Play()
{
    TicTacToe::ResetBoard();
    TicTacToe::displayBored();
    bool done = false;

    while (!done)
    {
            TicTacToe::getXOMove();
            done = TicTacToe::addMove();

    }
}

void TicTacToe::PlayerFlick()
{
    if (player == 'X')
                player = 'O';
            else
                player = 'X';
}


AI header

     #include <iostream>
     #include <iomanip>
     #include <string>
     using namespace std;
     class TicTacToeAI

    {
    private:
       TicTacToe board;
       int col =0;
       int row =0;
       int arr [3][3] = {0};
     public:
       void CreateArr(int *Arr, int arrLength);
       void play();
       void getXmove();
       void getOMove();
       void getXmove(char player, row&, col&);
       void GetoMove(char playr , row&, col&);
     };

     void TicTacToeAI::CreateArr(int *Arr,int arrLength)
     {

     }

Plazy
  • 13
  • 2
  • It's wall of text.. can you speficied a [Minimal Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) to demonstrate your idea? – Louis Go Aug 20 '20 at 08:19
  • Or by your `main`, do you want to let `TicTacToeAI test` to communicate with `run`? – Louis Go Aug 20 '20 at 08:20
  • Avoid `using namespace std;` especially in headers or before `#include`. – Jarod42 Aug 20 '20 at 08:26

1 Answers1

0

The most comman way could be Inversion of Control.

Code below demonstrate the Inversion of Control by Dependency Injection.

So TicTacToe could access the AI through the pointer as an class member.

#include<iostream>

class TicTacToeAI{    
};

class TicTacToe{
    private:
        const TicTacToeAI* m_AI;
    public:
        TicTacToe( const TicTacToeAI* ai ) : m_AI( ai ){ // Inject the pointer to TicTacToe

        }
};

int main(){
    TicTacToeAI Test;
    TicTacToe run( &Test );
    run.Play();
}
Louis Go
  • 2,213
  • 2
  • 16
  • 29
  • Could this work Both ways ? Due to TicTacToe atm having All control of the user input, inputting into the array. – Plazy Aug 20 '20 at 10:11
  • I did not fully read your code, but AI is needed only after user has input (unless AI takes first ). So oneway interaction should be enough. Just put user input into AI and AI output the next step. – Louis Go Aug 20 '20 at 12:39
  • Interface of AI seems not quite clear, and you don't need function like `CreateArr` to operate AI. Only two public functions are needed for AI: 1. Reset state 2. Take user input and output AI step. X and O doesn't matter, they are just a symbol. You should handle symbols output in `TicTacToe`. – Louis Go Aug 20 '20 at 12:44