DataMuseum.dk

Presents historical artifacts from the history of:

CP/M

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about CP/M

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦2a51cc3e1⟧ TextFile

    Length: 85376 (0x14d80)
    Types: TextFile
    Names: »CHESS80.PAS«

Derivation

└─⟦121d96d60⟧ Bits:30005835 RC Chess 750 source code
    └─ ⟦this⟧ »CHESS80.PAS« 

TextFile

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»