Help with Debugging My Chess Engine - 2

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

universecoder
Posts: 53
Joined: Mon Sep 19, 2016 6:51 am

Re: Help with Debugging My Chess Engine - 2

Post by universecoder »

Update: The above reason was right, my incorrect moves were significantly decreased!

After that, I discovered another error via the method mentioned above, while moving the pawns up by two squares, I wasn't checking if the square between the current square and the final square was blocked by another piece!

So I removed that bug too. Running perft tests right now!

So far, I have tested it till perft 5. It is taking forever for perft6.

1 20
2 400
3 8902
4 197281
5 4865609

Update:
1 20
2 400
3 8902
4 197281
5 4865609
6 119060324

This is correct as well.
These are correct. Will test them for more positions soon.
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Help with Debugging My Chess Engine - 2

Post by Sven »

Good! So you have also found this bug:

At the very end of undoMove() the line

Code: Select all

if ( move.capturedPiece != EM ) pieceList[move.capturedPiece].erase(move.to);
should better read

Code: Select all

if ( move.capturedPiece != EM ) pieceList[move.capturedPiece].insert(move.to);
since you want to restore the captured piece.
universecoder
Posts: 53
Joined: Mon Sep 19, 2016 6:51 am

Re: Help with Debugging My Chess Engine - 2

Post by universecoder »

Hey, that might've been the reason the unordered set was crashing?
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Help with Debugging My Chess Engine - 2

Post by Sven »

universecoder wrote:So far, I have tested it till perft 5. It is taking forever for perft6.
There is a way to get around that, which will also help later when it comes to regular tree search. Currently you make/unmake each single pseudo-legal move in order to test for legality. This test can be restricted to only those moves which fall into one of these four categories:

1) king moves,
2) moves trying to escape from check,
3) en passant captures, and
4) moves of pinned pieces (pinned to the own king).

All other pseudo-legal moves are always legal. Doing so will increase performance drastically. While 1-3 are trivial (for 2 you only need a simple isInCheck() method which you call once at the beginning of a node) you need to do slightly more work to find all pinned pieces (you could simply store their square numbers in a 64-bit word, or use a set as in case of your piece lists).
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Help with Debugging My Chess Engine - 2

Post by Sven »

universecoder wrote:Hey, that might've been the reason the unordered set was crashing?
Yes, of course!

Now I wonder: did you find and fix that bug as well? If you didn't then how can your perft numbers be correct? Or is there maybe a difference in runtime behaviour between your STL version and the one that I am using when compiling with CygWin?
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Help with Debugging My Chess Engine - 2

Post by Sven »

Furthermore I suggest to write a chessboard::isValid() method like the one below, and use it for debugging by adding

Code: Select all

assert(isValid());
at the beginning and at the end of playMove() and undoMove().

Code: Select all

