Guide me through building a chess program

Discussion of chess software programming and technical issues.

Moderator: Ras

Sapta

Re: Guide me through building a chess program

Post by Sapta »

Our project submission date is next week, and we are not going to do much to the program now. It's running well at times, giving exceptions at times(usually with time control and ID, but the problem seems elsewhere). I keep debugging but they are never ending.Still I am fairly satisfied with what 2.5 of us have done :lol: One last thing I would add today is a perft method so that I can debug later. A few questions about it.

1. It helps to detect move generation problems. But how much does it help to detect make-unmake method bugs? Most of our bugs seem to be present there. (Getting more than 8 white pawns on board :cry: )

2. What is nps in perft? Saw the term is another thread here.


Lots of thanks to all members who helped, especially to hgm, Sven Schüle and J. Wesley. Cleveland. :) I intend to keep working on the program and improve it whenever I can :D
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Guide me through building a chess program

Post by Sven »

Sapta wrote:Our project submission date is next week, and we are not going to do much to the program now. It's running well at times, giving exceptions at times(usually with time control and ID, but the problem seems elsewhere). I keep debugging but they are never ending.Still I am fairly satisfied with what 2.5 of us have done :lol:
Given that there are still bugs present, what I would do in your situation is to create a safety backup of my sources frequently (and to keep all those different versions - memory is cheap nowadays), and then to give my best to find as many bugs as possible while not adding more functionality. Stability and crash-free playing is quite important IMO.
Sapta wrote:One last thing I would add today is a perft method so that I can debug later. A few questions about it.

1. It helps to detect move generation problems. But how much does it help to detect make-unmake method bugs?
"perft" helps to detect bugs that cause a change of the node count in the full search tree, where no alpha-beta is done. This includes move generation, make/unmake, "is in check" test, legality test, definition and handling of basic data structures, low-level support code for all that, and everything else that has an impact on the node count.
Sapta wrote:Most of our bugs seem to be present there. (Getting more than 8 white pawns on board :cry: )
Restoring the board correctly during unmake is indeed quite essential :-)

So I would regard implementing "perft" as a "must" which should be done as early as possible in a new project, and for which it is never too late to do it.
Sapta wrote:2. What is nps in perft? Saw the term is another thread here.
I'm not sure about the exact meaning of your question. "nps" = "nodes per second", in perft like in regular search this is the number of nodes visited per second on average. It's up to you and depends on your implementation whether you count illegal positions, too, that doesn't matter much. (EDIT: it matters for the final perft node count returned, though, there illegal nodes do not count.) Also do not put yourself under too high pressure regarding getting a high nps, no. 1 := correctness. Of course "nps <= 10000" might be slow ... but even then, who cares, given the current stage of your program?

Some useful links for perft:
Chess programming wiki
Sharper
Roce

If you like to have a look, this is pseudo code of my perft() and divide() functions (divide() can be used to track down a problem after you found a node count mismatch with perft() - EDIT: you need an engine that supports a "divide" command, too, like Crafty for instance, to compare the numbers):

Code: Select all

int perft(int depth)
{
    if (depth == 0) return 1;

    generateAllMoves();
    int n = 0;
    for (int i = 0; i < moveList.size(); i++) {
        makeMove(moveList[i]);
        if (!isIllegal()) {
            n += perft(depth - 1);
        }
        unmakeLastMove();
    }
    return n;
}

void divide(int depth)
{
    generateAllMoves();
    int nLeaves= 0;
    int nMoves= 0;
    for (int i = 0; i < moveList.size(); i++) {
        makeMove(moveList[i]);
        if (!isIllegal()) {
            int n = perft(depth - 1);
            nLeaves += n;
            ++nMoves;
            printf("%s %d\n", moveString(moveList[i]), n);
        }
        unmakeLastMove();
    }
    printf("Nodes: %d\n", nLeaves);
    printf("Moves: %d\n", nMoves);
}
One more note: just in case your engine does not have a way to set up an arbitrary position from an FEN string, this would be the best time to implement that, too, since you will definitely need it to do perft testing. FEN specification is part of the PGN standard. Please apologize if this is already well-known for you.

Sven
Sapta

Re: Guide me through building a chess program

Post by Sapta »

Sven Schüle wrote: Given that there are still bugs present, what I would do in your situation is to create a safety backup of my sources frequently (and to keep all those different versions - memory is cheap nowadays), and then to give my best to find as many bugs as possible while not adding more functionality. Stability and crash-free playing is quite important IMO.
I completely agree. I wanted to make it just that. Bug free even if I could give no more features. At one point, it seemed the bugs were gone. So I implemented a few more things, and now some more bugs are emerging. I debugged the wrong way without perft, so now I am not sure if the bugs were still there in the basic parts or it's just the new stuff I added. Anyway, I have back-ups , although very disorganized atm. I'll organize them asap, else would forget why I have taken so many back-ups :lol:

Sven Schüle wrote: So I would regard implementing "perft" as a "must" which should be done as early as possible in a new project, and for which it is never too late to do it.
A big mistake on my part not implementing it right after alpha-beta. I did mention it a few times to our other members but no one took it seriously (they didn't take anything seriously :| )
Sven Schüle wrote:If you like to have a look, this is pseudo code of my perft() and divide() functions.....
Thank you for the pseudo code. It would be immensely helpful :)

Sven Schüle wrote: One more note: just in case your engine does not have a way to set up an arbitrary position from an FEN string, this would be the best time to implement that, too, since you will definitely need it to do perft testing. FEN specification is part of the PGN standard. Please apologize if this is already well-known for you.

Sven


Yes we have implemented that, thanks for the helpful suggestion. :)

PS- Thanks to Fred Hamilton for his help early on. Felt like I was missing someone :oops: