Doubled pawns

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
stegemma
Posts: 859
Joined: Mon Aug 10, 2009 10:05 pm
Location: Italy
Full name: Stefano Gemma

Re: Doubled pawns

Post by stegemma »

stegemma wrote:It is not very efficient but this is what I do now:

Code: Select all

inline int CountDoubled(uint64_t boPawns)
{
	int n = 0;
	if((boPawns & ~(boPawns * BOARD_H_COL)) != boEmpty)
	{
		boPawns >>= 8;
		uint64_t k = boEmpty;
		for&#40;int i = 0; i < 6; i++)
		&#123;
			k |= &#40;boPawns & BOARD_1_ROW&#41;; // accumula i bit dei pedoni sulla prima riga
			uint64_t dbl = k & &#40;boPawns >>= 8&#41;;
			n += bits8&#91;dbl&#93;;
		&#125;
	&#125;
	return n;
&#125;
(bits8 contains bits count for the first 256 integers)
According to VS profiler, the "if" takes about the same time as the whole loop!

This version seems to be faster:

Code: Select all

inline int CountDoubled&#40;uint64_t boPawns&#41;
&#123;
	int n = 0;
	boPawns >>= 8;
	uint64_t k = boEmpty;
	for&#40;int i = 0; i < 6; i++)
	&#123;
		k |= &#40;boPawns & BOARD_1_ROW&#41;; // accumulates pawn bits on first row
		uint64_t dbl = k & &#40;boPawns >>= 8&#41;;
		n += bits8&#91;dbl&#93;;
	&#125;
	return n;
&#125;
Of course removing any test on pawns if there are no more one of them must be done in the caller.

The compiler is smart enough to avoid the "& BOARD_1_ROW" and it uses a single 8 bit register (r8b, in my test). An improvement using less smart compilers could be to use uint8_t variables for dbl and k.
Author of Drago, Raffaela, Freccia, Satana, Sabrina.
http://www.linformatica.com
User avatar
stegemma
Posts: 859
Joined: Mon Aug 10, 2009 10:05 pm
Location: Italy
Full name: Stefano Gemma

Re: Doubled pawns

Post by stegemma »

hgm wrote:Normally this info would come from your Pawn hash, meaning that speed is irrelevant.
I've found a simpler way to do it: because I've a node array, I simply store the value of current pawn structure in the current node, so that I can use it avoiding re-computing any time:

Code: Select all

if&#40;pNode->boMyPawns == boMyPawns && pNode->boOtherPawns == boOtherPawns&#41;
&#123;
	++kSamePawns; // to test efficiency
	eval += pNode->vPawnValue;
&#125; else
&#123;
	++kNoSamePawns;  // to test efficiency
	pNode->boMyPawns = boMyPawns;
	pNode->boOtherPawns = boOtherPawns;
	pNode->vPawnValue = 0;
	// pedoni doppiati
	int nMyDoubled = CountDoubled&#40;boMyPawns&#41;;
	int nOtherDoubled = CountDoubled&#40;boOtherPawns&#41;;
	pNode->vPawnValue += iiValues&#91;nOtherDoubled - nMyDoubled&#93;;
...
&#125;
This very simple code gives me a "pawns hit" of about 50% and a little speed-up (more than +5 Knps).

Now I'll try to extend this idea to other evaluation parameters.

PS: I don't need to separate my/other pawns because you can't exchange a pawn structure inside a single node!!!
Author of Drago, Raffaela, Freccia, Satana, Sabrina.
http://www.linformatica.com