CookieCat's pawn structure code
Posted: Sat Jan 07, 2012 1:05 am
CookieCat currently recognizes seven pawn structure attributes. A sample:
[d]2qrr1n1/3b1kp1/2pBpn1p/1p2PP2/p2P4/1BP5/P3Q1PP/4RRK1 w - - 0 1[/d]
At present, only the location attribute is scored. Its values come from [color, sq] table look-ups.
Attribute recognition:
[d]2qrr1n1/3b1kp1/2pBpn1p/1p2PP2/p2P4/1BP5/P3Q1PP/4RRK1 w - - 0 1[/d]
Code: Select all
[] sfen 2qrr1n1/3b1kp1/2pBpn1p/1p2PP2/p2P4/1BP5/P3Q1PP/4RRK1 w - - 0 1
[] dps
Backward (white): [c3]
Backward (black): [c6 e6 g7]
Connected (white): [g2 h2 c3 d4 e5 f5]
Connected (black): [a4 b5 c6 h6 g7]
Isolated (white): [a2]
Isolated (black): [e6]
Location (white): [a2 g2 h2 c3 d4 e5 f5]
Location (black): [a4 b5 c6 e6 h6 g7]
Majority (white): [g2 d4 e5 f5]
Majority (black): [a4 b5]
Multiple (white): []
Multiple (black): []
Passed (white): []
Passed (black): []
Attribute recognition:
Code: Select all
{ Bitboard }
bbtype =
record
case Boolean of
False: (wvec: array [bbwtype] of bbwspantype); { Array of bitboard words }
True: (bv64: ui64type) { Unsigned 64 bit value }
end;
{ Bitboard color indexed vector }
bbcivtype = array [colorrtype] of bbtype;
{ Pawn structure }
pawnstructtype =
record
backward: bbcivtype; { Backward pawns by color }
connected: bbcivtype; { Connected pawns by color }
isolated: bbcivtype; { Isolated pawns by color }
location: bbcivtype; { Locus of pawns by color }
majority: bbcivtype; { Three file majority pawns by color }
multiple: bbcivtype; { Doubled (and worse) multiple pawns by color }
passed: bbcivtype { Passed pawns by color }
end;
procedure PawnStructReset(var pawnstruct: pawnstructtype);
var
color: colorrtype;
begin
with pawnstruct do
for color := colorrmin to colorrmax do
begin
BbReset(backward[color]);
BbReset(connected[color]);
BbReset(isolated[color]);
BbReset(location[color]);
BbReset(majority[color]);
BbReset(multiple[color]);
BbReset(passed[color])
end
end; { PawnStructReset }
procedure PawnStructLoadFromPos(var pawnstruct: pawnstructtype; var pos: postype);
var
color: colorrtype;
c0bb, c1bb: bbtype;
m0bb, m1bb: bbtype;
bb: bbtype;
sq: sqxtype;
advdir: dirtype;
advsq: sqxtype;
countbb: bbtype;
begin
with pawnstruct, pos, bbdb do
begin
PawnStructReset(pawnstruct);
for color := colorrmin to colorrmax do
begin
{ Setup }
c0bb := locbm[synthpawn[color]];
c1bb := locbm[synthpawn[othercolor[color]]];
advdir := pawnadvdir[color];
{ Scan }
bb := c0bb;
repeat
sq := BbNextSq(bb);
if sq <> sqnil then
begin
{ Backward }
if BbNI2(c0bb, guardedbbvec[color, sq]) then
begin
advsq := advance[sq, advdir];
if advsq <> sqnil then
if not BbNI2(c1bb, pawnatkbbvec[color, advsq]) then
BbSetSq(backward[color], sq)
end;
{ Connected }
if not BbNI2(c0bb, connectbbvec[sq]) then
BbSetSq(connected[color], sq);
{ Isolated }
if BbNI2(c0bb, adjfilebbvec[sq]) then
BbSetSq(isolated[color], sq);
{ Location }
location[color] := c0bb;
{ Majority }
BbAnd2(m0bb, c0bb, majfilebbvec[sq]);
BbAnd2(m1bb, c1bb, majfilebbvec[sq]);
if BbCount(m0bb) > BbCount(m1bb) then
BbSetSq(majority[color], sq);
{ Multiple }
BbAnd2(countbb, c0bb, bfilebbvec[MapSqToBfile(sq)]);
if BbCount(countbb) > 1 then
BbSetSq(multiple[color], sq);
{ Passed }
if BbNI2(c1bb, passerbbvec[color, sq]) then
BbSetSq(passed[color], sq)
end
until sq = sqnil;
end
end
end; { PawnStructLoadFromPos }