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;}
};
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With