2012-11-28 33 views
1

所以我有兩個並排的遊戲。鏈接/集成問題。我需要一個方向去哪裏?

proj2/main.cpp (main that gets run that then can call either game) 
proj2/spades/display.cpp 
proj2/spades/gameplay.cpp 
proj2/spades/otherFiles.cpp 
proj2/hearts/display.cpp (this is the same display class as in the spades game with the same functions just sightly altered.) 
proj2/hearts/hearts.cpp 
proj2/hearts/otherFiles.cpp 

基本上什麼事情是我試圖整合2場,1我創建,另一個使用相同display.cpp和display.h文件稍有改變。爲了做到這一點,我創建了2個獨立的命名空間,心臟和黑桃。我編譯的所有東西都很好,但一些.cpp文件沒有正確鏈接,並且出現如下錯誤。

./gamePlay.o: In function `__static_initialization_and_destruction_0(int, int)': 
gamePlay.cpp:(.text+0x396): undefined reference to `spades::display::display()' 
./gamePlay.o: In function `__tcf_3': 
gamePlay.cpp:(.text+0x480): undefined reference to `spades::display::~display()' 
./gamePlay.o: In function `spades::gamePlay::storeBid(std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)': 
gamePlay.cpp:(.text+0x1507): undefined reference to `spades::display::captureInput()' 

我在這裏做錯了什麼?

下面是一些我使用的文件。讓我知道,如果有任何我應該補充。 (不想臃腫這個帖子了,比我有)

gameplay.cpp

#include <iostream> 
#include <sys/ioctl.h> 
#include <cstdio> 
#include <unistd.h> 
#include <locale.h> 
#include <ncursesw/ncurses.h> 
#include <fstream> 


