2017-05-27 59 views
0

我正在製作一個象棋遊戲並嘗試向矢量添加有效位置。我正在製作的具體作品是騎士,而根據騎士在棋盤上的位置,我已經硬編碼的一些位置不在棋盤上。我的座標系對行使用A-H,對列使用0-8。C++使用find_first_not_of(char *)去除矢量元素

我定義了有效字符(A-H和0-8)的字符數組,並且我使用find_first_not_of來標識並刪除無效的座標對。例如:

有效期:A1

無效:3 - 刪除此

問:爲什麼我的函數刪除一些座標對是無效的,不適合的模式,但不是別人?例如,使用位置A2作爲輸入,@ 4和@ 0被成功刪除。但是剩餘的可用位置是C3,C1,B4,?3,B0,?1。

如果輸入是H2,那麼F3,F1,G0,G4是可用的位置,並且J3,J1,I4,I0被成功移除,只給出期望結果的有效位置。

問題:由於刪除無效位置的方法相同,我的某些時間和其他時間的輸出正確。

父類Piece.cpp:

char Piece::valids[16] = { 
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 
    '0', '1', '2', '3', '4', '5', '6', '7' 
}; 

void Piece::removeInvalids(vector<string>& v) 
{ 
    for (short i = 0; i < v.size(); i++) 
    { 
     string s = v.at(i); 
     size_t found = s.find_first_not_of(valids); 
     if (found != string::npos) 
     { 
      cout << v.at(i) << endl; 
      swap(v.at(i), v.back()); 
      v.pop_back(); 
     } 
    } 
} 

兒童類Knight.h:

vector<string> getAvailPositions(Piece **all) 
{ 
    vector<string> v; 
    stringstream ss; 
    ss << static_cast<char>(position[0] + 2) 
      << static_cast<char>(position[1] + 1); 
    v.push_back(ss.str()); 
    stringstream ss2; 
    ss2 << static_cast<char>(position[0] + 2) 
      << static_cast<char>(position[1] - 1); 
    v.push_back(ss2.str()); 
    stringstream ss3; 
    ss3 << static_cast<char>(position[0] + 1) 
      << static_cast<char>(position[1] + 2); 
    v.push_back(ss3.str()); 
    stringstream ss4; 
    ss4 << static_cast<char>(position[0] - 1) 
      << static_cast<char>(position[1] + 2); 
    v.push_back(ss4.str()); 
    stringstream ss5; 
    ss5 << static_cast<char>(position[0] + 1) 
      << static_cast<char>(position[1] - 2); 
    v.push_back(ss5.str()); 
    stringstream ss6; 
    ss6 << static_cast<char>(position[0] - 1) 
      << static_cast<char>(position[1] - 2); 
    v.push_back(ss6.str()); 
    stringstream ss7; 
    ss7 << static_cast<char>(position[0] - 2) 
      << static_cast<char>(position[1] - 1); 
    v.push_back(ss7.str()); 
    stringstream ss8; 
    ss8 << static_cast<char>(position[0] - 2) 
      << static_cast<char>(position[1] + 1); 
    v.push_back(ss8.str()); 
    removeInvalids(v); 
    return v; 
} 

請讓我知道是否應該做出這個帖子的任何更改爲您更好地幫助我, 謝謝。

+1

我建議使用位置的整數座標(例如從1到8的行和從1到8的列)而不是字符。這樣,您可以輕鬆計算板外位置並更輕鬆地編碼運動。爲了輸出位置並移動到用戶,您可以將這些轉換爲A-H和1-8作爲字符串。 – Gerriet

+0

你可以包括你的位置數組和你的valids字符串嗎?編輯:我看到'valids'現在在那裏。 –

+0

串位置;在Piece.h中。該變量的值將始終爲A0-H7。我在編輯中添加了valids數組到OP中。 –

回答

0

你應該重新考慮你的設計 - 這是複雜和低效的。這個怎麼樣:

typedef std::array<char, 2> Position; 

vector<Position> Knight::getAvailPositions() const 
{ 
    vector<Position> v; 
    v.reserve(8); 
    for (char a : {2, -2}) { 
     for (char b : {1, -1}) { 
      v.emplace_back(position[0] + a, position[1] + b); 
      v.emplace_back(position[0] + b, position[1] + a); 
     } 
    } 
    removeInvalids(v); 
    return v; 
} 

bool invalid(Position p) 
{ 
    return p[0] < 'A' || p[0] > 'H' || p[1] < '0' || p[1] > '7'; 
} 

void Piece::removeInvalids(vector<Position>& v) 
{ 
    v.erase(std::remove_if(v.begin(), v.end(), invalid), v.end()); 
} 

這避免了絕對噸是全部這些字符串& stringstreams躲在裏面的動態內存分配。現在您只需撥打一個getAvailPositions()電話。另外它的代碼更少。

+0

我主要擔心功能,性能對於此入門級C++課程中的數據結構而言確實不是問題。但是,謝謝你是解決方案,我會看看它是否解決了我的問題。給我一段時間來實施它,我會讓你知道。我也很欣賞這種洞察力。 –

0

它只是正確的原因有時是因爲你將當前的矢量元素與最後一個元素交換,然後移動到下一個元素。如果向量末尾的元素無效,那麼您只需將一個無效元素滑入矢量中間並跳過它即可。

在你的例子中,當它刪除@ 4時,它將?3拖入向量的中間,然後繼續查看b0,甚至沒有提問?3。如果您想繼續按照現在的方式使用代碼,您將需要重新修改從矢量中間刪除元素的邏輯。

儘管正如其他答案指出的那樣,編寫此代碼的方法更爲有效。

0

D.R你是我的代碼是正確的,這似乎加入這一行來解決這個問題:

void Piece::removeInvalids(vector<string>& v) 
{ 
    for (short i = 0; i < v.size(); i++) 
    { 
     string s = v.at(i); 
     size_t found = s.find_first_not_of(valids); 
     if (found != string::npos) 
     { 
      cout << v.at(i) << endl; 
      swap(v.at(i), v.back()); 
      v.pop_back(); 
      i = 0; 
     } 
    } 
} 

使它重新啓動循環。我現在要保持這種方式,因爲我一直到6月2日才完成這個項目並將它記錄下來。我相信我的老師會向班級解釋這是多麼可怕的學習體驗,但我們還沒有深入地討論過關於性能的問題,這將成爲下一門C++課程的重點。當我拿CSC-17C並調整演奏時,我可以修改這個程序。

謝謝大家的快速回復!