Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undefined reference to 'function' -- Linker issue?

Tags:

c++

linker

I am currently trying to compile and link my C++ files on a linux terminal. The command I run is:

g++ -o gameplay gamePlay.cpp player.cpp main.cpp display.cpp -lcurses

The command seems to compile everything perfectly, but once it trys to link things I get 2 errors.

undefined reference to 'gamePlay::deal(std::vector<card, std::allocator<card> >, std::vector<player, std::alloator<player> >)'

undefined reference to 'gamePlay::score(player)'

Below is my gamePlay.CPP file. I am really lost and any help would be much appreciated!

#include "gamePlay.h"
#include <cstdlib>
#include <sstream>

int gamePlay::compareCenter(int leadplayer){
int highest = center[leadplayer].getCardNum();
if(center[leadplayer].getCardNum() == 1)
    highest = center[leadplayer].getCardNum() + 13;
int suit = center[leadplayer].getSuit();
int player = leadplayer;

for(int i = leadplayer+1; i < leadplayer+4; i++)
{
    if((suit != 1) && (center[i%4].getSuit() == 1))
    {
       player = i%4;
       suit = 1;
       highest = center[i%4].getCardNum();
    }
    else if(suit == center[i%4].getSuit())
        if(center[i].getCardNum() == 1){
            player = i % 4;
            highest = center[i].getCardNum() + 13;
        }
        if(highest < center[i%4].getCardNum())
        {
            player = i%4;
            highest = center[i%4].getCardNum();
        }

}
players.at(player).setTricksTaken(players.at(player).getTricksTaken()+1);
return player;
}

vector <card> createDeck() {
//Create the Deck and create each suit by calling define cards.
vector <card> deck;
for(int i = 1; i <= 4; i++){
    for(int j = 1; j <= 13; j++){
        card newCard (i,j);
        deck.push_back(newCard);
    }
}
random_shuffle (deck.begin(), deck.end());
return deck;
}

void gamePlay::deal(vector <card> &deck, vector <player> players){
for(int j = 0; j<4; j++){
    for(int i = 0; i<13; i++){
    players.at(j).addCard(deck.at(0));
    deck.erase(deck.begin());
    }
}
}

bool containSuit(card lead, player players){
bool suit = false;
for(int i = 0; i < players.getHand().size(); i++){
    if(lead.getSuit() == players.getHand().at(i).getSuit())
        suit = true;
}
return suit;
}

bool gamePlay::onlySpade(player play){
for(int i = 0; i<play.getHand().size(); i++){
    if(play.getHand().at(i).getSuit()!=1)
    return false;
}
return true;
}

int gamePlay::handCheck(int xevent, int yevent, vector <player> players, int     trickStart){
        for(int i = 1; i < 14; i++){
            if(xevent<(i*6) && yevent>17 && yevent<23 &&      players.at(0).getHand().at(i-1).getSuit() != 0 && players.at(0).getHand().at(i-  1).getCardNum() != 0){
                card playedCard = players.at(0).getHand().at(i-1);
                //first check to find card on display
                //check to see if leading or not
                //if leading use spadesBroken function
                //if not leading use contains suit function
                if(trickStart==0 && !getSpadesBroken()){
                    if(onlySpade(players.at(0)))
                        return i;
                    else if(playedCard.getSuit() != 1)
                        return i;
                    else
                        return NULL;
                }
                if(trickStart == 0 && getSpadesBroken())
                    return i;
                if(trickStart > 0 &&  containSuit(center[trickStart],players.at(0))){
                        if(playedCard.getSuit()==center[trickStart].getSuit())
                        return i;
                }
                if(trickStart > 0 &&    !containSuit(center[trickStart],players.at(0)))
                    return i;
                else
                    return NULL;
            }
        }
}

