C ++使用find_first_not_of(char *)

时间:2017-05-27 06:45:59

标签: c++ chess

我正在制作国际象棋游戏并试图将有效位置添加到矢量中。我正在处理的具体部分是骑士,而且我已经硬编码的一些位置不在棋盘上,这取决于骑士在棋盘上的位置。我的坐标系使用A-H表示行,0-8表示列。

我已经定义了一个有效字符的字符数组(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;
}

如果对此帖有任何更改,请告诉我,以便更好地帮助我,谢谢。

3 个答案:

答案 0 :(得分: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()个电话只有一个。加上它的代码更少。

答案 1 :(得分:0)

它有时唯一正确的原因是因为你将当前向量元素与末尾的元素交换,然后继续移动到下一个元素。如果向量末尾的元素无效,那么您只是将无效滑入向量的中间并跳过它。

在你的例子中,当它移除@ 4时,它将?3拉到向量的中间,然后继续观察b0,甚至没有提问?3。如果你想按照现在的方式继续使用代码,你将需要重新设计从向量中间删除元素的逻辑。

虽然正如其他答案所指出的那样,但是有更有效的方式来编写这段代码。

答案 2 :(得分: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并调整性能时,我可以修改这个程序。

谢谢大家的快速回复!