bool chessboard::isValid() const {
	static int const MinPieces[1+12] = { 0, 0,   0,   0,   0,   0, 1, 0,   0,   0,   0,   0, 1 };
	static int const MaxPieces[1+12] = { 0, 8, 2+8, 2+8, 2+8, 1+8, 1, 8, 2+8, 2+8, 2+8, 1+8, 1 };

	for &#40;int piece = wp; piece <= bk; piece++) &#123;
		if &#40;pieceList&#91;piece&#93;.size&#40;) < MinPieces&#91;piece&#93;) &#123;
			cerr << "less pieces of type " << piece << " than allowed minimum" << endl;
			flush&#40;cerr&#41;;
			return false;
		&#125;
		if &#40;pieceList&#91;piece&#93;.size&#40;) > MaxPieces&#91;piece&#93;) &#123;
			cerr << "more pieces of type " << piece << " than allowed maximum" << endl;
			flush&#40;cerr&#41;;
			return false;
		&#125;
		for&#40;set<int>&#58;&#58;iterator it = pieceList&#91;piece&#93;.begin&#40;); it != pieceList&#91;piece&#93;.end&#40;); it++) &#123;
			if &#40;board&#91;*it&#93; != piece&#41; &#123;
				cerr << "piece list of type " << piece << " contains square " << *it << " but board contains " << board&#91;*it&#93; << " at that square" << endl;
				flush&#40;cerr&#41;;
				return false;
			&#125;
		&#125;
	&#125;
	for &#40;int square = 0; square < 64; square++) &#123;
		int sq = board64&#91;square&#93;;
		int piece = board&#91;sq&#93;;
		if &#40;piece != EM&#41; &#123;
			if &#40;piece < wp || piece > bk&#41; &#123;
				cerr << "illegal piece " << piece << " on square " << sq << endl;
				flush&#40;cerr&#41;;
				return false;
			&#125;
			if &#40;pieceList&#91;piece&#93;.find&#40;sq&#41; == pieceList&#91;piece&#93;.end&#40;)) &#123;
				cerr << "piece list of type " << piece << " that was found on square " << sq << " does not contain that square" << endl;
				flush&#40;cerr&#41;;
				return false;
			&#125;
		&#125;
	&#125;
	return true;
&#125;
I did so in my copy and found the bug in undoMove() that way.

Btw you can safely remove all *.hpp files from the command line in your Makefile but add the compiler option -Wall to see all warnings (which you should also fix).
universecoder
Posts: 53
Joined: Mon Sep 19, 2016 6:51 am

Re: Help with Debugging My Chess Engine - 2

Post by universecoder »

Furthermore I suggest to write a chessboard::isValid() method like the one below, and use it for debugging by adding
Code:
assert(isValid());

at the beginning and at the end of playMove() and undoMove().
Code:
bool chessboard::isValid() const {
static int const MinPieces[1+12] = { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 };
static int const MaxPieces[1+12] = { 0, 8, 2+8, 2+8, 2+8, 1+8, 1, 8, 2+8, 2+8, 2+8, 1+8, 1 };

for (int piece = wp; piece <= bk; piece++) {
if (pieceList[piece].size() < MinPieces[piece]) {
cerr << "less pieces of type " << piece << " than allowed minimum" << endl;
flush(cerr);
return false;
}
if (pieceList[piece].size() > MaxPieces[piece]) {
cerr << "more pieces of type " << piece << " than allowed maximum" << endl;
flush(cerr);
return false;
}
for(set<int>::iterator it = pieceList[piece].begin(); it != pieceList[piece].end(); it++) {
if (board[*it] != piece) {
cerr << "piece list of type " << piece << " contains square " << *it << " but board contains " << board[*it] << " at that square" << endl;
flush(cerr);
return false;
}
}
}
for (int square = 0; square < 64; square++) {
int sq = board64[square];
int piece = board[sq];
if (piece != EM) {
if (piece < wp || piece > bk) {
cerr << "illegal piece " << piece << " on square " << sq << endl;
flush(cerr);
return false;
}
if (pieceList[piece].find(sq) == pieceList[piece].end()) {
cerr << "piece list of type " << piece << " that was found on square " << sq << " does not contain that square" << endl;
flush(cerr);
return false;
}
}
}
return true;
}

I did so in my copy and found the bug in undoMove() that way.

Btw you can safely remove all *.hpp files from the command line in your Makefile but add the compiler option -Wall to see all warnings (which you should also fix).
Thanks for this. Right now I am running perft tests.
It is slow for the following reasons:
1. I am scanning over 64 squares in the move generation function instead of the piece list
2. The reasons you mentioned.

As the next step, I will bring back the set and rerun the tests. Then I'll bring back the unordered_set and rerun the tests.
After that I'll continue by implementing a static evaluation function, negamax search, alpha-beta pruning and so on.

After the engine is ready, I will begin optimizing it.
universecoder
Posts: 53
Joined: Mon Sep 19, 2016 6:51 am

Re: Help with Debugging My Chess Engine - 2

Post by universecoder »

Hello, this might seem to be as silly question, but I couldn't find any sources giving me links to any advanced perft tests. I finished the 6 positions given on: http://chessprogramming.wikispaces.com/perft+Results
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Help with Debugging My Chess Engine - 2

Post by Sven »

universecoder wrote:Hello, this might seem to be as silly question, but I couldn't find any sources giving me links to any advanced perft tests. I finished the 6 positions given on: http://chessprogramming.wikispaces.com/perft+Results
Some quick links (don't know if that is as "advanced" as you are looking for):
http://www.rocechess.ch/perft.html
http://www.albert.nu/programs/sharper/perft
http://www.chessprogramming.net/perfect-perft
universecoder
Posts: 53
Joined: Mon Sep 19, 2016 6:51 am

Re: Help with Debugging My Chess Engine - 2

Post by universecoder »

Thanks, I really needed something for testing pawn promotion stuff.