void gamePlay::displayHand(){
int offset = 0;
    for(int i =0; i<players.at(0).getHand().size(); i++){
        monitor.displayCard(offset, 18,     players.at(0).getHand().at(i).getSuit(), players.at(0).getHand().at(i).getCardNum(), 0);
        offset+=6;
    }
}
void gamePlay::humanPlay(int trickStart){
    int xevent, yevent;
    int key = monitor.captureInput();
    for(;;){
        mvprintw(8,26,"Please choose a card to play.");
        // if a mouse event occurred
        if (key == -1) {
            xevent = monitor.getMouseEventX();
            yevent = monitor.getMouseEventY();
            int handCh = handCheck(xevent, yevent, players,    trickStart);
            if(handCh != NULL){
                card played = players.at(0).getHand().at(handCh-1);
                players.at(0).getHand().at(handCh-1).setCardNum(0);
                players.at(0).getHand().at(handCh-1).setSuit(0);
                center[0]= played;
                monitor.displayCard(34, 11, center[0].getSuit(),   center[0].getCardNum(), 0);
                displayHand();
                break;
            }
        }
    }
}
void gamePlay::CPUplay(int trickStart, int CPU){
    bool goodCard = false;
    card playedCard =players.at(CPU).getHand().at(0);
    int i;
    for(i = 0; i < players.at(CPU).getHand().size(); i++){
             playedCard = players.at(CPU).getHand().at(i);
                //check to see if leading or not
                //if leading use spadesBroken function
                //if not leading use contains suit function
                if(trickStart==CPU && !getSpadesBroken()){
                    if(onlySpade(players.at(CPU)))
                        break;
                    if(playedCard.getSuit()!=1)
                        break;
                }
                if(trickStart == CPU && getSpadesBroken())
                    break;
                if(trickStart != CPU &&   containSuit(center[trickStart], players.at(CPU))){
                        if(playedCard.getSuit()==center[trickStart].getSuit())
                        break;
                }
                if(trickStart != CPU &&   !containSuit(center[trickStart], players.at(CPU)))
                    break;
    }
                players.at(CPU).getHand().at(i).setCardNum(0);
                players.at(CPU).getHand().at(i).setSuit(0);
                center[CPU]= playedCard;
                if(CPU==1)
                monitor.displayCard(29, 7, center[CPU].getSuit(),  center[CPU].getCardNum(), 0);
                if(CPU==2)
                monitor.displayCard(39, 2, center[CPU].getSuit(), center[CPU].getCardNum(), 0);
                if(CPU==3)
                monitor.displayCard(49, 7, center[CPU].getSuit(), center[CPU].getCardNum(), 0);
}


void gamePlay::score(player play){

int trickOver = play.getBid()-play.getTricksTaken(); // Calculate the difference   between bid and actually taken.

//Bidding Double Nil (if gets it 200 points other wise -200 points)
if(play.getDoubleNil()){
    if(play.getTricksTaken()==0) //player did get Double Nil successfully
        play.setScore(play.getScore()+200); // add 200 points
    else
        play.setScore(play.getScore()-200);
}
if(play.getBid()==0){ //Bidding Nil (if gets it 100 points other wise -100 points)
    if(play.getTricksTaken()==0) //player did get Nil successfully
        play.setScore(play.getScore()+100); //add 100 points
    else //player didnt get Nil
        play.setScore(play.getScore()-100); //take away 100 points
}
if(trickOver>0){ //player bids more than number of tricks won
    play.setScore((trickOver*-10));  //decrease score by 10 poitns for every   overtrick
}
if(trickOver<0){ //player bids less then number of tricks won
    play.setSandBag(play.getSandBag() + 1); //increase sandbag by 1
    play.setScore((trickOver*(-1))+(10*(play.getBid()))); //increase 10 points   per trick bid on and 1 point per trick over
}
if(play.getSandBag()>10){ //check for sandbagging
    play.setScore(play.getScore()-100);
}
play.setBid(NULL); //reset players bid to NULL
play.setDoubleNil(false); //Player has not yet bid double NILL.
}