#include "gamePlay.h" 
#include <cstdlib> 
#include <sstream> 
#include <ctime> 
namespace spades { 
vector <spades::player> players(4); 
vector <spades::card> deck(52); 
spades::display monitor; 
spades::card center[4]; 

vector <spades::card> gamePlay::getDeck(){return deck;} 
vector <spades::player> gamePlay::getplayers(){return players;} 

//sorts the cards in the players hand into diamonds, clubs, hearts, spades 
void gamePlay::handSort(){ 
    int spades[13]; 
    int hearts[13]; 
    int clubs[13]; 
    int diamonds[13]; 
    int index; 
    int i; 
    for(i=0; i<13; i++){ //determines the card number and places them into corresponding indexes 
     index = (players.at(0).hand.at(i).getCardNum()+11)%13; //cause the cards to be placed based on their number with 2 being index 0 and 1(ace) being index 12 
     switch(players.at(0).hand.at(i).getSuit()) 
     { 
     case 1: spades[index] = 1; 
     break; 
     case 2: hearts[index] = 1; 
     break; 
     case 3: clubs[index] = 1; 
     break; 
     case 4: diamonds[index] = 1; 
     break; 
     default: mvprintw(3,2,"!!!!!!!we have a problem!!!!!!!!!!"); 
     break; 
     } 
    } 
    i = 0; 
    while(i<13){ //being placing the ordered cards back into the players hand 
     int j = 0; 
     while(j < 13){ 
      if(diamonds[j] == 1){ //if a card has been placed in this index for the diamonds only array 
       if(j+2 == 14) //if the card is an ace 
        players.at(0).hand.at(i).setCardNum(1); 
       else 
        players.at(0).hand.at(i).setCardNum(j+2); //add 2 to each index to get the card number 
       players.at(0).hand.at(i).setSuit(4); 
       i++; 
      } 
      j++; 
     } 
     j = 0; 
     while(j < 13){ 
      if(clubs[j] == 1){ 
       if(j+2 == 14) 
        players.at(0).hand.at(i).setCardNum(1); 
       else 
        players.at(0).hand.at(i).setCardNum(j+2); 
       players.at(0).hand.at(i).setSuit(3); 
       i++; 
      } 
      j++; 
     } 
     j = 0; 
     while(j < 13){ 
      if(hearts[j] == 1){ 
       if(j+2 == 14) 
        players.at(0).hand.at(i).setCardNum(1); 
       else 
        players.at(0).hand.at(i).setCardNum(j+2); 
       players.at(0).hand.at(i).setSuit(2); 
       i++; 
      } 
      j++; 
     } 
     j = 0; 
     while(j < 13){ 
      if(spades[j] == 1){ 
       if(j+2 == 14) 
        players.at(0).hand.at(i).setCardNum(1); 
       else 
        players.at(0).hand.at(i).setCardNum(j+2); 
       players.at(0).hand.at(i).setSuit(1); 
       i++; 
      } 
      j++; 
     } 
    } 
} 

//compares the center pile of 4 played cards to determine who wins the trick 
int gamePlay::compareCenter(int leadplayer){ 
    int highest = center[leadplayer].getCardNum(); 
    if(center[leadplayer].getCardNum() == 1) 
     highest = 14; 
    int suit = center[leadplayer].getSuit(); 
    int player = leadplayer; 

    for(int i = leadplayer+1; i < leadplayer+4; i++) 
    { 
     if(center[i%4].getSuit() == 1) 
      setSpadesBroken(true); 
     if((suit != 1) && (center[i%4].getSuit() == 1)) 
     { 
      player = i%4; 
      suit = 1; 
      highest = center[i%4].getCardNum(); 
     } 
     if(suit == center[i%4].getSuit()){ 
      if(center[i%4].getCardNum() == 1){ 
       player = i % 4; 
       highest = 14; 
      } 
      if(highest < center[i%4].getCardNum()) 
      { 
       player = i%4; 
       highest = center[i%4].getCardNum(); 
      } 
     } 
    } 
    players.at(player).setTricksTaken(players.at(player).getTricksTaken()+1); //increments the trick count of the winning player 
    return player; //return the player who won to determine who goes first next turn 
} 

//Create the deck of 52 cards by setting the suit and number of each card to a nonzero integer 
void gamePlay::createDeck() { 
    for(int j = 0; j < 52; j++) 
    { 
     deck.at(j).setCardNum((j%13)+1); 
     deck.at(j).setSuit((j/13)+1); 
    } 
    random_shuffle(deck.begin(), deck.end()); 
} 

//deal out 13 cards to each player by setting the 
void gamePlay::deal(vector <spades::card> &newdeck, vector <spades::player> &newplayers){ 
    for(int i = 0; i<52; i++){ 
     newplayers.at(i/13).addCard(newdeck.at(i)); 
     newdeck.at(i).setSuit(0); 
     newdeck.at(i).setCardNum(0); 
    } 
} 

//determines if the player still has a card of the same suit in their hand as the leading card played 
bool gamePlay::containSuit(spades::card lead, spades::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; 
} 

//determines if the player has only spades cards left in their hand 
bool gamePlay::onlySpade(spades::player play){ 
    for(int i = 0; i<play.getHand().size(); i++){ 
     if(play.getHand().at(i).getSuit()!=1) 
      return false; 
    } 
    return true; 
} 

//determines if the position the player is clicking on the screen actually points to a playable card 
//and then returns the position of that card based on the player's hand vector of type <card> 
int gamePlay::handCheck(int xevent, int yevent, vector <spades::player> players, int trickStart){ 
    int i = xevent/6; 
    //first check to find the card on the display 
    if(i>=0 && i<players.at(0).getHand().size() && yevent>17 && yevent<23 && 
      players.at(0).getHand().at(i).getSuit() != 0 && 
      players.at(0).getHand().at(i).getCardNum() != 0) 
    { 
     spades::card playedCard = players.at(0).getHand().at(i); 
     //check to see if leading the current round or not and if spades are "broken" 
     if(trickStart==0 && !getSpadesBroken()){ 
      if(onlySpade(players.at(0))) 
       return i; 
      else if(playedCard.getSuit() != 1) 
       return i; 
      else 
       return (-1); 
     } 
     if(trickStart == 0 && getSpadesBroken()) 
      return i; 
     //if not leading, then call the containsuit method to see if your hand contains one of similar suit 
     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 (-1); 
    } 
    mvprintw(4,3,"invalid card"); 
    return (-1); 
} 

//draws the cards in the player's hand if it contains a valid card, erase the card otherwise if invalid 
void gamePlay::displayHand(){ 
    int offset = 0; 
    for(int i =0; i<players.at(0).getHand().size(); i++){ 
     if(players.at(0).getHand().at(i).getSuit() != 0) 
      monitor.displayCard(offset, 17, players.at(0).getHand().at(i).getSuit(), players.at(0).getHand().at(i).getCardNum(), 0); 
     else 
      monitor.eraseBox(offset, 17, 6, 5); 
     offset+=6; 
    } 
} 
void gamePlay::displayAdd(){ 
    vector <string> lines; 
    int count12 = 0; 
    string line; 
    ifstream myfile ("advertisement.txt"); 
    if (myfile.is_open()) 
    { 
     while (! myfile.eof()) 
     { 
       getline (myfile, line); 
       lines.push_back(line); 
       count12++; 
     } 
     myfile.close(); 
     int random1 = rand() % 6; 
     monitor.bannerBottom(lines.at(random1)); 
    } 
    else{ 
      monitor.bannerBottom("Unable to open Advertisement file."); 
    } 

} 
//determins the position of a mouse click and sends that to handcheck(), and then sends the card to the center pile array to be scored 
void gamePlay::humanPlay(int trickStart){ 
    int xevent, yevent; 
    for(;;){ 
     mvprintw(3,2,"Please choose a card to play."); 
     int key = monitor.captureInput(); 
     // if a mouse click occurred 
     if (key == -1) { 
      xevent = monitor.getMouseEventX(); 
      yevent = monitor.getMouseEventY(); 
      int handCh = handCheck(xevent, yevent, players, trickStart); 
      if(handCh != (-1)){ //if the card is valid 
       spades::card played = players.at(0).getHand().at(handCh); 
       players.at(0).hand.at(handCh).setCardNum(0); 
       players.at(0).hand.at(handCh).setSuit(0); 
       center[0]= played; 
       monitor.displayCard(39, 12, center[0].getSuit(), center[0].getCardNum(), 0); 
       displayHand(); 
       //playedCards++; //Update Global Variable---- NEED TO HAVE THIS INITIATED GLOBALLY. 
       break; 
      } 
      else 
       mvprintw(4,3,"invalid card"); 
     } 
    } 
} 

//loops through a computer players hand and checks to see if the random card is playable within the rules of the game 
void gamePlay::CPUplay(int trickStart, int CPU){ 
    bool goodCard = false; 
    spades::card playedCard =players.at(CPU).getHand().at(0); 
    int i; 
    for(i = 0; i < players.at(CPU).getHand().size(); i++){ 
     if(players.at(CPU).getHand().at(i).getSuit() != 0 && 
       players.at(CPU).getHand().at(i).getCardNum() != 0){ 
      playedCard = players.at(CPU).getHand().at(i); 
      //check to see if leading or not 
      if(trickStart==CPU && !getSpadesBroken()){ 
       if(onlySpade(players.at(CPU))) 
        break; 
       if(playedCard.getSuit()!=1) 
        break; 
      } 
      if(trickStart == CPU && getSpadesBroken()) 
       break; 
      //if not leading use contains suit function 
      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).hand.at(i).setCardNum(0); 
    players.at(CPU).hand.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); 
} 

//scores each team with the player being teamed with CPU 2 and the other team being CPU 1 and CPU 3 
void gamePlay::score(spades::player &play, spades::player &play2){ 
    int trickOver = play.getTricksTaken()-play.getBid(); // Calculate the difference between bid and actually taken. 
    if(play.getBid() == NULL) 
     trickOver = 0; 
    int trickOver2 = play2.getTricksTaken()-play2.getBid(); // Calculate the difference between bid and actually taken. 
    int totalBid = play.getBid()+play2.getBid(); 
    int totalTrick = trickOver+trickOver2; 
    //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); 
    } 
    else 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(totalTrick < 0){ //player bids more than number of tricks won 
     play.setScore(play.getScore()+(totalBid*(-10))); //decrease score by 10 poitns for every overtrick 
    } 
    else if(totalTrick >= 0){ //player bids less then number of tricks won 
     play.setSandBag(play.getSandBag() + totalTrick); //increase sandbag by 1 
     play.setScore(play.getScore()+totalTrick+(10*totalBid)); //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.setSandBag(play.getSandBag()-10); 
    } 
    play.setBid(NULL); //reset players bid to NULL 
    play2.setBid(NULL); //reset players bid to NULL 
    play.setTricksTaken(0); 
    play2.setTricksTaken(0); 
    play.setDoubleNil(false); //Player has not yet bid double NILL. 
} 

