user4058875
user4058875

Reputation:

C++ compile error with functions

I was wondering if someone could lend me some advice as to why my code wont compile. I have a simple tic tac toe game here split up into 3 files. Yet, main.cpp is unable to create an objects from my ticTacToe.h file and I just don't understand why. I feel like I'm a step away from getting this to run. ticTacToe.cpp and ticTacToe.h compile just fine. It's the main.cpp file that produces an error when it gets to line 14 "ttt.create_board();". The error message is "unidentified reference to 'ticTacToe: :create_board(char)'" Any help would be greatly appreciated. Thanks guys.

main.cpp

#include "ticTacToe.h"
#include <iostream>
#include <limits> //This is required to catch invalid user input

void run_game()
{
    char letter_o = 'O';
    char letter_x = 'X';
    ticTacToe ttt; //creates an object "ttt" to be used later
    ttt.player1Piece = letter_x;
    ttt.player2Piece = letter_o;
    std::cout << "Welcome to tic tac toe!" << std::endl;
    std::cout << "Here is a blank board: " << std::endl;
    ttt.create_board();
    while (true){
        std::cout << "\nPlayer X, it is your turn\n" << std::endl;
        ttt.update_board(letter_x);
        if (ttt.determine_winner(letter_x) == true){
            break;
        }
        std::cout << "\nPlayer O, it is your turn\n" << std::endl;
        ttt.update_board(letter_o);
        if (ttt.determine_winner(letter_o) == true){
            break;
        }
    }
}

int main() //main kicks things off by calling "run_game()"
{
    run_game();

}

ticTacToe.h

#ifndef TICTACTOE_H
#define TICTACTOE_H


class ticTacToe
{
    public: //Allow us to use the functions anywhere
    char board[3][3]; //Creates an 2d array for the board
    char player1Piece; //variable used in multiple functions
    char player2Piece; //varibable used in multiple

    void create_board();
    void print_board(char playerPiece, int pos1 = 0, int pos2 = 0);
    int check_for_overlap(int pos1, int pos2, char playerPiece);
    void update_board(char playerPiece);
    int determine_winner(char playerPiece);
};

#endif // TICTACTOE_H

ticTacToe.cpp

#include "ticTacToe.h"
#include <iostream>
#include <limits>

ticTacToe::ticTacToe()
{
     void ticTacToe::create_board()
{
    //initializes a blank board
    for(int a = 0; a < 3; a++){
        std::cout << "\n";
        for (int b = 0; b < 3; b++){
            board[a][b] = '-';
            std::cout << board[a][b];
        }
    }
}


void ticTacToe::print_board(char playerPiece, int pos1 = 0, int pos2 = 0)
{
    //prints out the updated board when called upon to do so
    for(int a = 0; a < 3; a++){
        std::cout << "\n";
        for (int b = 0; b < 3; b++){
            board[pos1][pos2] = playerPiece;
            std::cout << board[a][b];
        }
    }
}


int ticTacToe::check_for_overlap(int pos1, int pos2, char playerPiece)
{
    if (board[pos1-1][pos2-1] != '-'){
        std::cout << "\nOVERLAP DETECTED!!!!!!" << std::endl;
        return true;
        }
        return false;
}


void ticTacToe::update_board(char playerPiece)
{
    //updates the board based on user input
    int x, y;
    std::cout << "Enter a position to place the " << playerPiece << " on the board" << std::endl;
    while (true){
        std::cout << "Enter row: " << std::endl;
        std::cin >> x;
        if (x < 1 || x > 3 || std::cin.fail()){
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
            std::cout << "Your number is invalid. Try again. " << std::endl;
        } else {
            break;
        }
    }

    while (true)
    {
        std::cout << "Enter col: " << std::endl;
        std::cin >> y;
        if (y < 1 || y > 3 || std::cin.fail()){
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
            std::cout << "Your number is invalid. Try again. " << std::endl;
        } else {
            break;
        }
    }

    if (check_for_overlap(x, y, player1Piece) == true){
        x--;y--;print_board(player2Piece, x, y);
        std::cout << "\nThe board has been re-set. Try again!" << std::endl;
    } else if (check_for_overlap(x, y, player2Piece) == true){
        x--;y--;print_board(player1Piece, x, y);
        std::cout << "\nThe board has been re-set. Try again." << std::endl;
    } else {
        x--;y--;print_board(playerPiece, x, y);
    }
}


int ticTacToe::determine_winner(char playerPiece)
{
    /*slices the board and checks if playerPiece occupies that slot.
    If the player makes a line, print that playerPiece has won
    and exit the game.*/
    if (board[0][0] == playerPiece && board[0][1] == playerPiece && board[0][2] == playerPiece){
        std::cout << "\nPlayer " << playerPiece << " wins!" << std::endl;
        return true;
    }
    else if(board[1][0] == playerPiece && board[1][1] == playerPiece && board[1][2] == playerPiece){
        std::cout << "\nPlayer " << playerPiece << " wins!" << std::endl;
        return true;
    }
    else if(board[2][0] == playerPiece && board[2][1] == playerPiece && board[2][2] == playerPiece){
        std::cout << "\nPlayer " << playerPiece << " wins!" << std::endl;
        return true;
    }
    else if(board[0][0] == playerPiece && board[1][0] == playerPiece && board[2][0] == playerPiece){
        std::cout << "\nPlayer " << playerPiece << " wins!" << std::endl;
        return true;
    }
    else if(board[0][1] == playerPiece && board[1][1] == playerPiece && board[2][1] == playerPiece){
        std::cout << "\nPlayer " << playerPiece << " wins!" << std::endl;
        return true;
    }
    else if(board[0][2] == playerPiece && board[1][2] == playerPiece && board[2][2] == playerPiece){
        std::cout << "\nPlayer " << playerPiece << " wins!" << std::endl;
        return true;
    }
    else if(board[0][0] == playerPiece && board[1][1] == playerPiece && board[2][2] == playerPiece){
        std::cout << "\nPlayer " << playerPiece << " wins!" << std::endl;
        return true;
    }
    else if(board[0][2] == playerPiece && board[1][1] == playerPiece && board[2][0] == playerPiece){
        std::cout << "\nPlayer " << playerPiece << " wins!" << std::endl;
        return true;
    } else {
        return false;
    }
}

}

}