void gamePlay::runGame(){

for(int i = 0; i<4; i++){ //Creates 4 players with hands included
    player play;
    players.push_back(play);
}

int count = 0;
int handStart = 0;
while(players.at(0).getScore()<500 || players.at(1).getScore()<500 ||   players.at(2).getScore()<500 || players.at(3).getScore()<500)
{
    int xevent;
    int yevent;
    for(;;){
        mvprintw(3,2,"Click here to bid Double Nil or type out your bid   now.");
        int key = monitor.captureInput();
        monitor.drawBox(7, 4, 3, 2, 0);
        monitor.drawBox(7, 4, 3, 2, 0);
        if (key == -1) {
            xevent = monitor.getMouseEventX();
            yevent = monitor.getMouseEventY();
            break;
        }
        if (key > 0){
        stringstream messageString;
        messageString.str("");
        messageString << "Your bid is now: " << key;
        monitor.bannerBottom(messageString.str());
        players.at(0).setBid(key);
        break;
        }
    }
    if((xevent>=7 && xevent<=10)&&(yevent>=4 && yevent <=6)){
        players.at(0).setDoubleNil(true);
    }

    vector <card> deck = createDeck();

    deal(deck, players);
    displayHand();
    int trickStart = handStart;
    int count = 0;
    while(count<13){
    switch (trickStart)
    {
    case 0: humanPlay(trickStart);
            CPUplay(trickStart,1);
            CPUplay(trickStart,2);
            CPUplay(trickStart,3);
    case 1: CPUplay(trickStart,3);
            humanPlay(trickStart);
            CPUplay(trickStart,1);
            CPUplay(trickStart,2);
    case 2: CPUplay(trickStart,2);
            CPUplay(trickStart,3);
            humanPlay(trickStart);
            CPUplay(trickStart,1);
    case 3: CPUplay(trickStart,1);
            CPUplay(trickStart,2);
            CPUplay(trickStart,3);
            humanPlay(trickStart);
    }
    trickStart = compareCenter(trickStart);
    }
    for(int n =0; n<4;n++)
        score(players.at(n));

    handStart = (handStart +1) % 4;
}
}

Also here is my card.h file as well

using namespace std;

class card { //Create cards for deck
int cardSuit;
int cardNum;
public:

    int getSuit() {return cardSuit;}
    int getCardNum() {return cardNum;}
    void setSuit(int a){ cardSuit = a;}
    void setCardNum(int a){cardNum = a;}
    card (int suit, int number){cardSuit = suit; cardNum = number;}
    card (void){cardSuit = 0; cardNum= 0;}
};
like image 567
Peter Blum Avatar asked Oct 29 '12 18:10

Peter Blum


People also ask

How do I fix linker error?

You can fix the errors by including the source code file that contains the definitions as part of the compilation. Alternatively, you can pass . obj files or . lib files that contain the definitions to the linker.

How do you fix a undefined reference in C++?

You can fix undefined reference in C++ by investigating the linker error messages and then providing the missing definition for the given symbols. Note that not all linker errors are undefined references, and the same programmer error does not cause all undefined reference errors.

What causes linker errors C++?

Linker Errors: These error occurs when after compilation we link the different object files with main's object using Ctrl+F9 key(RUN). These are errors generated when the executable of the program cannot be generated. This may be due to wrong function prototyping, incorrect header files.

What is linker error?

Linker errors occur when the linker is trying to put all the pieces of a program together to create an executable, and one or more pieces are missing. Typically, this can happen when an object file or libraries can't be found by the linker. Fixing linker errors can be tricky.


1 Answers

You've defined a freestanding function

void deal(vector <card> &deck, vector <player> players){
for(int j = 0; j<4; j++){
    for(int i = 0; i<13; i++){
    players.at(j).addCard(deck.at(0));
    deck.erase(deck.begin());
    }
}
}

whereas I suppose you meant to define the member function gameplay::deal

void gameplay::deal(vector <card> &deck, vector <player> players){
//...   
}

As jmp correctly noticed in the comment, the same is true for your score function.

Also, I'd pass players by reference, since you seem to invoke addCard() on the players which means (I suppose) that you need the passed parameter to be altered.

like image 108
Armen Tsirunyan Avatar answered Oct 22 '22 18:10

Armen Tsirunyan