First, there is a "runway" type:
Code: Select all
{ Check detection runway }
runwaytype =
record
prwbb: bbtype; { Landing runway for pawn attackers }
nrwbb: bbtype; { Landing runway for knight attackers }
brwbb: bbtype; { Landing runway for bishop attackers }
rrwbb: bbtype; { Landing runway for rook attackers }
qrwbb: bbtype; { Landing runway for queen attackers }
disbb: bbtype { Discovery candidates }
end;
Code: Select all
procedure PosBuildRunway(var pos: postype; var runway: runwaytype);
var
evilkingsq: sqtype;
dir: dirtype;
scansq: sqxtype;
scanindex: Integer;
stopped: Boolean;
color: colortype;
goodsweepbb: bbtype;
scanbb: bbtype;
begin
with pos, board, bbdb, runway do
begin
BbReset(disbb); evilkingsq := ksqv[evil]; BbAnd2(goodsweepbb, sweep, locbc[good]);
{ Pawn runway }
prwbb := pawnatkbbvec[evil, evilkingsq];
{ Knight runway }
nrwbb := knightatkbbvec[evilkingsq];
{ Bishop runway }
BbReset(brwbb);
for dir := dirne to dirse do
begin
scanindex := scanmap[evilkingsq, dir]; stopped := False;
repeat
scansq := scansqs[scanindex]; Inc(scanindex);
if scansq = sqnil then stopped := True
else
begin
color := mantocolor[sqv[scansq]];
if color = colorv then BBSetSq(brwbb, scansq)
else
begin
stopped := True;
if color = evil then BBSetSq(brwbb, scansq) else BBSetSq(disbb, scansq)
end
end
until stopped
end;
{ Rook runway }
BbReset(rrwbb);
for dir := dire to dirs do
begin
scanindex := scanmap[evilkingsq, dir]; stopped := False;
repeat
scansq := scansqs[scanindex]; Inc(scanindex);
if scansq = sqnil then stopped := True
else
begin
color := mantocolor[sqv[scansq]];
if color = colorv then BBSetSq(rrwbb, scansq)
else
begin
stopped := True;
if color = evil then BBSetSq(rrwbb, scansq) else BBSetSq(disbb, scansq)
end
end
until stopped
end;
{ Queen runway }
BbIor2(qrwbb, brwbb, rrwbb);
{ Discovery runway, second pass }
scanbb := disbb;
repeat
scansq := BbNextSq(scanbb);
if scansq <> sqnil then
if BbNI3(goodsweepbb, beambbvec[evilkingsq, scansq], atkts[scansq]) then
BbResetSq(disbb, scansq)
until scansq = sqnil
end
end; { PosBuildRunway }
Code: Select all
procedure PosAssignMoveCheckFlags(var pos: postype; var gms: gmstype);
var
evilkingsq: sqtype;
index: Integer;
runway: runwaytype;
check: Boolean;
hfrsq: sqxtype;
frpiece: piecetype;
disco: Boolean;
beambb: bbtype;
begin
with pos, bbdb, gms, runway do
begin
PosBuildRunway(pos, runway); evilkingsq := ksqv[evil];
hfrsq := sqnil; frpiece := piecev; disco := False; BbReset(beambb);
for index := 0 to movecount - 1 do
with moves[index] do
begin
{ Set up for a new move }
check := False;
if hfrsq <> frsq then
begin
hfrsq := frsq; frpiece := mantopiece[frman];
disco := BbTestSq(disbb, frsq); beambb := beambbvec[evilkingsq, frsq]
end;
{ Process by moving piece kind }
case frpiece of
piecep:
case msc of
mscreg:
if BbTestSq(prwbb, tosq) then check := True
else
if disco and (not BbTestSq(beambb, tosq)) then check := True;
mscepc: if PosIsEnPassantMoveChecking(pos, moves[index]) then check := True;
mscppn: if disco or BbTestSq(nrwbb, tosq) then check := True;
mscppb:
if disco or BbTestSq(brwbb, tosq) then check := True
else
if toman <> manvv then
if compass[frsq, tosq] = compass[evilkingsq, frsq] then
if BbNI2(merge, pathwaybbvec[evilkingsq, frsq]) then check := True;
mscppr:
if disco or BbTestSq(rrwbb, tosq) then check := True
else
if toman = manvv then
if compass[frsq, tosq] = compass[evilkingsq, frsq] then
if BbNI2(merge, pathwaybbvec[evilkingsq, frsq]) then check := True;
mscppq:
if disco or BbTestSq(qrwbb, tosq) then check := True
else
if compass[frsq, tosq] = compass[evilkingsq, frsq] then
if BbNI2(merge, pathwaybbvec[evilkingsq, frsq]) then check := True
end; { case }
piecen: if disco or BbTestSq(nrwbb, tosq) then check := True;
pieceb: if disco or BbTestSq(brwbb, tosq) then check := True;
piecer: if disco or BbTestSq(rrwbb, tosq) then check := True;
pieceq: if BbTestSq(qrwbb, tosq) then check := True;
piecek:
case msc of
mscreg: if disco and (not BbTestSq(beambb, tosq)) then check := True;
msccqs, msccks:
if PosIsCastlingChecking(pos, MapColorMscToCastling(good, msc)) then check := True
end { case }
end; { case }
if check then MoveFlagSet(moves[index], mfchck)
end
end
end; { PosAssignMoveCheckFlags }