what happened to chess++?

Pages: 12345
You're missing the point. It's not a question of complexity of implementation, it's a question of where to draw the line on the scope of a configuration file.
Yes, you can put all sorts of things on a configuration file, and it may even be easier to put it there rather than in the code. But should it be there? Every aspect you move outside the code changes the exact nature of the program. If the initial state of the board depends on run time values, then the program is no longer a chess game, since in chess you can't have a board completely filled with black knights.

And on another note,
I mean, storing a games state in a file. No... just no.
htirwin wrote:
I just think that game state should be captured by the configuration file.
I don't understand the point of making a plain, regular chess game. That's been done. Can't Chess++ support things a chess game wouldn't normally need? I'm not talking email clients, just simple things like configurable starting state and online multiplayer.
Last edited on
I don't understand the point of a chess game whose initial state is configurable. Wikipedia lists only 7 variations that are exactly like the main game but with different starting positions.
Why not go all the way and make all rules programmable?

Why wouldn't a chess game need online multiplayer?
closed account (10X9216C)
@helios Yet another sensible person.

htirwin wrote:
I concede. It is laughably stupid to load a chess configuration from a file. What was I thinking? Just imagine all of the extra work that would take; just imagine the added complexity. You would never be able to finish it. Saved games and alternate starting configurations are pointless anyways. I mean, this is the type of thing that some random person might do that one time for the 5 mins they fiddle around with it. You are right. You should give up on even trying right from the start and never look back; it's just too difficult to warrant the effort. And I mean, something else is going to be hard-coded anyways. What kind of person would hard-code one thing and not another?

Lol, so much sarcasm. You were making hard coding out to be so much more difficult, when it's actually less work. It is the exact same code, just minus having a parser (which is usually rather complex and you don't end up writing your own but taking another's API).

LB wrote:
I don't understand the point of making a plain, regular chess game.

I thought the point was to demonstrate C++11. Having those configuration files doesn't make it any less plain. In the end it is still chess. If you don't want something plain you shouldn't have picked chess to begin with, there really isn't anywhere to go with it.
Last edited on
Wouldn't you need a parser anyway if you want to save your game?
Saved games and alternate starting configurations are pointless anyways.

I disagree. Saving game is useful feature and with it chess puzzles could be implemented. Also look at this page: http://en.wikipedia.org/wiki/Chess_variant
Now alternative rules does not looks like pointless feature?

I agree the there should be line where we should stop to not make it overengineered.
For example I do not think that the game should support any boards not on plane (except maybe on torus, as in plane where opposite edges are linked) or pieces with very unusual behavior
LB wrote:
I don't understand the point of making a plain, regular chess game. That's been done. Can't Chess++ support things a chess game wouldn't normally need?

Yes, but what you're making is less an extended chess game and more a platform for arbitrary board games with monochromatic pieces. Data goes in configuration files; behaviour goes in code. You're moving too much behaviour out of the code and into a configuration file.