//loops infinitely until a mouse click or key input is detected, then sets bid accordingly 
void gamePlay::storeBid(stringstream &msg){ 
    int xevent; 
    int yevent; 
    for(;;){ 
     mvprintw(3,2,"Click the box bid Double Nil or type out your bid now. \n Use the keys 1-9, a for 10, b for 11, c for 12, and d for 13."); 
     int key = monitor.captureInput(); 
     monitor.drawBox(2, 5, 3, 2, 0); 
     xevent = monitor.getMouseEventX(); 
     yevent = monitor.getMouseEventY(); 
     if (key == -1) 
      if((xevent>=2 && xevent<4)&&(yevent>=5 && yevent <7)){ 
       msg.str(""); 
       msg << "Your bid: double nil"; 
       monitor.bannerTop(msg.str()); 
       players.at(0).setDoubleNil(true); 
       break; 
      } 
      else{ 
       msg.str(""); 
       msg << "Your bid is horrible. Bid again!!!!"; 
       monitor.bannerTop(msg.str()); 
      } 
     if ((key-48) >= 0 && (key-48) <= 9){ 
      msg.str(""); 
      msg << "Your bid: " << (key-48); 
      monitor.bannerTop(msg.str()); 
      players.at(0).setBid(key-48); 
      break; 
     } 
     else if(key>=97 && key<=100){ 
      msg.str(""); 
      msg << "Your bid: " << (key-87); 
      monitor.bannerTop(msg.str()); 
      players.at(0).setBid(key-87); 
      break; 
     } 
     else if(key!=0 && key!=-1){ 
      msg.str(""); 
      msg << "Your bid is horrible. Bid again!!!!"; 
      monitor.bannerTop(msg.str()); 
     } 
    } 
    monitor.eraseBox(1, 1, 62, 16); 
} 

