在拼图匹配游戏逻辑中使用STL算法

时间:2018-04-15 23:44:14

标签: c++ algorithm c++11

我做了一个瓷砖匹配游戏。它有一个Board对象,它包含一个卡对象向量并将事件委托给它们。董事会事件处理中包含以下代码:

// Counting logic-driving card states
int cardFaceUpCounter = 0;
std::vector<Card*> faceUpCards(2);

// Checking for logic-driving card states 
for (auto& card : this->boardMatrix)
{
    if (this->isCardInAnim(&card))
    {
        return;
    }
    if (this->isCardFaceUp(&card))
    {
        ++cardFaceUpCounter;
        faceUpCards[cardFaceUpCounter - 1] = &card;
    }       
}

我刚刚在Pluralsight上完成了Kate Gregory的Beautiful C ++学习。 她认为我们应该避免编写循环,并应尽可能使用STL算法标题。 我发现她的论点和方法非常引人注目,因此我试图重构我最新的宠物项目以反映她的教诲。

上面的示例是我无法看到如何使用STL算法更好地传达意图并保持性能 - 单循环而不是两个或三个循环,尽管隐藏在算法调用中。 / p>

第二个问题是如果使用STL算法无法实现单循环效率,为了便于阅读,您仍然更喜欢这种方法。

2 个答案:

答案 0 :(得分:1)

这是我在想的一个例子。

int cardFaceUpCounter = 0;
std::vector<Card*> faceUpCards(2);

if (std::any_of(boardMatrix.begin(), boardMatrix.end(), [&](auto& card) {
    if (isCardFaceUp(&card))
        faceUpCards[cardFaceUpCounter++] = &card;

    return isCardInAnim(&card);    
})) return;

答案 1 :(得分:1)

使用range-v3,它将类似于:

std::vector<Card*> faceUpCards = this->boardMatrix
    | ranges::view::take_while([this](const auto& card){ return !isCardInAnim(&card);})
    | ranges::view::filter([this](const auto& card){ return isCardFaceUp(&card); })
    | ranges::view::transform([](auto& e){ return &e; });

只有STL,我会做类似的事情:

auto it = std::find_if(boardMatrix.begin(), boardMatrix.end(),
                       [this](const auto& card){ return isCardInAnim(&card);});
std::vector<Card*> faceUpCards(std::distance(boardMatrix.begin(), it), nullptr);
std::transform(boardMatrix.begin(), it,
               faceUpCards.begin(),
               [](auto& card){ return &card;});
faceUpCards.erase(std::remove_if(faceUpCards.begin(), faceUpCards.end(),
                                [this](const auto& card){ return !isCardFaceUp(&card); }),
                  faceUpCards.end());