|
|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 85376 (0x14d80)
Types: TextFile
Names: »CHESS80.PAS«
└─⟦121d96d60⟧ Bits:30005835 RC Chess 750 source code
└─⟦this⟧ »CHESS80.PAS«
program chess(input,output);
(* chess.p00 *)
label
1,
2,
9;
const
aa = 1; za = 10;
ac = '*'; zc = 'Z';
ad = -21; zd = +21;
aj = 1; zj = 78;
ak = 0; zk = 24;
akm2 = -2; zkp1= 25;
al = 0; zl = 119;
azl = -119; zal= 119;
an = 1; zn = 30; znn = 40;
as = 0; zs = 63;
att = -1; zt = 63;
av = -32767; zv = +32767;
aw = 1; zw = 500;
ax = 0; zx = 63;
ay = 0; zy = 3; zyb = 7;
lpp = 20;
syncf = 1;
syncl = 36;
synmf = 37;
synml = 47;
type
(* simple types *)
ta = aa..za;
tb = boolean;
tc = char;
td = ad..zd;
te = (b1,b2,b3,b4,s1,s2,s3,s4,n1,n2,n3,n4,n5,n6,n7,n8);
tf = (f1,f2,f3,f4,f5,f6,f7,f8);
tg = (pq,pr,pn,pb);
th = (h0,h1,h2,h3,h4,h5,h6,h7);
ti = integer;
tj = aj..zj;
tk = ak..zk;
tl = al..zl;
tm = (lite,dark,none);
tn = an..zn;
tnn = an..znn;
tp = (lp,lr,ln,lb,lq,lk,dp,dr,dn,db,dq,dk,mt);
tq = (ls,ll,ds,dl);
tr = (r1,r2,r3,r4,r5,r6,r7,r8);
ts = as..zs;
tt = att..zt;
tu = (ep,er,en,eb,eq,ek);
tv = av..zv;
tw = aw..zw;
tx = ax..zx;
ty = ay..zy;
tyb = ay..zyb;
tz = real;
byte = 0..255;
(* sets *)
sc = set of ac..zc;
sf = set of tf;
sq = set of tq;
sr = set of tr;
sx = set of tx;
(* records *)
rc = arrayÆtsÅ of tp;
rb = record
rbtm : tm;
rbts : tt;
rbti : ti;
rbsq : sq;
case integer of
0: (rbis: rc);
1: (rbirf: array Ætr,tfÅ of tp);
end;
ra = packed arrayÆtaÅ of tc;
rn = packed array ÆtnÅ of tc;
rnn = packed array ÆtnnÅ of tc;
rj = packed array ÆtjÅ of tc;
rd = packed record
rdpc : tb;
rdsl : tb;
rdkq : tb;
rdnb : tb;
rdrk : tb;
end;
rm = packed record
rmfr : ts;
rmto : ts;
rmcp : tp;
rmca : tb;
rmac : tb;
rmch : tb;
rmmt : tb;
rmil : tb;
rmsu : tb;
case rmpr : tb of
false:(
case rmoo : tb of
false : (rmep : tb);
true : (rmqs : tb);
);
true: (rmpp : tg);
end;
rs = packed record
case integer of
0: (rsss : sx);
1: (rsti : array ÆtyÅ of ti);
2: (rsbt : packed array ÆtybÅ of byte);
end;
rx = array ÆtsÅ of rs;
ry = packed record
ryls : rd;
rych : tc;
ryrs : rd;
end;
re = array ÆtwÅ of tv;
rf = array ÆtwÅ of rm;
var
(* data base *)
board : rb;
nbord : rc;
atkfr : rx;
atkto : rx;
alatk : array ÆtmÅ of rs;
tploc : array ÆtpÅ of rs;
tmloc : array ÆtmÅ of rs;
moves : rf;
valuu : re;
alloc : array ÆtkÅ of rs;
bstmv : array ÆtkÅ of tw;
bstvl : array Æakm2..zkp1Å of tv;
cstat : array ÆtkÅ of rs;
enpas : array ÆtkÅ of rs;
genpn : array ÆtkÅ of rs;
gento : array ÆtkÅ of rs;
genfr : array ÆtkÅ of rs;
mbval : array ÆtkÅ of tv;
mvsel : array ÆtkÅ of ti;
index : array Æak..zkp1Å of tw;
killr : array ÆtkÅ of rm;
lindx : array ÆtkÅ of tw;
srchm : array ÆtkÅ of th;
castle: array ÆtmÅ of tb;
going : ti;
lstmv : rm;
maxps : tv;
mblte : tv;
mbpwn : array ÆtmÅ of ti;
mbtot : tv;
nodes : ti;
jntk : tk;
jmtk : tk;
jntm : tm;
jntw : tw;
jfmv : tb;
(* lets *)
fkpshd: ti;
fksanq: ti;
fmaxmt: ti;
stages: ti;
fpadcr: array ÆtfÅ of ti;
fpblok: ti;
fpconn: ti;
fpflnx: ti;
frdubl: ti;
frk7th: ti;
ftrade: ti;
ftrdsl: ti;
ftrpok: ti;
ftrpwn: ti;
fwking: ti;
fwmajm: ti;
fwminm: ti;
fwpawn: ti;
fwrook: ti;
fcheck: ti;
fwattk: ti;
faking: ti; (* bonus for attack opp. king *)
fcfree: ti; (* bonus for castle free square *)
window: ti;
(* switches *)
swec : tb;
swpa : tb;
swps : tb;
swre : tb;
swsu : tb;
swtr : tb;
swpr : tb;
swbm : tb;
(* command processing data *)
com : ti;
icard : rj;
iline : rj;
jmtj : tj;
jntj : tj;
movms : rnn;
(* translation tables *)
xspb : array ÆtpÅ of tb;
xfpe : array ÆtpÅ of te;
xlld : array Æazl..zalÅ of td;
xlpe : array ÆtpÅ of te;
xrfs : array ÆtfÅ of rs;
xrrs : array ÆtrÅ of rs;
xnfs : array ÆtfÅ of rs;
xnrs : array ÆtrÅ of rs;
xrss : array ÆtsÅ of rs;
xrqm : array ÆtqÅ of rm;
xsqs : array ÆtqÅ of rs;
xssx : array ÆtsÅ of sx;
xtbc : array ÆtbÅ of tc;
xted : array ÆteÅ of td;
xtgc : array ÆtgÅ of tc;
xtgmp : array Ætg,tmÅ of tp;
xtls : array ÆtlÅ of tt;
xtma : array ÆtmÅ of ra;
xtmq : array ÆtmÅ of tq;
xtmv : array ÆtmÅ of tv;
xtpc : array ÆtpÅ of tc;
xtpm : array ÆtpÅ of tm;
xtpu : array ÆtpÅ of tu;
xtpv : array ÆtpÅ of tv;
xtqa : array ÆtqÅ of ra;
xtqs : array ÆtqÅ of ts;
xtrfs : array Ætr,tfÅ of ts;
xtsf : array ÆtsÅ of tf;
xtsl : array ÆtsÅ of tl;
xtsr : array ÆtsÅ of tr;
xtsx : array ÆtsÅ of tx;
xtsy : array ÆtsÅ of ty;
xtuc : array ÆtuÅ of tc;
xtump : array Ætu,tmÅ of tp;
xrqso : array ÆtqÅ of rs;
xrqsa : array ÆtqÅ of rs;
edge : array ÆteÅ of rs;
ct : array Æ0..255Å of ts;
cornr : rs;
nulmv : rm;
other : array ÆtmÅ of tm;
syntx : array Æsyncf..synmlÅ of ry;
(* chess.p01 *)
function max(a,b: ti):ti;
begin if a > b then max:=a else max:=b end;
function min(a,b: ti): ti;
begin if a < b then min:=a else min:=b end;
function sign(a,b: ti): ti;
begin if b <> 0 then sign:=trunc(b/abs(b)) * abs(a) else sign:=a end;
procedure sortit(var a: re; var b: rf; c: tw);
var
intb : tb;
intw : tw;
inti : ti;
intv : tv;
inrm : rm;
begin
for intw:=aw+2 to c do
begin
inti:=intw-1;
intv:=aÆintwÅ;
inrm:=bÆintwÅ;
intb:=true;
while (inti > aw) and intb do
if intv < aÆintiÅ then
begin
aÆinti+1Å:=aÆintiÅ;
bÆinti+1Å:=bÆintiÅ;
inti:=inti-1;
end else intb:=false;
aÆinti+1Å:=intv;
bÆinti+1Å:=inrm;
end;
end;
(* machine independent code *)
procedure andrs(var c: rs; a,b: rs);
begin
c.rsss:=a.rsss * b.rsss;
end;
(*
procedure andrs(var c: rs; var a,b: rs);
var inty : ty;
begin
for inty:=ay to zy do c.rstiÆintyÅ:=a.rstiÆintyÅ and b.rstiÆintyÅ;
end;
*)
(* machine independent code *)
procedure clrrs(var c: rs; a: ts);
begin c.rsss:=c.rsss-xssxÆaÅ end;
(*
procedure clrrs(var c: rs; a: ts);
var i : ts;
begin
i:=ord(xtsrÆaÅ);
c.rsbtÆiÅ:=c.rsbtÆiÅ and not(1 shl ord(xtsfÆaÅ));
end;
*)
(* machine independent code *)
procedure setrs(var c: rs; a: ts);
begin c.rsss:=c.rsss+xssxÆaÅ end;
(*
procedure setrs(var c: rs; a: ts);
var i : ts;
begin
i:=ord(xtsrÆaÅ);
c.rsbtÆiÅ:=c.rsbtÆiÅ or (1 shl ord(xtsfÆaÅ));
end;
*)
(* machine independent code *)
procedure iorrs(var c: rs; a,b: rs);
begin
c.rsss:=a.rsss + b.rsss;
end;
(*
procedure iorrs(var c: rs; var a,b: rs);
var inty : ty;
begin
for inty:=ay to zy do c.rstiÆintyÅ:=a.rstiÆintyÅ or b.rstiÆintyÅ;
end;
*)
procedure newrs(var a: rs);
var inty : ty;
begin
for inty:=ay to zy do a.rstiÆintyÅ:=0;
end;
(* machine independent code *)
procedure notrs(var c: rs; a: rs);
begin
c.rsss:=Æax..zxÅ - a.rsss;
end;
(*
procedure notrs(var c: rs; var a: rs);
var inty : ty;
begin
for inty:=ay to zy do c.rstiÆintyÅ:=not a.rstiÆintyÅ;
end;
*)
(* machine independent code
function nxtts(var a: rs; var b: ts): tb;
label 11;
var
intx : tx;
inty : ty;
begin
for inty:=zy downto ay do
if a.rstiÆintyÅ <> 0 then
begin
for intx:=zx downto ax do
if intx in a.rsss then
begin
b:=intx;
a.rsss:=a.rsss-ÆintxÅ;
nxtts:=true;
goto 11;
end;
end;
nxtts:=false;
11:
end;
*)
function nxtts(var a: rs; var b: ts): tb;
label 11;
var
i,j,p : ti;
intx : tx;
inty : ty;
begin
for i:=zyb downto ay do
if a.rsbtÆiÅ <> 0 then
begin
p:=128;
for j:=ay to zyb do
begin
if a.rsbtÆiÅ - p >= 0 then
begin
b:=j+i * 8;
a.rsbtÆiÅ:=a.rsbtÆiÅ-p;
nxtts:=true;
goto 11;
end;
p:=p div 2;
end;
end;
nxtts:=false;
11:
end;
(* machine independent code *)
function cntrs(var a: rs): ts;
var
i : tyb;
sum : ts;
begin
sum:=0;
for i:=ay to zyb do sum:=sum+ctÆa.rsbtÆiÅÅ;
cntrs:=sum;
end;
(* machine independent code
procedure sftrs(var a: rs; b: rs; c: te);
var
inrs : rs;
ints : ts;
inty : ty;
begin
newrs(a);
while nxtts(b,ints) do
if xtlsÆxtslÆintsÅ+xtedÆcÅÅ > 0 then
setrs(a,xtlsÆxtslÆintsÅ+xtedÆcÅÅ);
end;
*)
procedure sftrs(var a: rs; b: rs; c: te);
var i : integer;
begin
case c of
s1: for i:=ay to zyb do
if b.rsbtÆiÅ < 128 then
a.rsbtÆiÅ:=b.rsbtÆiÅ * 2
else
a.rsbtÆiÅ:=(b.rsbtÆiÅ-128) * 2;
s2: begin
for i:=ay to zyb-1 do a.rsbtÆi+1Å:=b.rsbtÆiÅ;
a.rsbtÆayÅ:=0;
end;
s3: for i:=ay to zyb do a.rsbtÆiÅ:=b.rsbtÆiÅ div 2;
s4: begin
for i:=ay to zyb-1 do a.rsbtÆiÅ:=b.rsbtÆi+1Å;
a.rsbtÆzybÅ:=0;
end;
b1: begin sftrs(a,b,s1); sftrs(a,a,s2) end;
b2: begin sftrs(a,b,s2); sftrs(a,a,s3) end;
b3: begin sftrs(a,b,s3); sftrs(a,a,s4) end;
b4: begin sftrs(a,b,s4); sftrs(a,a,s1) end;
n1: begin sftrs(a,b,b1); sftrs(a,a,s2) end;
n2: begin sftrs(a,b,b2); sftrs(a,a,s2) end;
n3: begin sftrs(a,b,b2); sftrs(a,a,s3) end;
n4: begin sftrs(a,b,b3); sftrs(a,a,s3) end;
n5: begin sftrs(a,b,b3); sftrs(a,a,s4) end;
n6: begin sftrs(a,b,b4); sftrs(a,a,s4) end;
n7: begin sftrs(a,b,b4); sftrs(a,a,s1) end;
n8: begin sftrs(a,b,b1); sftrs(a,a,s1) end;
end;
end;
function inrstb(var a: rs; b: ts): tb;
begin inrstb:=not not (ÆbÅ <= a.rsss) end;
function nulrs(var a: rs): tb;
var
inty : ty;
intb : tb;
begin
intb:=true;
for inty:=ay to zy do
intb:=intb and (a.rstiÆintyÅ = 0);
nulrs:=intb;
end;
function nulmvb(a: rm): tb;
begin
nulmvb:=a.rmac and a.rmpr and (not a.rmca);
end;
procedure pauser;
begin
if swpa then
begin
writeln(' PAUSING ');
readln;
end;
end;
(* chess.p03 *)
procedure mbeval; (* evaluate material balance *)
var inti : ti;
begin
if mblte <> 0 then
if mblte > 0 then inti:=mbpwnÆliteÅ else inti:=mbpwnÆdarkÅ
else inti:=0;
mbvalÆjntkÅ:=sign(
min(
trunc(min(fmaxmt,abs(mblte))
+1.0*ftrade*abs(mblte)*(ftrdsl-mbtot)
*(4*inti+ftrpok) / (4*inti+ftrpwn)
/ 2.62144e5)
,16320)
,mblte);
end;
procedure writexy(sq: ts);
begin
write(chr(sq mod 8 + ord('A')),sq div 8 + 1:0);
end;
procedure inital(var a: rb); (* inittialize for a new game *)
var
intf : tf;
intr : tr;
begin
with a do
begin
rbtm:=lite;
rbts:=-1;
rbti:=0;
rbsq:=Æls,ll,ds,dlÅ;
castleÆliteÅ:=false; castleÆdarkÅ:=false;
for intf:=f1 to f8 do
begin
rbirfÆr2,intfÅ:=lp;
for intr:=r3 to r6 do rbirfÆintr,intfÅ:=mt;
rbirfÆr7,intfÅ:=dp;
end;
rbirfÆr1,f1Å:=lr;
rbirfÆr1,f2Å:=ln;
rbirfÆr1,f3Å:=lb;
rbirfÆr1,f4Å:=lq;
rbirfÆr1,f5Å:=lk;
rbirfÆr1,f6Å:=lb;
rbirfÆr1,f7Å:=ln;
rbirfÆr1,f8Å:=lr;
rbirfÆr8,f1Å:=dr;
rbirfÆr8,f2Å:=dn;
rbirfÆr8,f3Å:=db;
rbirfÆr8,f4Å:=dq;
rbirfÆr8,f5Å:=dk;
rbirfÆr8,f6Å:=db;
rbirfÆr8,f7Å:=dn;
rbirfÆr8,f8Å:=dr;
movms:=' ENTER MOVE CR TYPE GO. ';
writeln(movms);
lstmv:=nulmv;
end;
end;
procedure primov(a: rm);
begin
with a do
begin
write(' ',xtpcÆnbordÆrmfrÅÅ:0,'/');
writexy(rmfr);
if rmca then write('*') else write('-');
writexy(rmto);
if nulmvb(a) then write(', NULL MOVE')
else begin
if rmca then write(', CAPTURE ',xtpcÆrmcpÅ,',')
else write(', SIMPLE,');
if not rmac then write(' NO');
write(' ACS');
if rmch then write(', CHECK');
if rmmt then write(', MATE');
if rmil then write(', ILLEGAL');
if rmsu then write(', SEARCHED');
case rmpr of
false:
case rmoo of
false: if rmep then write(', ENPASSANT');
true :
begin
write(', CASTLE ');
if rmqs then write('LONG') else write('SHORT');
end;
end;
true :
begin
write(', PROMOTE TO ');
case rmpp of
pq: write('QUEEN');
pr: write('ROOK');
pb: write('BISHOP');
pn: write('KNIGHT');
end;
end;
end;
end;
end;
writeln('.');
end;
(* machine independed code *)
procedure printb(a: rc);
var
intr : tr;
intf : tf;
intp : tp;
begin
writeln;
for intr:=r8 downto r1 do
begin
write(' ',ord(intr)+1:1,' ');
for intf:=f1 to f8 do
begin
intp:=aÆxtrfsÆintr,intfÅÅ;
if xtpmÆintpÅ = dark then write('-') else write(' ');
write(xtpcÆintpÅ);
end;
writeln;
end;
writeln; writeln(' A B C D E F G H');
end;
(*
procedure printb(a: rc);
const
invers = @144;
normal = @128;
var
intp : tp;
i,j,k : ti;
figure: tb;
attr : tc;
begin
attr:=invers;
for j:=0 to 23 do
begin
if j mod 3 = 0 then if attr = invers then attr:=normal else attr:=invers;
figure:=false;
if j mod 3 = 1 then
begin
k:=8-j div 3;
write(normal,k,' ')
end else write(normal,' ');
for i:=0 to 55 do
begin
case i mod 7 of
0: begin
if j mod 3 = 1 then figure:=true;
if attr = invers then attr:=normal else attr:=invers;
write(attr,' ');
end;
2: if figure then
begin
intp:=aÆ((k-1)*8 + i div 7)Å;
if intp = mt then
begin
figure:=false;
write(' ');
end else if xtpmÆintpÅ = dark then
write(normal,'-') else write(invers,'-');
end else write(' ');
3: if figure then write(xtpcÆintpÅ) else write(' ');
4: if figure then write('-') else write(' ');
1,5,6: write(attr,' ');
end;
end;
writeln;
end;
write(normal);
end;
*)
procedure prinbb(a: rs); (* print a bit board *)
var
intr : tr;
intf : tf;
begin
writeln;
for intr:=r8 downto r1 do
begin
write(' ',ord(intr)+1:1,' ');
for intf:=f1 to f8 do
write(xtbcÆinrstb(a,xtrfsÆintr,intfÅ)Å);
writeln;
end;
writeln(' ABCDEFGH');
end;
procedure prinam(a: rx); (* print attack map *)
var
intr, jntr : tr;
intf, jntf : tf;
begin
writeln;
for intr:=r8 downto r1 do
begin
for jntr:=r8 downto r1 do
begin
for intf:=f1 to f8 do
begin
write(' ');
for jntf:=f1 to f8 do
write(xtbcÆinrstb(aÆxtrfsÆintr,intfÅÅ,xtrfsÆjntr,jntfÅ)Å);
write(' ');
end;
writeln;
end;
writeln;
if intr in Ær1,r3,r5,r7Å then pauser;
end;
end;
procedure priswi(a: ra; b: tb); (* print a switch *)
begin
write(' ',aÆaaÅ,aÆaa+1Å);
if b then writeln(' ON') else writeln(' OFF');
end;
(* chess.p04 *)
procedure mbcapt(a: tp); (* evaluate material after capture *)
begin
mbtot:=mbtot-abs(xtpvÆaÅ);
if xtpuÆaÅ = ep then mbpwnÆxtpmÆaÅÅ:=mbpwnÆxtpmÆaÅÅ-1;
mblte:=mblte-xtpvÆaÅ;
mbeval;
end;
procedure mbprom(a: tp); (* evaluate matr. bal. change due to pawn
promotion *)
begin
mbtot:=mbtot+abs(xtpvÆaÅ-xtpvÆxtumpÆep,xtpmÆaÅÅÅ);
mbpwnÆxtpmÆaÅÅ:=mbpwnÆxtpmÆaÅÅ-1;
mblte:=mblte+xtpvÆaÅ-xtpvÆxtumpÆep,xtpmÆaÅÅÅ;
mbeval;
end;
procedure mbmorp(a: tp); (* remove pawn promotion from matr.bal. *)
begin
mbtot:=mbtot-abs(xtpvÆaÅ-xtpvÆxtumpÆep,xtpmÆaÅÅÅ);
mbpwnÆxtpmÆaÅÅ:=mbpwnÆxtpmÆaÅÅ+1;
mblte:=mblte-(xtpvÆaÅ-xtpvÆxtumpÆep,xtpmÆaÅÅÅ);
mbeval;
end;
procedure mbtpac(a: tp); (* remove capture form matr. bal. data *)
begin
mbtot:=mbtot+abs(xtpvÆaÅ);
if xtpuÆaÅ = ep then mbpwnÆxtpmÆaÅÅ:=mbpwnÆxtpmÆaÅÅ+1;
mblte:=mblte+xtpvÆaÅ;
mbeval;
end;
procedure addatk(a: ts); (* add attacks of piece to data-base *)
var
intb : tb;
intd : td;
inte : te;
intm : tm;
intp : tp;
intt : tt;
begin
intp:=nbordÆaÅ;
intm:=xtpmÆintpÅ;
for inte:=xfpeÆintpÅ to xlpeÆintpÅ do
begin
intt:=a;
intb:=xspbÆintpÅ;
intd:=xtedÆinteÅ;
repeat
intt:=xtlsÆxtslÆinttÅ+intdÅ;
if intt >= 0 then
begin
setrs(atkfrÆaÅ,intt);
setrs(atktoÆinttÅ,a);
setrs(alatkÆintmÅ,intt);
if nbordÆinttÅ <> mt then intb:=false;
end else intb:=false;
until not intb;
end;
end;
procedure addloc(a: ts; b: tp); (* add piece to data-base *)
begin
clrrs(tplocÆmtÅ,a);
setrs(tplocÆbÅ,a);
setrs(tmlocÆxtpmÆbÅÅ,a);
setrs(allocÆjntkÅ,a);
nbordÆaÅ:=b;
end;
procedure clstat; (* clear position status *)
begin
with board do
begin
rbtm:=lite;
rbts:=-1;
rbsq:=ÆÅ;
end;
castleÆliteÅ:=false; castleÆdarkÅ:=false;
end;
procedure cutatk(a: ts); (* cut attacks trough square *)
var
inrs : rs;
ints : ts;
imrs : rs;
intd : td;
intm : tm;
intl : tl;
intt : tt;
begin
inrs:=atktoÆaÅ;
while nxtts(inrs,ints) do
if xspbÆnbordÆintsÅÅ then
begin
intd:=xlldÆxtslÆaÅ-xtslÆintsÅÅ;
intm:=xtpmÆnbordÆintsÅÅ;
intl:=xtslÆaÅ+intd;
intt:=xtlsÆintlÅ;
while intt > att do
begin
clrrs(atkfrÆintsÅ,intt);
clrrs(atktoÆinttÅ,ints);
andrs(imrs,atktoÆinttÅ,tmlocÆintmÅ);
if nulrs(imrs) then clrrs(alatkÆintmÅ,intt);
if nbordÆinttÅ = mt then
begin
intl:=intl+intd;
intt:=xtlsÆintlÅ;
end else intt:=att;
end;
end;
end;
procedure delatk(a: ts); (* delete attacks from square *)
var
inrs : rs;
imrs : rs;
ints : ts;
intm : tm;
begin
inrs:=atkfrÆaÅ;
newrs(atkfrÆaÅ);
intm:=xtpmÆnbordÆaÅÅ;
while nxtts(inrs,ints) do
begin
clrrs(atktoÆintsÅ,a);
andrs(imrs,atktoÆintsÅ,tmlocÆintmÅ);
if nulrs(imrs) then clrrs(alatkÆintmÅ,ints);
clrrs(tplocÆnbordÆaÅÅ,a);
clrrs(tmlocÆintmÅ,a);
clrrs(allocÆjntkÅ,a);
setrs(tplocÆmtÅ,a);
nbordÆaÅ:=mt;
end;
end;
procedure prpatk(a: ts); (*propagate attacks trough square *)
var
inrs : rs;
ints : ts;
intd : td;
intm : tm;
intl : tl;
intt : tt;
begin
inrs:=atktoÆaÅ;
while nxtts(inrs,ints) do
if xspbÆnbordÆintsÅÅ then
begin
intd:=xlldÆxtslÆaÅ-xtslÆintsÅÅ;
intm:=xtpmÆnbordÆintsÅÅ;
intl:=xtslÆaÅ+intd;
intt:=xtlsÆintlÅ;
while intt >=0 do
begin
setrs(atkfrÆintsÅ,intt);
setrs(atktoÆinttÅ,ints);
setrs(alatkÆintmÅ,intt);
if nbordÆinttÅ = mt then
begin
intl:=intl+intd;
intt:=xtlsÆintlÅ;
end else intt:=-1;
end;
end;
end;
procedure gainit(a: rm); (* unprocess capture move *)
begin
with a do
begin
addloc(rmfr,nbordÆrmtoÅ);
addatk(rmfr);
cutatk(rmfr);
delatk(rmto);
addloc(rmto,rmcp);
addatk(rmto);
mbtpac(nbordÆrmtoÅ);
end;
end;
procedure loseit(a: rm); (* process capture move *)
begin
with a do
begin
mbcapt(nbordÆrmtoÅ);
delatk(rmto);
addloc(rmto,nbordÆrmfrÅ);
delatk(rmfr);
prpatk(rmfr);
addatk(rmto);
end;
end;
procedure moveit(a: rm); (* process ordinary move *)
begin
with a do
begin
addloc(rmto,nbordÆrmfrÅ);
cutatk(rmto);
delatk(rmfr);
prpatk(rmfr);
addatk(rmto);
end;
end;
procedure rtrkit(a: rm); (* unprocess ordinary move *)
begin
with a do
begin
addloc(rmfr,nbordÆrmtoÅ);
cutatk(rmfr);
delatk(rmto);
prpatk(rmto);
addatk(rmfr);
end;
end;
procedure pawnit(a: rm); (* unpromote a pawn *)
begin
with a do
begin
mbmorp(nbordÆrmtoÅ);
nbordÆrmtoÅ:=xtumpÆep,xtpmÆnbordÆrmtoÅÅÅ;
end;
end;
procedure proacs(a: rm);(* process mover affecting castle status *)
procedure proaca(a: ts); (* process castle status changes *)
var
inrs : rs;
imrs : rs;
begin
clrrs(cstatÆjntkÅ,a);
andrs(inrs,cstatÆjntkÅ,xrrsÆxtsrÆaÅÅ);
if not inrstb(inrs,xtrfsÆxtsrÆaÅ,f5Å) then
andrs(cstatÆjntkÅ,cstatÆjntkÅ,xnrsÆxtsrÆaÅÅ);
andrs(imrs,inrs,xrfsÆf8Å);
andrs(inrs,inrs,xrfsÆf1Å);
iorrs(inrs,inrs,imrs);
if nulrs(inrs) then andrs(cstatÆjntkÅ,cstatÆjntkÅ,xnrsÆxtsrÆaÅÅ);
end;
begin
with a do
begin
if inrstb(cstatÆjntkÅ,rmfr) then proaca(rmfr);
if inrstb(cstatÆjntkÅ,rmto) then proaca(rmto);
end;
end;
procedure promot(a: rm); (* process promotion *)
begin
with a do
begin
mbprom(xtgmpÆrmpp,jntmÅ);
nbordÆrmfrÅ:=xtgmpÆrmpp,jntmÅ;
end;
end;
(* chess.p05 *)
procedure genone(a: tt; b: ts); (* stack one generated move *)
var
inrs : rs;
begin
with movesÆjntwÅ do
begin
rmfr:=a;
rmto:=b;
rmcp:=nbordÆbÅ;
rmca:=(nbordÆbÅ <> mt);
iorrs(inrs,xrssÆaÅ,xrssÆbÅ);
andrs(inrs,inrs,cstatÆjntkÅ);
rmac:=not nulrs(inrs);
rmch:=false;
rmmt:=false;
rmil:=false;
rmsu:=false;
rmpr:=false;
rmoo:=false;
rmep:=false;
end;
valuuÆjntwÅ:=0;
if jntw < zw then jntw:=jntw+1;
if jntw = zw then writeln('*** MOVE LIMITS ***');
end;
procedure dndate(a: rm); (* downdate data base to back out a move *)
var
ints : ts;
intr : tr;
intf : tf;
rkfr : ts;
rkto : ts;
begin
with a do
begin
case ord(rmca)*4 + ord(rmac)*2 + ord(rmpr) of
0: rtrkit(a); (* ordinary move *)
1: begin (* pawn move and promote *)
pawnit(a);
rtrkit(a);
end;
2: if rmoo then (* miscellaneous acs *)
begin
if rmqs then intf:=f1 else intf:=f8;
intr:=xtsrÆrmfrÅ;
rkfr:=xtrfsÆintr,intfÅ;
rkto:=(rmfr+rmto) div 2;
castleÆjntmÅ:=false;
addloc(rkfr,nbordÆrktoÅ);
delatk(rkto);
prpatk(rkto);
addatk(rkfr);
rtrkit(a);
end else rtrkit(a);
3: ; (* null move *)
4: if rmep then (* capture enpassant *)
begin
ints:=xtrfsÆxtsrÆrmfrÅ,xtsfÆrmtoÅÅ;
addloc(ints,rmcp);
cutatk(ints);
addatk(ints);
rtrkit(a);
mbtpac(nbordÆintsÅ);
end else gainit(a);
5: begin (* capture and promote *)
pawnit(a);
gainit(a);
end;
6: gainit(a); (* capture acs *)
7: begin (* capture rook acs, promote *)
pawnit(a);
gainit(a);
end;
end;
jntw:=lindxÆjntkÅ;
jntk:=jntk-1;
jntm:=otherÆjntmÅ;
end;
end; (* dndate *)
procedure create; (* create global data base *)
var
inrs : rs;
intm : tm;
intp : tp;
intq : tq;
ints : ts;
begin
with board do
begin
jntw:=aw+1;
jntk:=ak;
jntm:=rbtm;
nodes:=0;
lindxÆjntkÅ:=jntw;
srchmÆjntkÅ:=h0;
for ints:= as to zs do
begin
newrs(atkfrÆintsÅ);
newrs(atktoÆintsÅ);
nbordÆintsÅ:=mt;
end;
newrs(allocÆjntkÅ);
for intp:=lp to mt do newrs(tplocÆintpÅ);
for intm:=lite to none do
begin
newrs(tmlocÆintmÅ);
newrs(alatkÆintmÅ);
end;
mbtot:=0;
mbpwnÆliteÅ:=0;
mbpwnÆdarkÅ:=0;
mblte:=0;
maxps:=0;
for ints:=as to zs do
if rbisÆintsÅ <> mt then
begin
addloc(ints,rbisÆintsÅ);
mbtpac(rbisÆintsÅ);
end else setrs(tplocÆmtÅ,ints);
mbeval;
inrs:=allocÆjntkÅ;
while nxtts(inrs,ints) do addatk(ints);
newrs(cstatÆjntkÅ);
for intq:=ls to dl do
if intq in rbsq then iorrs(cstatÆjntkÅ,cstatÆjntkÅ,xsqsÆintqÅ);
newrs(enpasÆjntkÅ);
if rbts >= 0 then setrs(enpasÆjntkÅ,rbts);
genpnÆjntkÅ:=tplocÆxtumpÆep,jntmÅÅ;
notrs(gentoÆjntkÅ,tmlocÆjntmÅ);
notrs(inrs,genpnÆjntkÅ);
andrs(genfrÆjntkÅ,tmlocÆjntmÅ,inrs);
end;
end; (* create *)
function update(var a: rm):tb; (* update data base for a move *)
var
inrs : rs;
imrs : rs;
ints : ts;
intf : tf;
intr : tr;
rkto : ts;
rkfr : ts;
begin
with a do
begin
jntk:=jntk+1;
if jntk = zk then writeln('*** SEARCH LIMIT ***');
newrs(enpasÆjntkÅ);
cstatÆjntkÅ:=cstatÆjntk-1Å;
allocÆjntkÅ:=allocÆjntk-1Å;
mbvalÆjntkÅ:=mbvalÆjntk-1Å;
lindxÆjntkÅ:=jntw;
case ord(rmca)*4 +ord(rmac)*2 + ord(rmpr) of
0: if rmep then (* ordinary move *)
begin (* pawn move 2 spaces *)
sftrs(inrs,xrssÆrmtoÅ,s1);
sftrs(imrs,xrssÆrmtoÅ,s3);
iorrs(inrs,inrs,imrs);
andrs(inrs,inrs,tplocÆxtumpÆep,otherÆjntmÅÅÅ);
if not nulrs(inrs) then setrs(enpasÆjntkÅ,(rmto+rmfr) div 2);
moveit(a);
end else moveit(a);
1: begin (* move and promote *)
promot(a);
moveit(a);
end;
2: begin (* miscellaneous acs *)
if rmoo then
begin (* castle *)
if rmqs then intf:=f1 else intf:=f8;
intr:=xtsrÆrmfrÅ;
rkfr:=xtrfsÆintr,intfÅ;
rkto:=(rmfr+rmto) div 2;
andrs(cstatÆjntkÅ,cstatÆjntkÅ,xnrsÆintrÅ);
castleÆotherÆjntmÅÅ:=true;
addloc(rkto,nbordÆrkfrÅ);
addatk(rkto);
delatk(rkfr);
moveit(a);
end else
begin
proacs(a);
moveit(a);
end;
end;
3: ; (* null move *)
4: if rmep then (* capture *)
begin
ints:=xtrfsÆxtsrÆrmfrÅ,xtsfÆrmtoÅÅ;
mbcapt(nbordÆintsÅ);
delatk(ints);
prpatk(ints);
moveit(a);
end else loseit(a);
5: begin (* capture and promote *)
promot(a);
loseit(a);
end;
6: begin (* capture acs *)
proacs(a);
loseit(a);
end;
7: begin (* capture rook acs, promote *)
promot(a);
proacs(a);
loseit(a);
end;
end;
(* initialize move generation *)
jntm:=otherÆjntmÅ;
genpnÆjntkÅ:=tplocÆxtumpÆep,jntmÅÅ;
notrs(gentoÆjntkÅ,tmlocÆjntmÅ);
notrs(inrs,genpnÆjntkÅ);
andrs(genfrÆjntkÅ,tmlocÆjntmÅ,inrs);
(* determine if move leaves king in check, or moves king into check *)
andrs(inrs,tplocÆxtumpÆek,jntmÅÅ,alatkÆotherÆjntmÅÅ);
rmch:=not nulrs(inrs);
andrs(inrs,tplocÆxtumpÆek,otherÆjntmÅÅÅ,alatkÆjntmÅ);
rmil:=not nulrs(inrs);
update:= not rmil;
if not rmil then mvselÆjntk-1Å:=mvselÆjntk-1Å+1;
(* initialize move searching *)
srchmÆjntkÅ:=h1;
nodes:=nodes+1;
end;
end; (* update *)
procedure pwnpro; (* generate all promotion moves *)
var
intg : tg;
begin
movesÆjntw-1Å.rmpr:=true;
movesÆjntw-1Å.rmpp:=pq;
for intg:=pr to pb do
begin
movesÆjntwÅ:=movesÆjntw-1Å;
movesÆjntwÅ.rmpp:=intg;
jntw:=jntw+1;
end;
end;
procedure genpwn(a: rs;b: rs); (* generate pawn moves *)
var
inrs : rs;
imrs : rs;
ints : ts;
begin
if jntm = lite then
begin (* white pawn *)
sftrs(inrs,a,s2);
andrs(inrs,tplocÆmtÅ,inrs);
imrs:=inrs;
andrs(inrs,b,inrs);
while nxtts(inrs,ints) do
begin
genone(xtlsÆxtslÆintsÅ-xtedÆs2ÅÅ,ints);
if ints >= xtrfsÆr8,f1Å then pwnpro;
end;
andrs(inrs,imrs,xrrsÆr3Å);
sftrs(inrs,inrs,s2);
andrs(inrs,inrs,tplocÆmtÅ);
andrs(inrs,inrs,b);
while nxtts(inrs,ints) do
begin
genone(xtlsÆxtslÆintsÅ-2*xtedÆs2ÅÅ,ints);
movesÆjntw-1Å.rmep:=true;
end;
sftrs(inrs,a,b1);
iorrs(imrs,tmlocÆotherÆjntmÅÅ,enpasÆjntkÅ);
andrs(imrs,imrs,b);
andrs(inrs,inrs,imrs);
while nxtts(inrs,ints) do
begin
genone(xtlsÆxtslÆintsÅ-xtedÆb1ÅÅ,ints);
movesÆjntw-1Å.rmca:=true;
movesÆjntw-1Å.rmep:=inrstb(enpasÆjntkÅ,ints);
if movesÆjntw-1Å.rmep then movesÆjntw-1Å.rmcp:=dp;
if ints >= xtrfsÆr8,f1Å then pwnpro;
end;
sftrs(inrs,a,b2);
iorrs(imrs,tmlocÆotherÆjntmÅÅ,enpasÆjntkÅ);
andrs(imrs,imrs,b);
andrs(inrs,inrs,imrs);
while nxtts(inrs,ints) do
begin
genone(xtlsÆxtslÆintsÅ-xtedÆb2ÅÅ,ints);
movesÆjntw-1Å.rmca:=true;
movesÆjntw-1Å.rmep:=inrstb(enpasÆjntkÅ,ints);
if movesÆjntw-1Å.rmep then movesÆjntw-1Å.rmcp:=dp;
if ints >= xtrfsÆr8,f1Å then pwnpro;
end;
end else
begin (* black pawns *)
sftrs(inrs,a,s4);
andrs(inrs,tplocÆmtÅ,inrs);
imrs:=inrs;
andrs(inrs,b,inrs);
while nxtts(inrs,ints) do
begin
genone(xtlsÆxtslÆintsÅ-xtedÆs4ÅÅ,ints);
if ints <= xtrfsÆr1,f8Å then pwnpro;
end;
andrs(inrs,imrs,xrrsÆr6Å);
sftrs(inrs,inrs,s4);
andrs(inrs,inrs,tplocÆmtÅ);
andrs(inrs,inrs,b);
while nxtts(inrs,ints) do
begin
genone(xtlsÆxtslÆintsÅ-2*xtedÆs4ÅÅ,ints);
movesÆjntw-1Å.rmep:=true;
end;
sftrs(inrs,a,b3);
iorrs(imrs,tmlocÆotherÆjntmÅÅ,enpasÆjntkÅ);
andrs(imrs,imrs,b);
andrs(inrs,inrs,imrs);
while nxtts(inrs,ints) do
begin
genone(xtlsÆxtslÆintsÅ-xtedÆb3ÅÅ,ints);
movesÆjntw-1Å.rmca:=true;
movesÆjntw-1Å.rmep:=inrstb(enpasÆjntkÅ,ints);
if movesÆjntw-1Å.rmep then movesÆjntw-1Å.rmcp:=lp;
if ints <= xtrfsÆr1,f8Å then pwnpro;
end;
sftrs(inrs,a,b4);
iorrs(imrs,tmlocÆotherÆjntmÅÅ,enpasÆjntkÅ);
andrs(imrs,imrs,b);
andrs(inrs,inrs,imrs);
while nxtts(inrs,ints) do
begin
genone(xtlsÆxtslÆintsÅ-xtedÆb4ÅÅ,ints);
movesÆjntw-1Å.rmca:=true;
movesÆjntw-1Å.rmep:=inrstb(enpasÆjntkÅ,ints);
if movesÆjntw-1Å.rmep then movesÆjntw-1Å.rmcp:=lp;
if ints <= xtrfsÆr1,f8Å then pwnpro;
end;
end;
end; (* genpwn *)
(* chess.p06 *)
procedure genfsl(a: rs);(* generate all moves from a set of squares *)
var (* origin set *)
inrs : rs;
imrs : rs;
iprs : rs;
ints : ts;
imts : ts;
begin
andrs(inrs,a,genfrÆjntkÅ);
notrs(imrs,a);
andrs(genfrÆjntkÅ,genfrÆjntkÅ,imrs);
andrs(iprs,a,genpnÆjntkÅ);
andrs(genpnÆjntkÅ,genpnÆjntkÅ,imrs);
while nxtts(inrs,ints) do
begin
andrs(imrs,atkfrÆintsÅ,gentoÆjntkÅ);
while nxtts(imrs,imts) do genone(ints,imts);
end;
if not nulrs(iprs) then genpwn(iprs,gentoÆjntkÅ);
end;
procedure gentsl(a: rs);(* generate all moves to a set of squares *)
var (* target set *)
inrs : rs;
imrs : rs;
iprs : rs;
ints : ts;
imts : ts;
begin
andrs(inrs,a,gentoÆjntkÅ);
notrs(imrs,a);
andrs(gentoÆjntkÅ,gentoÆjntkÅ,imrs);
iprs:=inrs;
while nxtts(inrs,ints) do
begin
andrs(imrs,atktoÆintsÅ,genfrÆjntkÅ);
while nxtts(imrs,imts) do genone(imts,ints);
end;
if not nulrs(iprs) then genpwn(genpnÆjntkÅ,iprs);
end;
procedure genkillr(from, ito : ts); (* generate killer move *)
var frrs, tors, inrs, iprs : rs;
begin
frrs:=xrssÆfromÅ;
tors:=xrssÆitoÅ;
andrs(iprs,frrs,genpnÆjntkÅ); (* valid pawn from square *)
if not nulrs(iprs) then (* pawn move *)
begin
andrs(inrs,tors,gentoÆjntkÅ); (* only vaild dest.square *)
if not nulrs(inrs) then
begin
clrrs(gentoÆjntkÅ,ito); (* remove dest.square *)
genpwn(iprs,tors);
end;
end
else
begin (* normal move *)
andrs(inrs,frrs,genfrÆjntkÅ); (* only valid from square *)
if not nulrs(inrs) then
begin
andrs(inrs,atkfrÆfromÅ,gentoÆjntkÅ);
andrs(inrs,inrs,tors); (* only valid dest.square *)
if not nulrs(inrs) then
begin
clrrs(gentoÆjntkÅ,ito); (* remove dest.square *)
genone(from,ito);
end;
end;
end;
end;
procedure gencap; (* generate capture moves *)
var inrs : rs;
begin
iorrs(inrs,enpasÆjntkÅ,tmlocÆotherÆjntmÅÅ);
gentsl(inrs);
end;
procedure gencas; (* generate castle moves *)
var
intq : tq;
inrs : rs;
imrs : rs;
begin
for intq:=xtmqÆjntmÅ to succ(xtmqÆjntmÅ) do
if inrstb(cstatÆjntkÅ,xtqsÆintqÅ) then
begin
andrs(inrs,xrqsoÆintqÅ,allocÆjntkÅ);
andrs(imrs,xrqsaÆintqÅ,alatkÆotherÆjntmÅÅ);
if nulrs(inrs) and nulrs(imrs) then
begin
movesÆjntwÅ:=xrqmÆintqÅ;
valuuÆjntwÅ:=0;
jntw:=jntw+1;
end;
end;
end;
procedure genall; (* generate all legal moves *)
begin
genfsl(allocÆjntkÅ); (* generate simple moves *)
gencas; (* generate castle moves *)
end;
procedure lstmov; (* lst legal players moves *)
var intw : tw;
begin
create;
genall;
for intw:=aw+1 to jntw-1 do
begin
if update(movesÆintwÅ) then ;
dndate(movesÆintwÅ);
end;
end;
procedure themov(a: rm); (* make the move for real *)
var
intb : tb;
inrs : rs;
intq : tq;
ints : ts;
begin
lstmv:=a;
intb:=update(a);
with board do
begin
rbtm:=jntm;
inrs:=enpasÆjntkÅ;
if nxtts(inrs,ints) then rbts:=ints else rbts:=att;
if jntm = dark then rbti:=rbti+1;
for intq:=ls to dl do
if inrstb(cstatÆjntkÅ,xtqsÆintqÅ) then rbsq:=rbsq+ÆintqÅ
else rbsq:=rbsq-ÆintqÅ;
for ints:=as to zs do rbisÆintsÅ:=nbordÆintsÅ;
end;
end;
function search: tw; (* search look-ahead tree, return the best move *)
label 11,12,13,14,15,16;
procedure evalu8; (* evaluate current position *)
var
intv : tv;
imtv : tv;
intq : tq;
inrs : rs;
function evatk(a: tm): tv;
var
inrs : rs;
ints : ts;
intv : tv;
begin
intv:=0;
inrs:=tplocÆxtumpÆek,otherÆaÅÅÅ;
if nxtts(inrs,ints) then
begin
andrs(inrs,atkfrÆintsÅ,alatkÆaÅ);
intv:=cntrs(inrs)*faking;
end;
andrs(inrs,alatkÆaÅ,tmlocÆaÅ);
notrs(inrs,inrs);
andrs(inrs,inrs,tmlocÆaÅ);
while nxtts(inrs,ints) do (* piece not cover *)
if xtpuÆnbordÆintsÅÅ <> eq then
intv:=intv - abs(xtpvÆnbordÆintsÅÅ) div fwattk;
evatk:=intv;
if swtr then write(' A',intv:0);
end;
function evking(a, b: rs): tv;
var
ints : ts;
inrs : rs;
intv : tv;
begin
intv:=0;
inrs:=a;
if nxtts(inrs,ints) then
begin
andrs(inrs,atkfrÆintsÅ,b);
intv:=intv+cntrs(inrs)*fkpshd;
end;
evking:=intv;
if swtr then write(' K',intv:0);
end;
function evmobl(a, b: tp): tv;
var
inrs : rs;
ints : ts;
intv : tv;
begin
iorrs(inrs,tplocÆaÅ,tplocÆbÅ);
intv:=0;
while nxtts(inrs,ints) do intv:=intv+cntrs(atkfrÆintsÅ);
evmobl:=intv;
if swtr then write(' M',intv:0);
end;
function evpawn(a: rs; b: te; c: tr; d: tm):tv;
var
i : ti;
inrs : rs;
imrs : rs;
ints : ts;
imts : ts;
intf : tf;
infs : arrayÆtfÅ of ts;
intv : tv;
begin
sftrs(inrs,a,s1);
andrs(inrs,inrs,a);
intv:=cntrs(inrs)*fpflnx;
sftrs(inrs,a,b1);
andrs(inrs,inrs,a);
intv:=intv+cntrs(inrs)*fpconn;
sftrs(inrs,a,b2);
andrs(inrs,inrs,a);
intv:=intv+cntrs(inrs)*fpconn;
sftrs(inrs,a,b);
andrs(inrs,inrs,tmlocÆdÅ);
i:=cntrs(inrs);
if i > 0 then (* blocked by own piece *)
begin
intv:=intv-i*fpblok; (* penalize for blocked *)
andrs(imrs,inrs,a);
intv:=intv-cntrs(imrs)*fpblok; (* double if own pawn *)
andrs(imrs,inrs,tplocÆxtumpÆen,dÅÅ);
intv:=intv+cntrs(imrs)*(fpblok-fpblok div 4); (* 1/4 if N *)
andrs(imrs,inrs,tplocÆxtumpÆeq,dÅÅ);
intv:=intv+cntrs(imrs)*(fpblok-fpblok div 2); (* 1/2 if Q *)
end;
inrs:=a;
for intf:=f1 to f8 do infsÆintfÅ:=as;
while nxtts(inrs,ints) do
begin
intf:=xtsfÆintsÅ;
imts:=xtrfsÆc,f1Å;
if infsÆintfÅ > as then
if c = r2 then imts:=max(infsÆintfÅ,ints)
else imts:=min(infsÆintfÅ,ints);
infsÆintfÅ:=ints;
intv:=intv+(abs(ord(c)-ord(xtsrÆintsÅ))-
abs(ord(c)-ord(xtsrÆimtsÅ)))*fpadcrÆintfÅ;
end;
evpawn:=intv;
if swtr then write(' P',intv:0);
end;
function evrook(a, b: rs): tv;
var
intv : tv;
inti : ti;
ints : ts;
inrs : rs;
begin
intv:=0;
inrs:=a;
if nxtts(inrs,ints) then
begin
andrs(inrs,a,atkfrÆintsÅ);
if not nulrs(inrs) then intv:=intv+frdubl;
end;
andrs(inrs,a,b);
inti:=cntrs(inrs);
intv:=intv+inti*inti*frk7th;
evrook:=intv;
if swtr then write(' R',intv:0);
end;
begin
if swtr then write('MB',mbvalÆjntkÅ:0);
if xtmvÆjntmÅ*mbvalÆjntkÅ+maxps <= bstvlÆjntk-2Å then
intv:=xtmvÆjntmÅ*mbvalÆjntkÅ
else
begin
intv:=
(fwpawn*(evpawn(tplocÆlpÅ,s2,r2,lite)-evpawn(tplocÆdpÅ,s4,r7,dark))
+fwminm*(evmobl(lb,ln) -evmobl(db,dn) )
+fwmajm*(evmobl(lr,lq) -evmobl(dr,dq) )
+fwrook*(evrook(tplocÆlrÅ,xrrsÆr7Å)-evrook(tplocÆdrÅ,xrrsÆr2Å))
+fwking*(evking(tplocÆlkÅ,tplocÆlpÅ)-evking(tplocÆdkÅ,tplocÆdpÅ))
) div 64;
if swtr then write(' v=',intv:0);
imtv:=0;
for intq:=ls to dl do
if inrstb(cstatÆjntkÅ,xtqsÆintqÅ) then (* castle legal *)
begin
andrs(inrs,xrqsoÆintqÅ,tplocÆmtÅ);
case intq of
ls : imtv:=imtv+(cntrs(inrs)+1)*2;
ll : imtv:=imtv+(cntrs(inrs)+1);
ds : imtv:=imtv-(cntrs(inrs)+1)*2;
dl : imtv:=imtv-(cntrs(inrs)+1);
end;
end;
intv:=intv+imtv*fcfree;
if castleÆliteÅ then intv:=intv-(fksanq-(board.rbti+jntk));
if castleÆdarkÅ then intv:=intv+(fksanq-(board.rbti+jntk));
if swtr then write(' vc=',intv:0);
intv:=intv + (evatk(lite) - evatk(dark));
if movesÆindexÆjntkÅÅ.rmch then
intv:=intv-xtmvÆjntmÅ*fcheck; (* bonus *)
maxps:=max(maxps,abs(intv));
intv:=xtmvÆjntmÅ*(mbvalÆjntkÅ+intv);
end;
if swtr then
begin
writeln(' MPS',maxps:0,' TM',xtmvÆjntmÅ:0,' V=',intv:0);
write(' ':jntk*2,' EVALU8 ',jntk:0,' ',jntw:0,' ',indexÆjntkÅ:0,' ',intv:0);
primov(movesÆindexÆjntkÅÅ);
end;
valuuÆindexÆjntkÅÅ:=intv;
end;
procedure newbst(a: tk); (* save best move *)
var
intw : tw;
inrm : rm;
begin
bstmvÆaÅ:=indexÆa+1Å;
if a = ak then
begin
inrm:=movesÆbstmvÆaÅÅ;
if swbm then
begin
write('* NEWBEST * ');
primov(inrm);
write(' ',bstvlÆak+1Å:5,' ');
primov(movesÆbstmvÆak+1ÅÅ);
end;
for intw:=bstmvÆaÅ-1 downto aw+1 do
movesÆintw+1Å:=movesÆintwÅ;
movesÆaw+1Å:=inrm;
bstmvÆakÅ:=aw+1;
end else
if not movesÆbstmvÆaÅÅ.rmca then
killrÆjntkÅ:=movesÆbstmvÆaÅÅ;
end;
function minmax(a: tk): tb;
begin
minmax:=false;
if swtr then
write(' ':jntk*2,' MINMAX ',a:0,' ',-bstvlÆa-1Å:0,
' ',bstvlÆaÅ:0,' ',-bstvlÆa+1Å:0);
if -bstvlÆa+1Å > bstvlÆaÅ then
begin
bstvlÆaÅ:=-bstvlÆa+1Å;
newbst(a);
minmax:=bstvlÆa+1Å <= bstvlÆa-1Å;
if swtr then write(' NEW BEST. PRUNE: ',bstvlÆa+1Å <= bstvlÆa-1Å);
end;
if swtr then writeln;
end;
procedure scorem; (* score mate *)
begin
writeln('*** SCOREM *** ',jntk:0);
movesÆindexÆjntkÅÅ.rmmt:=true;
if movesÆindexÆjntkÅÅ.rmch then valuuÆindexÆjntkÅÅ:=64*jntk-zv
else valuuÆindexÆjntkÅÅ:=0;
if swtr then
writeln(' ':jntk*2,' SCOREM ',jntk:0,' ',jntw:0,' ',indexÆjntkÅ:0,
' ',valuuÆindexÆjntkÅÅ:0);
end;
function select: tb; (* select next move to search *)
var
intb : tb;
intk : tk;
intw : tw;
imtw : tw;
kitw : tw;
intv : tv;
exit : tb;
procedure seldon;
begin
intb:=false;
if swtr then writeln(' ':jntk*2,' SELECT ',jntk:0,' END.');
exit:=true;
end;
procedure selmov(a: tw);
begin
intb:=true;
indexÆjntk+1Å:=a;
movesÆaÅ.rmsu:=true;
if swtr then
begin
if jntk = 0 then writeln;
write(' ':jntk*2,' SELECT ',jntk:0,' ',ord(srchmÆjntkÅ):0,' ',a:0);
primov(movesÆaÅ);
end;
exit:=true;
end;
procedure selnxt(a: th);
begin
indexÆjntk+1Å:=lindxÆjntkÅ-1;
srchmÆjntkÅ:=a;
end;
procedure selany;
label 99;
var intw: tw;
begin
for intw:=indexÆjntk+1Å+1 to jntw-1 do
if not movesÆintwÅ.rmsu then
begin
selmov(intw);
if exit then goto 99;
end;
99: (* exit *)
end;
begin
exit:=false;
repeat (* new search node *)
case srchmÆjntkÅ of
h0: begin (* initialize for new move *)
mvselÆjntkÅ:=0;
intv:=bstvlÆjntk-2Å;
bstvlÆjntk-2Å:=-zv;
maxps:=0;
genall;
for intw:=aw+1 to jntw-1 do
begin
if update(movesÆintwÅ) then
begin
indexÆjntkÅ:=intw;
evalu8;
end;
dndate(movesÆintwÅ);
end;
bstvlÆjntk-2Å:=intv;
sortit(valuu,moves,jntw-1);
for intk:=ak to zk do killrÆintkÅ:=nulmv;
if swtr or swps then
for intw:=aw+1 to jntw-1 do
begin
write(' PRELIM ',intw:0,' ',valuuÆintwÅ:0);
primov(movesÆintwÅ);
if intw/lpp = intw div lpp then pauser;
end;
selnxt(h6);
end;
h1: begin (* initialize at new depth *)
mvselÆjntkÅ:=0;
if jntk > jmtk then
begin
evalu8;
indexÆjntk+1Å:=aw;
bstvlÆjntk+1Å:=-valuuÆindexÆjntkÅÅ;
if movesÆindexÆjntkÅÅ.rmch and (jntk < zk) then
srchmÆjntkÅ:=h3
else
begin
if minmax(jntk) or (jntk = zk) then seldon;
if not exit then srchmÆjntkÅ:=h2;
end;
end else srchmÆjntkÅ:=h3;
if not exit then
begin
gencap;
selnxt(srchmÆjntkÅ);
end;
end;
h2: begin (* capture search *)
intw:=aw;
intv:=av;
for imtw:=lindxÆjntkÅ to jntw-1 do
with movesÆimtwÅ do
if not rmsu then
if abs(xtpvÆrmcpÅ) > intv then
begin
intv:=abs(xtpvÆrmcpÅ);
intw:=imtw;
end;
if intw <> aw then selmov(intw) else seldon;
end;
h3: begin (* full width search - capture *)
intw:=aw;
intv:=av;
for imtw:=lindxÆjntkÅ to jntw-1 do
with movesÆimtwÅ do
if not rmsu then
if abs(xtpvÆrmcpÅ) > intv then
begin
intv:=abs(xtpvÆrmcpÅ);
intw:=imtw;
end;
if intw <> aw then
selmov(intw)
else
if not nulmvb(killrÆjntkÅ) then
begin
imtw:=jntw;
genkillr(killrÆjntkÅ.rmfr,killrÆjntkÅ.rmto);
srchmÆjntkÅ:=h4;
if jntw > imtw then selmov(imtw);
end;
if not exit then selnxt(h4);
end;
h4: begin (* initialize scan of castle & other moves by killer piece *)
gencas;
selnxt(h5);
end;
h5: begin (* full width search *)
selany;
if not exit then
begin
genfsl(allocÆjntkÅ);
selnxt(h6);
end;
end;
h6: begin (* full width search - remainding move *)
selany;
if not exit then
begin
if mvselÆjntkÅ = 0 then scorem;
seldon;
end;
end;
h7: begin (* research first ply *)
jntw:=lindxÆak+1Å;
mvselÆakÅ:=0;
for intw:=aw+1 to jntw-1 do movesÆintwÅ.rmsu:=false;
if jmtk = ak+1 then write('** REDO ')
else write(jmtk:0,'. STAGES ');
write(nodes:0,' ');
primov(movesÆbstmvÆakÅÅ);
if swtr then
writeln(' ':jntk*2,' REDO ',jntk:0,' ',bstvlÆak-2Å:0,' ',bstvlÆak-1Å:0);
selnxt(h6);
end;
end;
until exit; (* select exit *)
select:=intb;
end;
begin (* search *)
bstmvÆakÅ:=aw;
indexÆjntkÅ:=aw;
movesÆawÅ:=lstmv;
bstvlÆak-2Å:=av;
evalu8;
if swsu then
begin
if swec then writeln(' ',board.rbti:0,'. ',-valuuÆawÅ:4);
writeln(' ',board.rbti:0,'. ',-valuuÆawÅ:4);
end else begin writeln; if swec then writeln end;
bstvlÆak-2Å:=valuuÆawÅ-window;
bstvlÆak-1Å:=-valuuÆawÅ-window;
jmtk:=ak+1;
while (jmtk < stages) and (jntk < max(zk div 2,zk-8)) do
begin
11: (* start new ply *)
bstvlÆjntkÅ:=bstvlÆjntk-2Å;
12: (* different first move *)
if not select then
begin
bstvlÆjntkÅ:=valuuÆindexÆjntkÅÅ;
newbst(jntk);
end else
begin
if update(movesÆindexÆjntk+1ÅÅ) then goto 11 else
begin
dndate(movesÆindexÆjntkÅÅ);
goto 12;
end;
13: (* float value back *)
if minmax(jntk) then goto 15;
14: (* find another move at this ply *)
if select then
if update(movesÆindexÆjntk+1ÅÅ) then goto 11 else
begin
dndate(movesÆindexÆjntkÅÅ);
goto 14;
end;
end;
15: (* back up a ply *)
if jntk > ak then
begin
dndate(movesÆindexÆjntkÅÅ);
goto 13;
end;
(* done with iteration *)
if (bstvlÆakÅ <= bstvlÆak-2Å) or (bstvlÆakÅ >= -bstvlÆak-1Å) then
begin (* no move found *)
if mvselÆakÅ = 0 then goto 16; (* no legal moves - give up *)
if stages-1 = jmtk then
begin
bstvlÆak-2Å:=-zv;
bstvlÆak-1Å:=-zv;
srchmÆakÅ:=h7;
jntw:=ak+1;
goto 11;
end;
end;
bstvlÆak-2Å:=bstvlÆakÅ-window;
bstvlÆak-1Å:=-bstvlÆakÅ-window;
jmtk:=jmtk+1;
srchmÆakÅ:=h7;
end;
16: (* exit search *)
search:=bstmvÆakÅ;
end; (* search *)
(* chess.p07 *)
procedure reader; (* read input from user *)
var
inra : ra;
intj : tj;
ok : tb;
procedure rdrerr(a: rn); (* print diagnostic and exit *)
var
intj : tj;
intn : tn;
begin
if not swec then
begin
write(' ');
for intj:=aj to zj-1 do write(ilineÆintjÅ);
writeln;
end;
for intj:=aj to jntj-1 do write(' ');
writeln('`'); (* pointer to error *)
for intn:=an to zn do write(aÆintnÅ);
writeln;
ok:=false;
end;
function rdrgnt(var a: ra): tb; (* get next token from command *)
var intj : tj;
begin
while (jntj < zj) and (ilineÆjntjÅ < 'A') do jntj:=jntj+1;
a:=' ';
intj:=aj;
while (jntj < zj) and (intj < za) and (ilineÆjntjÅ in Æ'A'..'Z'Å) do
begin
aÆintjÅ:=ilineÆjntjÅ;
intj:=intj+1;
jntj:=jntj+1;
end;
rdrgnt:=intj <> aj;
while ilineÆjntjÅ in Æ'A'..'Z'Å do jntj:=jntj+1;
end;
procedure rdrsft; (* skip first token in command line *)
var
inra : ra;
intb : tb;
begin
jntj:=aj;
intb:=rdrgnt(inra);
end;
procedure rdline; (* get next input line from user *)
var intj : tj; intc : tc;
begin
intj:=aj;
readln;
while not eoln(input) and (intj < zj) do
begin
read(intc); icardÆintjÅ:=intc;
intj:=intj+1;
end;
while intj < zj do
begin
icardÆintjÅ:=' ';
intj:=intj+1;
end;
for intj :=aj to zj-1 do
if icardÆintjÅ in Æ'a'..'z'Å then
icardÆintjÅ:=chr(ord(icardÆintjÅ)-ord(' '));
icardÆzjÅ:=';';
jmtj:=aj;
end;
function rdrmov: tb; (* extract next command from input line *)
var imtj : tj;
begin
while (jmtj < zj) and (icardÆjmtjÅ = ' ') do jmtj:=jmtj+1;
imtj:=aj;
while (jmtj < zj) and (icardÆjmtjÅ <> ';') do
begin
ilineÆimtjÅ:=icardÆjmtjÅ;
imtj:=imtj+1;
jmtj:=jmtj+1;
end;
if (icardÆjmtjÅ = ';') and (jmtj < zj) then jmtj:=jmtj+1;
rdrmov:=imtj <> aj;
while imtj < zj do
begin
ilineÆimtjÅ:=' ';
imtj:=imtj+1;
end;
ilineÆzjÅ:=';';
jntj:=aj;
end;
function rdrnum: ti; (* crack number from command line *)
var
intb : tb;
inti : ti;
begin
while (jntj < zj) and (ilineÆjntjÅ = ' ') do jntj:=jntj+1;
if ilineÆjntjÅ = '-' then
begin
intb:=true;
jntj:=jntj+1;
end else
begin
intb:=false;
if ilineÆjntjÅ = '+' then jntj:=jntj+1;
end;
inti:=0;
while ilineÆjntjÅ in Æ'0'..'9'Å do
begin
if inti < maxint div 10 then inti:=10*inti+ord(ilineÆjntjÅ)-ord('0')
else rdrerr(' NUMBER TOO LARGE ');
jntj:=jntj+1;
end;
if ok and (ilineÆjntjÅ in Æ'A'..'Z'Å) then
rdrerr(' DIGIT EXPECTED ');
if intb then inti:=-inti;
rdrnum:=inti;
end;
procedure boacmd; (* command - set up position *)
var
intm : tm;
ints : ts;
procedure boaadv(a: ti);
begin
if ints+a < zs then ints:=ints+a else ints:=zs;
end;
procedure boasto(a: tp);
begin
board.rbisÆintsÅ:=a;
if ints < zs then ints:=ints+1;
end;
begin
clstat;
lstmv:=nulmv;
for ints:=as to zs do board.rbisÆintsÅ:=mt;
intm:=lite;
ints:=0;
repeat
if ilineÆjntjÅ in Æ'P','R','N','B','Q','K','L','D','1'..'8'Å then
case ilineÆjntjÅ of
'P': boasto(xtumpÆep,intmÅ);
'R': boasto(xtumpÆer,intmÅ);
'N': boasto(xtumpÆen,intmÅ);
'B': boasto(xtumpÆeb,intmÅ);
'Q': boasto(xtumpÆeq,intmÅ);
'K': boasto(xtumpÆek,intmÅ);
'L': intm:=lite;
'D': intm:=dark;
'1','2','3','4','5','6','7','8': boaadv(ord(ilineÆjntjÅ)-ord('0'));
end
else
if ilineÆjntjÅ in Æ'A'..'9'Å then
begin
for ints:=as to zs do board.rbisÆintsÅ:=mt;
clstat;
rdrerr(' ILLEGAL BOARD OPTION ');
jntj:=zj-1;
end;
jntj:=jntj+1;
until jntj = zj;
lstmov;
end;
procedure endcmd; (* command - end program *)
begin com:=9 end;
procedure goncmd; (* command - go n moves *)
begin
going:=rdrnum;
if ok then com:=2;
if going <= 0 then going:=1;
end;
procedure inicmd; (* command - initialize for a new game *)
begin com:=1 end;
procedure letcmd; (* command - change variable *)
var inti : ti;
begin
while rdrgnt(inra) do
begin
inti:=rdrnum;
if ok then
begin
(* if inra = 'FKPSHD ' then fkpshd:=inti else
if inra = 'FKSANQ ' then fksanq:=inti else
if inra = 'FMAXMT ' then fmaxmt:=inti else
*) if inra = 'STAGES ' then stages:=inti else
(* if inra = 'FPADQR ' then fpadcrÆf1Å:=inti else
if inra = 'FPADQN ' then fpadcrÆf2Å:=inti else
if inra = 'FPADQB ' then fpadcrÆf3Å:=inti else
if inra = 'FPADQF ' then fpadcrÆf4Å:=inti else
if inra = 'FPADKF ' then fpadcrÆf5Å:=inti else
if inra = 'FPADKB ' then fpadcrÆf6Å:=inti else
if inra = 'FPADKN ' then fpadcrÆf7Å:=inti else
if inra = 'FPADKR ' then fpadcrÆf8Å:=inti else
if inra = 'FPBLOK ' then fpblok:=inti else
if inra = 'FPCONN ' then fpconn:=inti else
if inra = 'FPFLNX ' then fpflnx:=inti else
if inra = 'FRDUBL ' then frdubl:=inti else
if inra = 'FRK7TH ' then frk7th:=inti else
if inra = 'FTRADE ' then ftrade:=inti else
if inra = 'FTRDSL ' then ftrdsl:=inti else
if inra = 'FTRPOK ' then ftrpok:=inti else
if inra = 'FTRPWN ' then ftrpwn:=inti else
*) if inra = 'FWKING ' then fwking:=inti else
if inra = 'FWMAJM ' then fwmajm:=inti else
if inra = 'FWMINM ' then fwminm:=inti else
if inra = 'FWPAWN ' then fwpawn:=inti else
if inra = 'FWROOK ' then fwrook:=inti else
if inra = 'FCHECK ' then fcheck:=inti else
if inra = 'FWATTK ' then fwattk:=inti else
if inra = 'FAKING ' then faking:=inti else
if inra = 'FCFREE ' then fcfree:=inti else
if inra = 'WINDOW ' then window:=inti else
rdrerr(' ILLEGAL LET VARIABLE NAME ');
end;
end;
if ok then writeln('OK');
end;
procedure plecmd; (* command - print variable *)
begin
while rdrgnt(inra) do
begin
(* if inra = 'FKPSHD ' then writeln(inra,'= ', fkpshd) else
if inra = 'FKSANQ ' then writeln(inra,'= ', fksanq) else
if inra = 'FMAXMT ' then writeln(inra,'= ', fmaxmt) else
*) if inra = 'STAGES ' then writeln(inra,'= ', stages) else
(* if inra = 'FPADQR ' then writeln(inra,'= ', fpadcrÆf1Å) else
if inra = 'FPADQN ' then writeln(inra,'= ', fpadcrÆf2Å) else
if inra = 'FPADQB ' then writeln(inra,'= ', fpadcrÆf3Å) else
if inra = 'FPADQF ' then writeln(inra,'= ', fpadcrÆf4Å) else
if inra = 'FPADKF ' then writeln(inra,'= ', fpadcrÆf5Å) else
if inra = 'FPADKB ' then writeln(inra,'= ', fpadcrÆf6Å) else
if inra = 'FPADKN ' then writeln(inra,'= ', fpadcrÆf7Å) else
if inra = 'FPADKR ' then writeln(inra,'= ', fpadcrÆf8Å) else
if inra = 'FPBLOK ' then writeln(inra,'= ', fpblok) else
if inra = 'FPCONN ' then writeln(inra,'= ', fpconn) else
if inra = 'FPFLNX ' then writeln(inra,'= ', fpflnx) else
if inra = 'FRDUBL ' then writeln(inra,'= ', frdubl) else
if inra = 'FRK7TH ' then writeln(inra,'= ', frk7th) else
if inra = 'FTRADE ' then writeln(inra,'= ', ftrade) else
if inra = 'FTRDSL ' then writeln(inra,'= ', ftrdsl) else
if inra = 'FTRPOK ' then writeln(inra,'= ', ftrpok) else
if inra = 'FTRPWN ' then writeln(inra,'= ', ftrpwn) else
*) if inra = 'FWKING ' then writeln(inra,'= ', fwking) else
if inra = 'FWMAJM ' then writeln(inra,'= ', fwmajm) else
if inra = 'FWMINM ' then writeln(inra,'= ', fwminm) else
if inra = 'FWPAWN ' then writeln(inra,'= ', fwpawn) else
if inra = 'FWROOK ' then writeln(inra,'= ', fwrook) else
if inra = 'FCHECK ' then writeln(inra,'= ', fcheck) else
if inra = 'FWATTK ' then writeln(inra,'= ', fwattk) else
if inra = 'FAKING ' then writeln(inra,'= ', faking) else
if inra = 'FCFREE ' then writeln(inra,'= ', fcfree) else
if inra = 'WINDOW ' then writeln(inra,'= ', window) else
rdrerr(' ILLEGAL VARIABLE NAME ');
end;
end;
procedure pricmd; (* command - print board *)
begin
if rdrgnt(inra) then printb(nbord) else printb(board.rbis);
end;
procedure pamcmd; (* command - print attack map *)
begin
while rdrgnt(inra) do
if inraÆaaÅ = 'T' then prinam(atkto)
else
if inraÆaaÅ = 'F' then prinam(atkfr)
else rdrerr(' ATTACK MAP NOT "TO" OR "FROM"');
writeln(' LITE');
prinbb(alatkÆliteÅ);
writeln(' DARK');
prinbb(alatkÆdarkÅ);
end;
procedure popcmd; (* command - print other stuff *)
var intq : tq;
begin
with board do
begin
writeln(xtmaÆrbtmÅ,' TO MOVE.');
writeln(rbts,' ENPASSANT.');
writeln('MOVE NUMBER ',rbti:0);
for intq:=ls to dl do
if intq in rbsq then writeln(xtqaÆintqÅ,' SIDE CASTLE LEGAL.');
end;
end;
procedure pmvcmd; (* command - print move list *)
var intw : tw;
begin
for intw:=aw+1 to jntw-1 do
begin
write(intw:4,' ');
primov(movesÆintwÅ);
if intw/lpp = intw div lpp then pauser;
end;
end;
procedure swicmd; (* command - flip switch *)
procedure swione(var b: tb);
var
a : ra;
imtj : tj;
begin
imtj:=jntj;
a:=inra;
if rdrgnt(inra) then
begin
if inra = 'ON ' then b:=true
else
if inra = 'OFF ' then b:=false
else jntj:=imtj;
priswi(a,b);
end else priswi(a,b);
end;
begin
while rdrgnt(inra) and ok do
begin
if inra = 'EC ' then swione(swec) else
if inra = 'PA ' then swione(swpa) else
if inra = 'PS ' then swione(swps) else
if inra = 'RE ' then swione(swre) else
if inra = 'SU ' then swione(swsu) else
if inra = 'TR ' then swione(swtr) else
if inra = 'PR ' then swione(swpr) else
if inra = 'BM ' then swione(swbm) else
rdrerr(' INVALID SWITCH OPTION ');
end;
end;
procedure whacmd; (* command - print last message *)
begin writeln(movms) end;
procedure stacmd; (* command - status changes *)
var
inra : ra;
intm : tm;
procedure staepf(b: tf); (* process ep file *)
begin
if intm = lite then
board.rbts:=xtrfsÆr6,bÅ
else
board.rbts:=xtrfsÆr3,bÅ;
end;
procedure stacak; (* allow castle king side *)
begin
if intm = lite then
board.rbsq:=board.rbsq + ÆlsÅ
else
board.rbsq:=board.rbsq + ÆdsÅ;
end;
procedure stacaq; (* allow castle queen side *)
begin
if intm = lite then
board.rbsq:=board.rbsq + ÆllÅ
else
board.rbsq:=board.rbsq + ÆdlÅ;
end;
procedure staenp; (* set enpassant file *)
begin
if not rdrgnt(inra) then
begin
clstat;
rdrerr(' ENPASSANT FILE OMITTED ');
end;
if inra = 'QR ' then staepf(f1) else
if inra = 'QN ' then staepf(f2) else
if inra = 'QB ' then staepf(f3) else
if inra = 'Q ' then staepf(f4) else
if inra = 'K ' then staepf(f5) else
if inra = 'KB ' then staepf(f6) else
if inra = 'KN ' then staepf(f7) else
if inra = 'KR ' then staepf(f8) else
begin
clstat;
rdrerr(' ILLEGAL ENPASSANT FILE ');
end;
end;
procedure stagos; (* set side to move *)
begin
board.rbtm:=intm;
jntm:=intm;
end;
begin (* stacmd *)
clstat;
intm:=lite;
while rdrgnt(inra) and ok do
begin
if inra = 'D ' then intm:=dark else
if inra = 'EP ' then staenp else
if inra = 'G ' then stagos else
if inra = 'L ' then intm:=lite else
if inra = 'N ' then board.rbti:=rdrnum else
if inra = 'OO ' then stacak else
if inra = 'OOO ' then stacaq else
begin
clstat;
rdrerr(' INVALID STATUS OPTION ');
end;
end;
lstmov;
end;
begin
com:=0;
repeat
ok:=true;
while not rdrmov do rdline;
if swec then
begin
write(' ');
for intj:=aj to zj-1 do write(ilineÆintjÅ);
writeln;
end;
if ilineÆaj+1Å in Æ'A'..'W','Y'..'Z'Å then
begin
inra:=' ';
inraÆaaÅ:=ilineÆajÅ;
inraÆaa+1Å:=ilineÆaj+1Å;
rdrsft;
if inra = 'BO ' then boacmd else
if inra = 'EN ' then endcmd else
if inra = 'GO ' then goncmd else
if inra = 'IN ' then inicmd else
if inra = 'LE ' then letcmd else
if inra = 'PL ' then plecmd else
if inra = 'PR ' then pricmd else
if inra = 'PA ' then pamcmd else
if inra = 'PO ' then popcmd else
if inra = 'PM ' then pmvcmd else
if inra = 'SW ' then swicmd else
if inra = 'WH ' then whacmd else
if inra = 'ST ' then stacmd else
rdrerr(' INVALID COMMAND ');
end;
until (com > 0) or not(ilineÆaj+1Å in Æ'A'..'W','Y','Z'Å);
end; (* reader *)
(*chess.p02 *)
procedure inicon;
var
intd : td;
inte : te;
intf : tf;
inti : ti;
intl : tl;
intq : tq;
intr : tr;
intt : tt;
intx : tx;
inty : ty;
imti : ti;
x,sum : ti;
inrs : rs;
procedure inisyn(a: ra);
begin
with syntxÆintiÅ do
begin
with ryls do
begin
rdpc:=true;
rdsl:=aÆaa+0Å <> ' ';
rdkq:=aÆaa+1Å <> ' ';
rdnb:=aÆaa+2Å <> ' ';
rdrk:=aÆaa+3Å <> ' ';
end;
rych:=aÆaa+4Å;
with ryrs do
begin
rdpc:=aÆaa+5Å <> ' ';
rdsl:=aÆaa+6Å <> ' ';
rdkq:=aÆaa+7Å <> ' ';
rdnb:=aÆaa+8Å <> ' ';
rdrk:=aÆaa+9Å <> ' ';
end;
end;
inti:=inti+1;
end;
procedure inixtp(a:tp; b:tc; c:tm; d:tu; e:tb; f:te; g:te; h:tv);
begin
xtpcÆaÅ:=b;
xtpmÆaÅ:=c;
xspbÆaÅ:=e;
xfpeÆaÅ:=f;
xlpeÆaÅ:=g;
xtpuÆaÅ:=d;
xtpvÆaÅ:=h;
if a <> mt then xtumpÆd,cÅ:=a;
end;
begin
inixtp(lp,'P',lite,ep,false,b1,b2,1*64);
inixtp(lr,'R',lite,er,true ,s1,s4,5*64);
inixtp(ln,'N',lite,en,false,n1,n8,3*64);
inixtp(lb,'B',lite,eb,true ,b1,b4,3*64);
inixtp(lq,'Q',lite,eq,true ,b1,s4,9*64);
inixtp(lk,'K',lite,ek,false,b1,s4,0);
inixtp(dp,'P',dark,ep,false,b3,b4,-1*64);
inixtp(dr,'R',dark,er,true ,s1,s4,-5*64);
inixtp(dn,'N',dark,en,false,n1,n8,-3*64);
inixtp(db,'B',dark,eb,true ,b1,b4,-3*64);
inixtp(dq,'Q',dark,eq,true ,b1,s4,-9*64);
inixtp(dk,'K',dark,ek,false,b1,s4,0);
inixtp(mt,'.',none,ep,false,b2,b1,0);
xtgmpÆpq,liteÅ:=lq; xtgmpÆpq,darkÅ:=dq; xtgcÆpqÅ:='Q';
xtgmpÆpr,liteÅ:=lr; xtgmpÆpr,darkÅ:=dr; xtgcÆprÅ:='R';
xtgmpÆpn,liteÅ:=ln; xtgmpÆpn,darkÅ:=dn; xtgcÆpnÅ:='N';
xtgmpÆpb,liteÅ:=lb; xtgmpÆpb,darkÅ:=db; xtgcÆpbÅ:='B';
xtucÆekÅ:='K';
xtucÆeqÅ:='Q';
xtucÆerÅ:='R';
xtucÆenÅ:='N';
xtucÆebÅ:='B';
xtucÆepÅ:='P';
(* initialize other constants *)
xtbcÆfalseÅ:='-';
xtbcÆtrue Å:='*';
otherÆliteÅ:=dark; xtmvÆliteÅ:= 1;
otherÆdarkÅ:=lite; xtmvÆdarkÅ:=-1;
otherÆnoneÅ:=none;
xtmaÆliteÅ:=' WHITE ';
xtmaÆdarkÅ:=' BLACK ';
xtmaÆnoneÅ:=' NO ONE ';
xtqaÆlsÅ:='WHITE KING';
xtqaÆllÅ:='WHITE LONG';
xtqaÆdsÅ:='BLACK KING';
xtqaÆdlÅ:='BLACK LONG';
(* initialize 10X12 to 8X8 and 8X8 to 10X12 translation tables *)
for intl:=al to zl do xtlsÆintlÅ:=-1;
intl:=21;
intt:=-1;
for intr:=r1 to r8 do
begin
for intf:=f1 to f8 do
begin
intt:=intt+1;
xtrfsÆintr,intfÅ:=intt;
xtlsÆintlÅ:=intt;
xtslÆinttÅ:=intl;
xtsrÆinttÅ:=intr;
xtsfÆinttÅ:=intf;
intl:=intl+1;
end;
intl:=intl+2;
end;
(* initialize 8X8 to bit board tables *)
intt:=-1;
for inty:=ay to ay do
begin
for intx:=ax to zx do
begin
intt:=intt+1;
xtsxÆinttÅ:=intx;
xtsyÆinttÅ:=inty;
xssxÆinttÅ:=ÆintxÅ;
newrs(xrssÆinttÅ);
xrssÆinttÅ.rsss:=ÆintxÅ;
end;
end;
(* initialize constant bit boards *)
for intr:=r1 to r8 do newrs(xrrsÆintrÅ);
for intf:=f1 to f8 do newrs(xrfsÆintfÅ);
for intr:=r1 to r8 do
for intf:=f1 to f8 do
begin
setrs(xrrsÆintrÅ,xtrfsÆintr,intfÅ);
setrs(xrfsÆintfÅ,xtrfsÆintr,intfÅ);
end;
for intf:=f1 to f8 do notrs(xnfsÆintfÅ,xrfsÆintfÅ);
for intr:=r1 to r8 do notrs(xnrsÆintrÅ,xrrsÆintrÅ);
(* initialize edges *)
edgeÆs1Å:=xrfsÆf1Å;
edgeÆs2Å:=xrrsÆr8Å;
edgeÆs3Å:=xrfsÆf8Å;
edgeÆs4Å:=xrrsÆr1Å;
iorrs(edgeÆb1Å,edgeÆs1Å,edgeÆs2Å);
iorrs(edgeÆb2Å,edgeÆs2Å,edgeÆs3Å);
iorrs(edgeÆb3Å,edgeÆs3Å,edgeÆs4Å);
iorrs(edgeÆb4Å,edgeÆs4Å,edgeÆs1Å);
iorrs(edgeÆn1Å,edgeÆb1Å,xrrsÆr7Å);
iorrs(edgeÆn2Å,edgeÆb2Å,xrrsÆr7Å);
iorrs(edgeÆn3Å,edgeÆb2Å,xrfsÆf7Å);
iorrs(edgeÆn4Å,edgeÆb3Å,xrfsÆf7Å);
iorrs(edgeÆn5Å,edgeÆb3Å,xrrsÆr2Å);
iorrs(edgeÆn6Å,edgeÆb4Å,xrrsÆr2Å);
iorrs(edgeÆn7Å,edgeÆb4Å,xrfsÆf2Å);
iorrs(edgeÆn8Å,edgeÆb1Å,xrfsÆf2Å);
(* initialize corner mask *)
iorrs(inrs,xrrsÆr1Å,xrrsÆr2Å);
iorrs(inrs,inrs,xrrsÆr7Å);
iorrs(inrs,inrs,xrrsÆr8Å);
iorrs(cornr,xrfsÆf1Å,xrfsÆf2Å);
iorrs(cornr,cornr,xrfsÆf7Å);
iorrs(cornr,cornr,xrfsÆf8Å);
andrs(cornr,cornr,inrs);
(* initialize direction table *)
xtedÆn1Å:= 19; xtedÆn2Å:= 21;
xtedÆn8Å:= 8; xtedÆb1Å:= 9;
xtedÆs2Å:= 10; xtedÆb2Å:= 11;
xtedÆn3Å:= 12; xtedÆs1Å:= -1;
xtedÆs3Å:= 1; xtedÆn7Å:=-12;
xtedÆb4Å:=-11; xtedÆs4Å:=-10;
xtedÆb3Å:= -9; xtedÆn4Å:= -8;
xtedÆn6Å:=-21; xtedÆn5Å:=-19;
(* initialize square difference to direction table *)
for inti:=azl to zal do xlldÆintiÅ:=0;
for inte:=b1 to s4 do
begin
intd:=xtedÆinteÅ;
for imti:=1 to 7 do xlldÆimti*intdÅ:=intd;
end;
for inte:=n1 to n8 do xlldÆxtedÆinteÅÅ:=xtedÆinteÅ;
(* initialize castling translation tables *)
iorrs(xsqsÆlsÅ,xrssÆxtrfsÆr1,f8ÅÅ,xrssÆxtrfsÆr1,f5ÅÅ);
iorrs(xsqsÆllÅ,xrssÆxtrfsÆr1,f1ÅÅ,xrssÆxtrfsÆr1,f5ÅÅ);
iorrs(xsqsÆdsÅ,xrssÆxtrfsÆr8,f8ÅÅ,xrssÆxtrfsÆr8,f5ÅÅ);
iorrs(xsqsÆdlÅ,xrssÆxtrfsÆr8,f1ÅÅ,xrssÆxtrfsÆr8,f5ÅÅ);
iorrs(xrqsoÆlsÅ,xrssÆxtrfsÆr1,f6ÅÅ,xrssÆxtrfsÆr1,f7ÅÅ);
iorrs(xrqsoÆllÅ,xrssÆxtrfsÆr1,f4ÅÅ,xrssÆxtrfsÆr1,f3ÅÅ);
iorrs(xrqsaÆlsÅ,xrssÆxtrfsÆr1,f5ÅÅ,xrqsoÆlsÅ);
iorrs(xrqsaÆllÅ,xrssÆxtrfsÆr1,f5ÅÅ,xrqsoÆllÅ);
iorrs(xrqsoÆllÅ,xrssÆxtrfsÆr1,f2ÅÅ,xrqsoÆllÅ);
iorrs(xrqsoÆdsÅ,xrssÆxtrfsÆr8,f6ÅÅ,xrssÆxtrfsÆr8,f7ÅÅ);
iorrs(xrqsoÆdlÅ,xrssÆxtrfsÆr8,f4ÅÅ,xrssÆxtrfsÆr8,f3ÅÅ);
iorrs(xrqsaÆdsÅ,xrssÆxtrfsÆr8,f5ÅÅ,xrqsoÆdsÅ);
iorrs(xrqsaÆdlÅ,xrssÆxtrfsÆr8,f5ÅÅ,xrqsoÆdlÅ);
iorrs(xrqsoÆdlÅ,xrssÆxtrfsÆr8,f2ÅÅ,xrqsoÆdlÅ);
for intq:=ls to dl do
with xrqmÆintqÅ do
begin
rmcp:=mt;
rmca:=false;
rmac:=true;
rmch:=false;
rmmt:=false;
rmil:=false;
rmsu:=false;
rmpr:=false;
rmoo:=true;
end;
xrqmÆlsÅ.rmfr:=xtrfsÆr1,f5Å; xrqmÆlsÅ.rmto:=xtrfsÆr1,f7Å;
xrqmÆllÅ.rmfr:=xtrfsÆr1,f5Å; xrqmÆllÅ.rmto:=xtrfsÆr1,f3Å;
xrqmÆdsÅ.rmfr:=xtrfsÆr8,f5Å; xrqmÆdsÅ.rmto:=xtrfsÆr8,f7Å;
xrqmÆdlÅ.rmfr:=xtrfsÆr8,f5Å; xrqmÆdlÅ.rmto:=xtrfsÆr8,f3Å;
xrqmÆlsÅ.rmqs:=false;
xrqmÆllÅ.rmqs:=true;
xrqmÆdsÅ.rmqs:=false;
xrqmÆdlÅ.rmqs:=true;
xtmqÆliteÅ:=ls;
xtmqÆdarkÅ:=ds;
xtqsÆlsÅ:=xtrfsÆr1,f8Å;
xtqsÆllÅ:=xtrfsÆr1,f1Å;
xtqsÆdsÅ:=xtrfsÆr8,f8Å;
xtqsÆdlÅ:=xtrfsÆr8,f1Å;
(* initialize null move *)
with nulmv do
begin
rmfr:=as;
rmto:=as;
rmcp:=mt;
rmca:=false;
rmac:=true;
rmch:=false;
rmmt:=false;
rmil:=false;
rmsu:=false;
rmpr:=true;
rmpp:=pb;
end;
(* initialize countbit table *)
for inti:=0 to 255 do
begin
sum:=0;
x:=128;
imti:=inti;
while imti > 0 do
begin
if imti-x >= 0 then
begin
sum:=sum+1;
imti:=imti-x;
end;
x:=x div 2;
end;
ctÆintiÅ:=sum;
end;
(* initialize command processing variable *)
jmtj:=zj;
icardÆzjÅ:=';';
ilineÆzjÅ:=';';
(* initialize moves syntax table *)
inti:=syncf;
inisyn(' *P ');
inisyn(' *P/ 1');
inisyn('/ 1*P ');
inisyn(' *P/ R ');
inisyn('/ R *P ');
inisyn(' *P/ R1');
inisyn('/ R1*P ');
inisyn(' *P/ KR');
inisyn('/ KR*P ');
inisyn(' *P/KR1');
inisyn('/KR1*P/ ');
inisyn('/ 1*P/ 1');
inisyn('/ R *P/ R ');
inisyn('/ 1*P/ R ');
inisyn('/ R *P/ 1');
inisyn('/ R1*P/ 1');
inisyn('/ 1*P/ R1');
inisyn('/ R1*P/ R ');
inisyn('/ R *P/ R1');
inisyn('/KR *P/ 1');
inisyn('/ 1*P/KR ');
inisyn('/KR *P/ R ');
inisyn('/ R *P/KR ');
inisyn('/ 1*P/KR1');
inisyn('/KR1*P/ 1');
inisyn('/ R *P/KR1');
inisyn('/KR1*P/ R ');
inisyn('/ R1*P/ R1');
inisyn('/KR *P/ R1');
inisyn('/ R1*P/KR ');
inisyn('/KR *P/KR ');
inisyn('/KR1*P/ R1');
inisyn('/ R1*P/KR1');
inisyn('/KR1*P/KR ');
inisyn('/KR *P/KR1');
inisyn('/KR1*P/KR1');
inisyn(' - R1');
inisyn(' - KR1');
inisyn('/ 1- R1');
inisyn('/ R - R1');
inisyn('/ 1- KR1');
inisyn('/ R - KR1');
inisyn('/ R1- R1');
inisyn('/KR - R1');
inisyn('/ R1- KR1');
inisyn('/KR - KR1');
inisyn('/KR1- KR1');
(* initialize lets *)
fkpshd:=10;
fmaxmt:=2048;
stages:=2;
fpadcrÆf1Å:=1;
fpadcrÆf2Å:=2;
fpadcrÆf3Å:=4;
fpadcrÆf4Å:=6;
fpadcrÆf5Å:=7;
fpadcrÆf6Å:=4;
fpadcrÆf7Å:=2;
fpadcrÆf8Å:=1;
fpblok:=10;
fpconn:=5;
fpflnx:=3;
frdubl:=60;
frk7th:=120;
ftrade:=36;
ftrdsl:=5156;
ftrpok:=2;
ftrpwn:=8;
fwking:=20;
fwmajm:=64;
fwminm:=128;
fwpawn:=64;
fwrook:=2;
fcheck:=32;
fwattk:=16;
fksanq:=64;
fcfree:=4;
faking:=25;
window:=100;
(* initialize switches *)
swec:=false;
swpa:=true;
swps:=false;
swre:=true;
swsu:=true;
swtr:=false;
swpr:=false;
swbm:=false;
going:=0;
end; (* inicon *)
(* chess.p08 *)
procedure mineng(a: rm; b: ra); (* generate minimum english notation *)
var intn : tnn;
procedure addchr(a: tc); (* add character to message *)
begin
movmsÆintnÅ:=a;
if intn < znn then intn:=intn+1;
end;
procedure addsqr(a: ts; b: rd); (* add square to message *)
begin
with b do
begin
if rdpc then addchr(xtucÆxtpuÆnbordÆaÅÅÅ);
if rdsl then addchr('/');
if rdkq then
if xtsfÆaÅ in Æf1..f4Å then addchr('Q') else addchr('K');
if rdnb then
case xtsfÆaÅ of
f1,f8: addchr('R');
f2,f7: addchr('N');
f3,f6: addchr('B');
f4 : addchr('Q');
f5 : addchr('K');
end;
if rdrk then
if jntm = lite then
case xtsrÆaÅ of
r1: addchr('1');
r2: addchr('2');
r3: addchr('3');
r4: addchr('4');
r5: addchr('5');
r6: addchr('6');
r7: addchr('7');
r8: addchr('8');
end
else
case xtsrÆaÅ of
r1: addchr('8');
r2: addchr('7');
r3: addchr('6');
r4: addchr('5');
r5: addchr('4');
r6: addchr('3');
r7: addchr('2');
r8: addchr('1');
end;
end;
end;
procedure addwrd(a:ra; b: ta); (* add word to message *)
var inta : ta;
begin
for inta:=aa to b do addchr(aÆintaÅ);
end;
function differ(a,b: rm): tb; (* compare moves, true if different *)
var intb : tb;
begin
intb:=(a.rmfr <> b.rmfr) or (a.rmto <> b.rmto) or (a.rmcp <> b.rmcp);
if a.rmpr = b.rmpr then
if a.rmpr then differ:=intb or (a.rmpp <> b.rmpp)
else
if a.rmoo = b.rmoo then
if a.rmoo then differ:=intb or (a.rmqs <> b.rmqs)
else differ:=intb
else differ:=true
else differ:=true;
end;
procedure setsqd(a:ts; b:rd; var c:sr; var d:sf); (* define specific *)
begin (* square descriptor *)
c:=Ær1..r8Å;
d:=Æf1..f8Å;
with b do
begin
if rdkq and rdnb then d:=ÆxtsfÆaÅÅ;
if (not rdkq) and rdnb then
case xtsfÆaÅ of
f1,f8: d:=Æf1,f8Å;
f2,f7: d:=Æf2,f7Å;
f3,f6: d:=Æf3,f6Å;
f4 : d:=Æf4Å;
f5 : d:=Æf5Å;
end;
if rdrk then c:=ÆxtsrÆaÅÅ;
end;
end;
procedure mingen(a:rm; b,c:ti); (* produce minimum engl. notation *)
var
intg : tg;
inti : ti;
intw : tw;
inlr : sr;
inrr : sr;
inlf : sf;
inrf : sf;
exit : tb;
found: tb;
begin
exit:=false;
inti:=b;
repeat
with syntxÆintiÅ do
begin
if a.rmpr then intg:=a.rmpp else intg:=pb;
setsqd(a.rmfr,ryls,inlr,inlf);
setsqd(a.rmto,ryrs,inrr,inrf);
found:=true;
intw:=aw+1;
repeat
if differ(movesÆintwÅ,a) then
if (nbordÆa.rmfrÅ = nbordÆmovesÆintwÅ.rmfrÅ) and
(a.rmcp = movesÆintwÅ.rmcp) then
with movesÆintwÅ do
if (xtsrÆrmfrÅ in inlr) and (xtsrÆrmtoÅ in inrr) and
(xtsfÆrmfrÅ in inlf) and (xtsfÆrmtoÅ in inrf) and
((rmpr and (intg = rmpp)) or (not rmpr)) then found:=false;
intw:=intw+1;
until (intw = jntw-1) or not found;
if found then
begin (* no other move looks the same *)
addsqr(a.rmfr,ryls);
addchr(rych);
addsqr(a.rmto,ryrs);
exit:=true;
end;
end;
inti:=inti+1;
until (inti = c) or exit;
end;
begin
movms:=' ';
intn:=aw+1;
addwrd(b,za);
addwrd('- ',2);
with a do
begin
addchr(chr(rmfr mod 8 + ord('A')));
addchr(chr(rmfr div 8 + ord('1')));
if rmca then addchr('*') else addchr('-');
addchr(chr(rmto mod 8 + ord('A')));
addchr(chr(rmto div 8 + ord('1')));
addwrd(' = ',3);
if rmoo then
begin
addwrd('0-0 ',3);
if rmqs then addwrd('-0 ',2);
end else
if rmca then mingen(a,syncf,syncl) else mingen(a,synmf,synml);
if rmpr then
begin
addchr('=');
addchr(xtgcÆrmppÅ);
end;
addwrd('. ',3);
if rmch then
begin
addwrd('CHECK ',5);
if rmmt then addwrd('MATE ',4);
addchr('.');
end else
if rmmt then addwrd('STALEMATE.',10);
end;
end; (* mineng *)
function yrm(var inrm: rm):tb;
label 9,10,11,12,13,14,15,16,18;
var
intb : tb;
intc : tc;
intw : tw;
intp : tp;
incp : tp;
ifca : tb;
ifpr : tb;
ifoo : tb;
ifqs : tb;
intg : tg;
ifmv : tb;
ifld : tb;
iflf : tb;
ifrd : tb;
ifrf : tb;
intf : tf;
intr : tr;
inlf : sf;
inlr : sr;
inrf : sf;
inrr : sr;
exit : tb;
error : tb;
function nchin(a: sc; b: ti):tb; (* determine if next input *)
var intb : tb; (* char is not in a given set *)
begin
intb:=not(intc in a);
if not intb then
begin
case b of
1: ifca:=true; (* yrmcap semantics - capture *)
2: ifoo:=true; (* yrmcas semantics - castle *)
3: case intc of (* yrmcpc semantics - captured piece *)
'P': incp:=xtumpÆep,otherÆjntmÅÅ;
'R': incp:=xtumpÆer,otherÆjntmÅÅ;
'N': incp:=xtumpÆen,otherÆjntmÅÅ;
'B': incp:=xtumpÆeb,otherÆjntmÅÅ;
'Q': incp:=xtumpÆeq,otherÆjntmÅÅ;
end;
4: ifqs:=true; (* yrmcqs semantics - castle long *)
5: begin (* yrmlkq semantics - K or Q on left *)
case intc of
'K': inlf:=Æf5..f8Å*inlf;
'Q': inlf:=Æf1..f4Å*inlf;
end;
iflf:=true;
end;
6: begin (* yrmlrb semantics - R, N or B on left *)
case intc of
'R': inlf:=Æf1,f8Å*inlf;
'N': inlf:=Æf2,f7Å*inlf;
'B': inlf:=Æf3,f6Å*inlf;
end;
ifld:=true;
end;
7: if jntm = lite then (* yrmlrk semantics rank on left *)
case intc of
'1': inlr:=Ær1Å;
'2': inlr:=Ær2Å;
'3': inlr:=Ær3Å;
'4': inlr:=Ær4Å;
'5': inlr:=Ær5Å;
'6': inlr:=Ær6Å;
'7': inlr:=Ær7Å;
'8': inlr:=Ær8Å;
end
else
case intc of
'1': inlr:=Ær8Å;
'2': inlr:=Ær7Å;
'3': inlr:=Ær6Å;
'4': inlr:=Ær5Å;
'5': inlr:=Ær4Å;
'6': inlr:=Ær3Å;
'7': inlr:=Ær2Å;
'8': inlr:=Ær1Å;
end;
8: ; (* yrmnul semantics - null *)
9: case intc of (* yrmpcm semantics - piece moved *)
'P': intp:=xtumpÆep,jntmÅ;
'R': intp:=xtumpÆer,jntmÅ;
'N': intp:=xtumpÆen,jntmÅ;
'B': intp:=xtumpÆeb,jntmÅ;
'Q': intp:=xtumpÆeq,jntmÅ;
'K': intp:=xtumpÆek,jntmÅ;
end;
10: begin (* yrmpro semantics - promotion *)
case intc of
'R': intg:=pr;
'N': intg:=pn;
'B': intg:=pb;
'Q': intg:=pq;
end;
ifpr:=true;
end;
11: begin (* yrmrkq semantics - K or Q on rigth *)
case intc of
'K': inrf:=Æf5..f8Å*inrf;
'Q': inrf:=Æf1..f4Å*inrf;
end;
ifrf:=true;
end;
12: begin (* yrmrrb semantics - R, N or B on rigth *)
case intc of
'R': inrf:=Æf1,f8Å*inrf;
'N': inrf:=Æf2,f7Å*inrf;
'B': inrf:=Æf3,f6Å*inrf;
end;
ifrd:=true;
end;
13: if jntm = lite then (* yrmrrk semantics rank on rigth *)
case intc of
'1': inrr:=Ær1Å;
'2': inrr:=Ær2Å;
'3': inrr:=Ær3Å;
'4': inrr:=Ær4Å;
'5': inrr:=Ær5Å;
'6': inrr:=Ær6Å;
'7': inrr:=Ær7Å;
'8': inrr:=Ær8Å;
end
else
case intc of
'1': inrr:=Ær8Å;
'2': inrr:=Ær7Å;
'3': inrr:=Ær6Å;
'4': inrr:=Ær5Å;
'5': inrr:=Ær4Å;
'6': inrr:=Ær3Å;
'7': inrr:=Ær2Å;
'8': inrr:=Ær1Å;
end;
14: case intc of
'A': intf:=f1;
'B': intf:=f2;
'C': intf:=f3;
'D': intf:=f4;
'E': intf:=f5;
'F': intf:=f6;
'G': intf:=f7;
'H': intf:=f8;
end;
15: begin
case intc of
'1': intr:=r1;
'2': intr:=r2;
'3': intr:=r3;
'4': intr:=r4;
'5': intr:=r5;
'6': intr:=r6;
'7': intr:=r7;
'8': intr:=r8;
end;
intp:=board.rbisÆxtrfsÆintr,intfÅÅ;
inlf:=ÆintfÅ; inlr:=ÆintrÅ;
end;
16: case intc of
'A': intf:=f1;
'B': intf:=f2;
'C': intf:=f3;
'D': intf:=f4;
'E': intf:=f5;
'F': intf:=f6;
'G': intf:=f7;
'H': intf:=f8;
end;
17: begin
case intc of
'1': intr:=r1;
'2': intr:=r2;
'3': intr:=r3;
'4': intr:=r4;
'5': intr:=r5;
'6': intr:=r6;
'7': intr:=r7;
'8': intr:=r8;
end;
incp:=board.rbisÆxtrfsÆintr,intfÅÅ;
inrf:=ÆintfÅ; inrr:=ÆintrÅ;
end;
18: ifca:=true;
end;
jntj:=jntj+1;
while (jntj < zj) and (ilineÆjntjÅ = ' ') do jntj:=jntj+1;
intc:=ilineÆjntjÅ;
if (intc = '.') or (intc = ';') then exit:=true;
end;
nchin:=intb;
end;
procedure yrmhit; (* found a move *)
begin
if ifmv then (* second possible move found *)
begin
error:=true;
writeln(' AMBIGUOUS MOVE.');
end else
begin
ifmv:=true;
inrm:=movesÆintwÅ;
end;
end;
procedure yrmcom; (* compare squares *)
begin
with movesÆintwÅ do
if (xtsrÆrmfrÅ in inlr) and
(xtsfÆrmfrÅ in inlf) and
(xtsrÆrmtoÅ in inrr) and
(xtsfÆrmtoÅ in inrf) and
(not rmil) and (board.rbisÆrmfrÅ = intp) then
if rmca = ifca then
if rmca then
if rmcp = incp then
yrmhit
else
else yrmhit;
end;
begin
intb:=false;
ifca:=false;
ifpr:=false;
ifoo:=false;
ifqs:=false;
ifld:=false;
iflf:=false;
ifrd:=false;
ifrf:=false;
intp:=mt;
incp:=mt;
inlf:=Æf1..f8Å;
inrf:=Æf1..f8Å;
inlr:=Ær1..r8Å;
inrr:=Ær1..r8Å;
exit:=false;
error:=false;
intc:=ilineÆjntjÅ;
if ilineÆjntj+1Å in Æ'1'..'8'Å then
begin
if nchin(Æ'A'..'H'Å ,14) then goto 10;
if nchin(Æ'1'..'8'Å ,15) then goto 16;
if not nchin(Æ'-'Å , 8) then goto 9;
if nchin(Æ'*','X'Å ,18) then goto 16;
9: (* standard syntax from ok *)
if nchin(Æ'A'..'H'Å ,16) then goto 16;
if not nchin(Æ'1'..'8'Å ,17) then goto 15;
end;
10: (* not standard *)
if nchin(Æ'P','R','N','B','Q','K'Å, 9) then goto 14;
if nchin(Æ'/'Å , 8) then goto 11;
if nchin(Æ'K','Q'Å , 5) then ;
if nchin(Æ'R','N','B'Å , 6) then ;
if nchin(Æ'1'..'8'Å , 7) then ;
if exit then goto 15;
11: (* left side done *)
if not nchin(Æ'-'Å , 8) then goto 12;
if nchin(Æ'*','X'Å , 1) then goto 16;
if nchin(Æ'P','R','N','B','Q'Å , 3) then goto 16;
if nchin(Æ'/'Å , 8) then goto 13;
12: (* right side square *)
if nchin(Æ'K','Q'Å ,11) then ;
if nchin(Æ'R','N','B'Å ,12) then ;
if nchin(Æ'1'..'8'Å ,13) then ;
if exit then goto 15;
13: (* promotion *)
if nchin(Æ'='Å , 8) then goto 15;
if nchin(Æ'R','N','B','Q'Å ,10) then goto 16;
if exit then goto 15;
14: (* castling *)
if nchin(Æ'0','O'Å , 8) then goto 16;
if nchin(Æ'-'Å , 8) then goto 16;
if nchin(Æ'0','O'Å , 2) then goto 16;
if nchin(Æ'-'Å , 4) then goto 15;
if nchin(Æ'0','O'Å , 8) then goto 16;
15: (* syntax correct *)
exit:=false;
if ifrf and not ifrd then inrf:=inrf * Æf4,f5Å;
if iflf and not ifld then inlf:=inlf * Æf4,f5Å;
ifmv:=false;
intw:=aw;
while (intw < jntw) and not error do
with movesÆintwÅ do
begin
if rmpr = ifpr then
if rmpr then
if rmpp = intg then
yrmcom
else
else
if rmoo = ifoo then
if rmoo then
if rmqs = ifqs then
yrmhit
else
else
yrmcom;
intw:=intw+1;
end;
if not error then
if ifmv then
begin
intb:=true;
jfmv:=true
end else writeln(' ILLEGAL MOVE.');
goto 18;
16: (* syntax error *)
writeln(' SYNTAX ERROR.');
18: (* exit *)
yrm:=intb;
end;
procedure yrmove;
label 99;
var inrm : rm;
begin
jfmv:=false;
lstmov;
repeat
reader;
if com > 0 then goto 99;
until yrm(inrm);
if jfmv then
begin
mineng(inrm,'YOUR MOVE ');
write(movms);
if swec then write(movms);
themov(inrm);
end;
99:
end;
procedure mymove; (* make machines move *)
var
inti : ti;
inrm : rm;
begin
create; (* initalize data base *)
inrm:=movesÆsearchÅ; (* find the best move *)
if inrm.rmil then
begin (* no move found *)
going:=0;
if lstmv.rmch then writeln(' CONGRATULATIONS.') (* checkmate *)
else writeln(' DRAWN.'); (* stalemate *)
end else
begin
mineng(inrm,' MY MOVE '); (* translate move to english *)
write(movms); (* tell the player *)
for inti:=1 to 7 do write(chr(7));
if swec then write(movms);
themov(inrm); (* make the move *)
if swsu then
begin
if swec then
write(' ',board.rbti:0,'. ',bstvlÆakÅ:4,' ',nodes:0,' nodes. ');
write(' ',board.rbti:0,'. ',bstvlÆakÅ:4,' ',nodes:0,' nodes. ');
end;
writeln;
if swec then writeln;
end;
if swpr then printb(board.rbis);
end;
begin
writeln(' HI. THIS IS CHESS 0.5');
inicon;
1:
inital(board); (* initialize for a new game *)
repeat
repeat
yrmove;
case com of
1: goto 1;
2: goto 2;
9: goto 9;
0: ;
end;
until swre;
2:
repeat (* execute machines move *)
mymove;
if going > 0 then going:=going-1;
until going = 0;
until false;
9:
end.
«eof»