//main function that runs the entire game 
void gamePlay::runGame(){ 
    double startTime = clock(); 
    stringstream messageString; 
    srand(time(NULL)); 

    int count; 
    int handStart = 0; 
    int trickStart; 
    while(players.at(0).getScore()<500 && players.at(1).getScore()<500) 
    { 
     createDeck(); 
     deal(deck, players); //deal out 13 cards to each player 
     handSort(); // sort the human players hand 
     displayHand(); 

     storeBid(messageString); //asks for bid 

     //sets the bid randomly between 2-4 for each computer player 
     players.at(1).setBid(rand()%3+2); 
     players.at(2).setBid(rand()%3+2); 
     players.at(3).setBid(rand()%3+2); 
     //displays the current bid and scores of each team 
     messageString << " Partner: " << (players.at(2).getBid()) 
     << " CPU 1: " << players.at(1).getBid() 
     << " CPU 3: " << players.at(3).getBid() 
     << " Team Score = " << players.at(0).getScore() 
     << " Enemy Score = " << players.at(1).getScore(); 
     monitor.bannerTop(messageString.str()); 
     displayAdd(); 
     trickStart = handStart; 
     count = 0; 
     setSpadesBroken(false); 
     while(count<13){ // simulates the different cases where the human player plays 1st, 2nd, 3rd, last 
      bool success = true; 
      switch (trickStart) 
      { 
      case 0: humanPlay(trickStart); 
      CPUplay(trickStart,1); 
      CPUplay(trickStart,2); 
      CPUplay(trickStart,3); 
      break; 
      case 3: CPUplay(trickStart,3); 
      humanPlay(trickStart); 
      CPUplay(trickStart,1); 
      CPUplay(trickStart,2); 
      break; 
      case 2: CPUplay(trickStart,2); 
      CPUplay(trickStart,3); 
      humanPlay(trickStart); 
      CPUplay(trickStart,1); 
      break; 
      case 1: CPUplay(trickStart,1); 
      CPUplay(trickStart,2); 
      CPUplay(trickStart,3); 
      humanPlay(trickStart); 
      break; 
      default: mvprintw(3,2,"!!!!we have a problem!!!!"); 
      success = false; 
      break; 
      } 
      monitor.eraseBox(3, 2, 20, 2); 

      for(;;){//pause to wait for an acknowledgment mouse click 
       int key = monitor.captureInput(); 
       monitor.eraseBox(3, 2, 30, 4); 
       mvprintw(3,2,"click anywhere to continue"); 
       if(key == -1){ 
        break; 
       } 
      } 
      //if no errors appear, display the tricks taken 
      if(success){ 
       monitor.eraseBox(1, 1, 62, 16); 
       trickStart = compareCenter(trickStart); 
       messageString.str(""); 
       messageString << "Your Tricks= " << players.at(0).getTricksTaken() 
       << " Partner= " << players.at(2).getTricksTaken() 
       << " CPU 1= " << players.at(1).getTricksTaken() 
       << " CPU 3= " << players.at(3).getTricksTaken(); 
       displayAdd(); 
       monitor.bannerAboveBottom(messageString.str()); 
       count++; 
      } 
     } 

     //score the round and tally up for each team 
     for(int n =0; n<2;n++) 
      score(players.at(n),players.at(n+2)); 
     messageString.str(""); 
     monitor.bannerTop(messageString.str()); 
     messageString << "Your Tricks = " << players.at(0).getTricksTaken() 
     << " Partner = " << players.at(2).getTricksTaken() 
     << " CPU 1 = " << players.at(1).getTricksTaken() 
     << " CPU 3 = " << players.at(3).getTricksTaken(); 
     handStart = (handStart +1) % 4; 
    } 
    double endTime = clock(); 

} 


} 

