-1

I've got this file where it seems to be an undefined reference but I don't know why, everything it seems correct to me. Someone can help me?

This is the error:

g++ -c driver.cpp -std=c++11 -pedantic -Wall
g++ -o driver driver.o
/usr/bin/ld: driver.o: in function `main':
driver.cpp:(.text+0x23): undefined reference to `TicTacToe::TicTacToe()'
/usr/bin/ld: driver.cpp:(.text+0x2f): undefined reference to `TicTacToe::makeMove()'
collect2: error: ld returned 1 exit status
make: *** [makefile:2: driver] Error 1

And these are the files I'm using:

The driver program:

// driver.cpp: use of TicTacToe class
#include "TicTacToe.h" // include definition of class TicTacToe

int main() {
    TicTacToe g; // creates object g of class TicTacToe
    g.makeMove(); // invokes function makeMove
}

This is the class:

// TicTacToe.h
#ifndef TICTACTOE_H
#define TICTACTOE_H
#include <array>

class TicTacToe {
    private:
        enum Status {WIN, DRAW, CONTINUE}; // enumeration constants
        std::array<std::array<int, 3>, 3> board;
    public:
        TicTacToe(); // default constructor
        void makeMove(); // make move
        void printBoard() const; // print board
        bool validMove(int, int) const; // validate move
        bool xoMove(int); // x o move
        Status gameStatus() const; // game status
};

#endif

These are the class function members:

// TicTacToe.cpp
// Member-function defnitions for class TicTacToe.
#include <iostream>
#include <iomanip>
#include "TicTacToe.h" // include definition of class TicTacToe
using std::cout;
using std::cin;
using std::setw;

TicTacToe::TicTacToe() {
    for (int j{0}; j < 3; ++j) { // initialize board
        for (int k{0}; k < 3; ++k) {
            board[j][k] = ' ';
        }
    }
}

void TicTacToe::makeMove() {
    printBoard();

    while (true) {
        if (xoMove('X')) {
            break;
        }
        else if (xoMove('O')) {
            break;
        }
    }
}

void TicTacToe::printBoard() const {
    cout << "   0    1    2\n\n";

    for (int r{0}; r < 3; ++r) {
        cout << r;

        for (int c = 0; c < 3; ++r) {
            cout << setw(3) << static_cast< char > (board[r][c]);

            if (c != 2) {
                cout << " |";
            }
        }

        if (r != 2) {
            cout << "\n ____|____|____\n     |    |    \n";
        }
    }

    cout << "\n\n";
}

bool TicTacToe::xoMove(int symbol) {
    int x;
    int y;

    do {
        cout << "Player " << static_cast<char>(symbol) << " enter move: ";
        cin >> x >> y;
        cout << '\n';
    } while (!validMove(x, y));

    board[x][y] = symbol;
    printBoard();
    Status xoStatus = gameStatus();

    if (xoStatus == WIN) {
        cout << "Player " << static_cast<char>(symbol) << " wins!\n";
        return true;
    }
    else if (xoStatus == DRAW) {
        cout << "Game is draw.\n";
        return true;
    }
    else { // CONTINUE
        return false;
    }
}

bool TicTacToe::validMove(int r, int c) const {
    return r >= 0 && r < 3 && c >= 0 && c < 3 && board[r][c] == ' ';
}

// must specify that type Status is part of the TicTacToe class.
TicTacToe::Status TicTacToe::gameStatus() const {
    // check for a win on diagonals
    if (board[0][0] != ' ' && board[0][0] == board[1][1] && board[0][0] == board[2][2]) {
        return WIN;
    }
    else if (board[2][0] != ' ' && board[2][0] == board[1][1] && board[2][0] == board[0][2]) {
        return WIN;
    }

    // check for win in rows
    for (int a{0}; a < 3; ++a) {
        if (board[a][0] != ' ' && board[a][0] == board[a][1] && board[a][0] == board[a][2]) {
            return WIN;
        }
    }

    // check for win in columns
    for (int a{0}; a < 3; ++a) {
        if (board[0][a] != ' ' && board[0][a] == board[1][a] && board[0][a] == board[2][a]) {
            return WIN;
        }
    }

    // check for a completed game
    for (int r{0}; r < 3; ++r) {
        for (int c{0}; c < 3; ++c) {
            if (board[r][c] == ' ') {
                return CONTINUE; // game is not finished
            }
        }
    }

    return DRAW; // game is a draw
}

It's probably something stupid but I don't know what I have to look for.

  • 6
    You never compile or link `TicTacToe.cpp` – Drew Dormann Feb 08 '22 at 16:48
  • 1
    Do not do `#include` for `cpp` files. You have to use the command `g++` with each `cpp` file to generate an object file (`.o`). Then link them (again, using `g++`) into an executable. You can do it all in one step, as shown in the link I posted in my above comment. – Aziz Feb 08 '22 at 16:56
  • Unrelated. Go easy on yourself. what does `g` tell you about a variable? For a two line function you can get away with it, but that doesn't last after about 10 lines, `g` will blend in with `d`, `p`, `i`, and `l` and you will spend more time tracing what means what than you do debugging. – user4581301 Feb 08 '22 at 17:02
  • `for (int c = 0; c < 3; ++r) {` probably meant `++c` – Wyck Feb 08 '22 at 17:12

1 Answers1

0

step by step:

g++ -c driver.cpp TicTacToe.cpp -std=c++11 -pedantic -Wall

g++ -o driver driver.o TicTacToe.o

./driver

H.M
  • 425
  • 2
  • 16
  • ok, I tried but now I have another problem. When I run the program it prints a lot of casual simbols and it shouldn't do that. – Ivan Cerasuolo Feb 08 '22 at 17:01
  • you asked for compling not debugging ! , it's bug in your coding level not compiling ( your porgram has segmentation fault too) , search for solving "segmentation fault". – H.M Feb 08 '22 at 17:04