@myesolar
It makes some sense to have a configuration parser -- certain things in any game should be configurable -- but it's stupid to write it yourself when there exist libraries like Boost.Property_tree.
Why is the if() branch written as a lambda which is called on the spot?
https://github.com/cpluspluscom/ChessPlusPlus/blob/master/src/app/ChessPlusPlusState.cpp

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
void ChessPlusPlusState::onLButtonReleased(int x, int y)
{
    if(!board.valid(p)) return;
    if(selected == board.end())
    {
        selected = find(p); //doesn't matter if board.end(), selected won't change then
        if(selected != board.end() && (*selected)->suit != *turn)
        {
            selected = board.end(); //can't select enemy pieces
        }
    }
    else
    {
        if(find(p) == board.end() || (*find(p))->suit != (*selected)->suit)[&]
        {
            {
                auto it = std::find_if(board.pieceCapturings().begin(),
                                       board.pieceCapturings().end(),
                                       [&](board::Board::Movements_t::value_type const &m)
                                       {
                                           return m.first == selected && m.second == p;
                                       });
                if(it != board.pieceCapturings().end())
                {
                    for(auto jt = board.pieceCapturables().begin(); jt != board.pieceCapturables().end(); ++jt)
                    {
                        if(jt->second == p)
                        {
                            if(board.capture(selected, it, jt))
                            {
                                nextTurn();
                                return;
                            }
                        }
                    }
                }
            }
            {
                auto it = std::find_if(board.pieceTrajectories().begin(),
                                       board.pieceTrajectories().end(),
                                       [&](board::Board::Movements_t::value_type const &m)
                                       {
                                           return m.first == selected && m.second == p;
                                       });
                if(it != board.pieceTrajectories().end())
                {
                    if(board.move(selected, it))
                    {
                        nextTurn();
                    }
                }
            }
        }();
        selected = board.end(); //deselect
    }
}
I posted a topic a while back about un-lambda-fying it and nobody knew a good way to.
Last edited on
Shouldn't it be enough to remove the "[&]" and "();"?
That's one of my burnt toast points :P
Shouldn't it be enough to remove the "[&]" and "();"?
No, there's return statements in there T.T
I remember the topic, I think I likened it to a bastardized way of doing goto.
Last edited on
Lachlan Easton... which is fine. in the case you remove those things, it exits the function... which is what it does anyways lol
That would skip line 54 though
Just noticed two of those returns are in other lambdas, the only one that returns from the if-lambda is
1
2
3
4
5
if(board.capture(selected, it, jt))
{
    nextTurn();
    return;
}

Does selected need to be set to board.end() ?
Yes, otherwise you can move opponent's pieces.
Move each block into its own member function, then do
1
2
3
bool temp = find(p) == board.end() || (*find(p))->suit != (*selected)->suit;
if(temp && (test1() || test2()))
    nextTurn();

The fact that the two checks have completely different structures really sucks to extract common behavior.
Last edited on
I think it was a bad idea having Trajectories and Capturings in seperate lists. How are they different conceptually (Other than the fact there's an enemy piece on the tile)?
Also, WTF do it and jt stand for? Iterator and Jiterator?

Edit: For that matter, 'the hell is p? I'm guessing "position" but position of what exactly? Why are we allowing non local single letter variable names!? Edit2: And it looks like other things are naming p as well...
Last edited on
I like helios's solution, but if Trajectories and Capturings weren't separate I'd go for something like
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
34
35
36
if(!board.valid(p)) return;
auto piece_at_p = find(p);
if(selected == board.end())
{
    selected = piece_at_p; //doesn't matter if board.end(), selected won't change then
    if(selected != board.end() && (*selected)->suit != *turn)
    {
        selected = board.end(); //can't select enemy pieces
    }
    return;
}
// If spot is empty or spot contains enemy
if(piece_at_p == board.end() || (*piece_at_p)->suit != (*selected)->suit)
{
    // We're allowed to use Boost right?
    BOOST_SCOPE_EXIT(&selected, &board)
    {// Deselect when all is said and done, see http://www.boost.org/doc/libs/1_55_0/libs/scope_exit/doc/html/scope_exit/tutorial.html 
        selected = board.end();
    }BOOST_SCOPE_EXIT_END
    
    auto selected_pos = std::make_pair(selected, p);
    auto destination  = std::find(board.pieceTrajectories().begin(),
                                  board.pieceTrajectories().end(),
                                  selected_pos);
    if(destination == board.pieceTrajectories().end()) return;

    auto capturing = std::find_if(board.pieceCapturables().begin(),
                                  board.pieceCapturables().end(),
                                  [&](board::Board::Movements_t::value_type const &m)
                                  {
                                      return m.second == p;
                                  });
    if((capturing != board.pieceCapturables().end() && board.capture(selected, destination, capturing))
    || (board.move(selected, destination)))
        nextTurn();
}

(untested, just an example)

Edit: on further reflection, why don't pieces know where their own Trajectories (or do they?)?
Last edited on
Trajectories and Capturings have to be separate because of pawns. Pawns can't move the same way they capture.

Originally pieces did know their own trajectories and capturings but it became a problem so they were relocated to be managed by the board instead.
Also, WTF do it and jt stand for? Iterator and Jiterator?
"Jterator" is obviously how they spell it in Nordic languages.
Pages: 12345