gameplay.h

#include "player.h" 
#include "display.h" 

#ifndef gamePlay_H 
#define gamePlay_H 
namespace spades { 
using namespace std; 

class gamePlay{ 

    bool spadesBroken; 

public: 
    vector <spades::card> getDeck(); 
    vector <spades::player>getplayers(); 
    bool getSpadesBroken() {return spadesBroken;} 
    void setSpadesBroken(bool b){spadesBroken = b;} 

    int compareCenter(int leadplayer); 
    void createDeck(); 
    void deal(vector <spades::card> &deck, vector <spades::player> &players); 
    void handSort(); 
    bool containSuit(spades::card lead, spades::player players); 
    bool onlySpade(spades::player play); 

    int handCheck(int xevent, int yevent, vector <spades::player> players, int trickStart); 

    void displayHand(); 
    void displayAdd(); 
    void humanPlay(int trickStart); 
    void CPUplay(int trickStart, int CPU); 
    void score(spades::player &play, spades::player &play2); 
    void storeBid(stringstream &msg); 
    void runGame(); 

}; 
} 
#endif 

player.h

#include <iostream> // Stream declarations 
#include <vector> //Vectors used to store deck and players hands 
#include <string> //String declarations 
#include <algorithm> //Shuffle Method 
#include "card.h" 

