Is there are better alternative than this?

       https://github.com/LB--/ChessPlusPlus/blob/lb-refactor/src/AppStateGame.cpp#L76
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
else
{
    if(board.at(p) == nullptr || board.at(p)->suit != selected->suit)[&]
    {
        if(selected->captures.find(p) != selected->captures.end()) //if #1
        {
            for(auto it = board.Captures().cbegin(); it != board.Captures().cend(); ++it)
            {
                if(it->second == p)
                {
                    board.capture(selected->pos, it);
                    nextTurn();
                    return; //return from lambda, not enclosing function
                }
            }
        }
        if(selected->trajectory.find(p) != selected->trajectory.end()) //if #2
        {
            board.move(selected->pos, p);
            nextTurn();
        }
    }();
    selected = nullptr;
}
I'm calling a capture-by-reference lambda and returning from it under certain conditions to skip evaluation of the second if statement, which may or may not be true but should not be evaluated under certain circumstances. I still need the second if to execute regardless of if the first executes, except in the case where I return of course. I can't return from the entire enclosing function because I have code after the lambda and after the else that should still execute.

My question is, since this seems like poor design, is there a better alternative? This seems like the easiest way to do it, but I think there should be a better way.

Eventually this will be refactored and abstracted anyway, but I'm getting the rough outline of how it should work down first before abstracting it to be more modular.

EDIT: and by 'better solution', I mean 'without abusing lambdas' - you could get arrested for that.
Last edited on
closed account (o1vk4iN6)
Since we are abusing the lambda anyways :V.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

else
{
    auto DoCondition = [&]()
        {
            if(selected->trajectory.find(p) != selected->trajectory.end()) //if #2
            {
                board.move(selected->pos, p);
                nextTurn();
            }
            return false;
        };

    if(board.at(p) == nullptr || board.at(p)->suit != selected->suit)
    {
        if(selected->captures.find(p) != selected->captures.end()) //if #1
        {
            for(auto it = board.Captures().cbegin(); it != board.Captures().cend() || DoCondition(); ++it)
            {
                if(it->second == p)
                {
                    board.capture(selected->pos, it);
                    nextTurn();
                    break;
                }
            }
        }
        
    }

    selected = nullptr;
}
By 'better solution' I meant 'without abusing lambdas', I should have clarified. Also I can't understand how your solution does the same thing as mine? It looks like you're evaluating if #2 every iteration of the loop, which will definitely cause problems.
Last edited on
closed account (o1vk4iN6)
Short circuit, DoCondition() will only be called if it != board.Captures().cend() is false (the end of the loop).
Ah, of course - for some reason I hadn't realized that. But yeah, I think they can arrest us for lambda abuse.
Last edited on
Topic archived. No new replies allowed.