Upvotes: 0

Views: 148

Answers (3)

Paul Rooney
Paul Rooney

Reputation: 21619

The problem is here

ticTacToe::ticTacToe()
{
     void ticTacToe::create_board()
     {

     }

     // more functions

}

You have wrapped all your member functions inside your tictacToe constructor. As you are not actually doing anything in your constructor you can remove it.

Remove

 ticTacToe::ticTacToe()
    {

and

}
}

At the end of your cpp file.

Also do not specify default parameters to a method in the method definition (cpp file) and the method declaration (h file).

if you do

class ticTacToe
{
public: //Allow us to use the functions anywhere

    ...
    void print_board(char playerPiece, int pos1 = 0, int pos2 = 0);
    ...
}; 

Don't then redeclare the defaults.

void ticTacToe::print_board(char playerPiece, int pos1 = 0, int pos2 = 0)

Instead declare the method

void ticTacToe::print_board(char playerPiece, int pos1, int pos2)

A final comment

check_for_overlap returns int. As you internally use bool and check for bool when you call it, you should change the method signature to

bool ticTacToe::check_for_overlap(int pos1, int pos2, char playerPiece)

Upvotes: 0

gsamaras
gsamaras

Reputation: 73444

Change this

ticTacToe::ticTacToe()
{
     void ticTacToe::create_board()
{
    //initializes a blank board
    for(int a = 0; a < 3; a++){
        std::cout << "\n";
        for (int b = 0; b < 3; b++){
            board[a][b] = '-';
            std::cout << board[a][b];
        }
    }
}

to this

void ticTacToe::create_board()
{
    //initializes a blank board
    for(int a = 0; a < 3; a++){
        std::cout << "\n";
        for (int b = 0; b < 3; b++){
            board[a][b] = '-';
            std::cout << board[a][b];
        }
    }
}

Then remove from ticTacToe.cpp file the last two curly brackets in the file.

If you want to have a constructor, then you should define it inside the class, like the other functions (and then of course implement it inside .cpp).

class ticTacToe {
    ...
    char player2Piece; //varibable used in multiple

    ticTacToe();               <--- HERE
    void create_board();
    void print_board(char playerPiece, int pos1, int pos2); <-- Change the default arguments here
    ...
};

Also, in void print_board(char playerPiece, int pos1, int pos2); you should not pass the default arguments in the .h file (or the other way around).

Upvotes: 1

NaCl
NaCl

Reputation: 2723

Simply remove both } at the very end of ticTacToe.cpp and

ticTacToe::ticTacToe()
{

You didn't declare any constructor in the header file.

Then there is another Problem with the function print_board.

It's declared as void print_board(char playerPiece, int pos1 = 0, int pos2 = 0) but you're using default arguments in definition, too.

Change both int pos1=0, int pos2=0 to int pos1, int pos2 in ticTacToe.cpp.

Try to overthink your code formatting to know which bracet belong to which. :)

Upvotes: 2

Related Questions