#ifndef PLAYER_H 
#define PLAYER_H 
namespace spades { 
using namespace std; 

class player { 


    int score; //total score 
    int bid; //bid for that round 
    int tricksTaken; //score for thast round 
    int sandBag; //the number of points you win, more than what you bid, every 10th bag = -100 
    bool doubleNil; 
    //vector <card> hand; 

public: 
    player(); 
    vector <card> hand; 

    int getSandBag(){return sandBag;} 
    bool getDoubleNil() {return doubleNil;} 
    int getScore() {return score;} 
    int getBid() {return bid;} 
    int getTricksTaken() {return tricksTaken;} 
    vector<card> getHand() {return hand;} 

    void setSandBag(int i) {sandBag = i;} 
    void setBid(int i) {bid = i;} 
    void setTricksTaken(int i) {tricksTaken=i;} 
    void setScore(int i) {score = i;} 
    void setDoubleNil(bool i) {doubleNil = i;} 

    //add card to end of vector 
    void addCard(card b); 
    void removeCard(card a); 

}; 
} 
#endif 

player.cpp

#include <iostream> // Stream declarations 
#include <vector> //Vectors used to store deck and players hands 
#include <string> //String declarations 
#include <algorithm> //Shuffle Method 
#include <sys/ioctl.h> 
#include <cstdio> 
#include <unistd.h> 
#include <locale.h> 
#include <ncursesw/ncurses.h> 
#include "player.h" 
namespace spades { 
using namespace std; 


player::player() { 
    score =0; //total score 
    bid = NULL; //bid for that round 
    tricksTaken = 0; //score for thast round 
    sandBag = 0; //the number of points you win, more than what you bid, every 10th bag = -100 
    doubleNil = false; 
    for(int i=0; i<13; i++) 
     hand.push_back(card()); 
} 

void player::addCard(spades::card b){ 
    for (int i=0; i<hand.size(); i++){ 
     //compare card being played to the ones in your hand to search and determine which one to erase 
     if((hand.at(i).getCardNum() == 0) && 
      (hand.at(i).getSuit() == 0)) 
     { 
      hand.at(i).setCardNum(b.getCardNum()); 
      hand.at(i).setSuit(b.getSuit()); 
      return; 
     } 
    } 
} 

void player::removeCard(spades::card a) { 
    for (int i=0; i<hand.size(); i++){ 
     //compare card being played to the ones in your hand to search and determine which one to erase 
     if((hand.at(i).getCardNum() == a.getCardNum()) && 
      (hand.at(i).getSuit() == a.getSuit())) 
     { 
      hand.at(i).setCardNum(0); 
      hand.at(i).setSuit(0); 
      return; 
     } 
    } 
} 
} 
+1

tl;你的答案可能是[here](http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do- i-fix) –

回答

1

什麼是您的鏈接線是什麼樣子?它看起來像當你連接時,你錯過了spades.o?

如果不是它,使用nm命令,看看有什麼符號spades.o是提供 - 它總是可以 你已經typo'd一個命名空間名稱或東西:

nm -C spades.o | grep 'display::.*display' 

(該-C選項應該將nm納入C++/demangled模式 - 如果它不適合nm,則在grep之前在管道鏈中添加「C++ filt」或「dem」步驟)。

+0

這裏是我的Makefile'CC = g ++
all:compile
\t find。 -name'* .o'-print0 | xargs -0 $(CC)-lncursesw -o myExecutable
compile:
\t find。 -name'* .cpp'-print0 | xargs的-0 $(CC)-c
清潔:
\t發現。 -iname'* .o'-print0 | xargs的-0 rm' –

+0

好吧,這看起來像它應該工作,我認爲,儘管這是您所需要的有點太複雜。 所以請嘗試使用納米,看看什麼是符號在你spades.o和比較,與你的鏈接告訴你丟失... –

相關問題