Tuesday, April 5, 2016

Just for fun - the 6kb chess engine - NanoChess68 ...

Just for fun - Cut and paste the following Algol code at: Execute Algol online...
#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #
 
COMMENT
# Toledo Nanochess (c)2009 Oscar Toledo G. #
# http://www.nanochess.org/ #
 
# Algol-68 translation (c)2010 Neville C. Dempsey #
# http://sourceforge.net/projects/algol68 #
 
# v0.4   - Tue Jul 9 21:23:49 EST 2013 #
# v0.4.1 - Tue Apr 5 20:54:20 NZST 2016 - fix []INT overflow #
END COMMENT
 
INT bb,i,y,u,b:=666;# b is used before it is defined! #
[0:666]INT ii;
FOR i FROM LWB ii TO UPB ii DO ii[i]:=0 OD;
INT gg:=120,x:=10,z:=15,mm:=10000;
 
[]INT l=[]INT(5,3,4,6,2,4,3,5,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,13,11,
12,14,10,12,11,13,0,99,0,306,297,495,846,-1,0,1,2,2,1,0,-1,-1,1,-10,
10,-11,-9,9,11,10,20,-9,-11,-10,-20,-21,-19,-12,-8,8,12,19,21)[@0];
 
PRIO <<=5;# Should be 5.5 to match C #
OP <<=(INT i,s)INT: ABS (SBIN i SHL s );
 
OP SBA=(INT i)BOOL: i NE 0;# Cast a INT into an BOOL #
 
OP SBIN = (INT i)BITS: (i>=0 | BIN i | NOT BIN ABS (i+1) ); # 2s compliment #
PRIO XOR=2;# 2.5 to match C #
OP XOR=(INT a,b)INT: ABS ((SBIN a OR SBIN b)&NOT (SBIN a&SBIN b) );
PRIO XORAB=1;
OP XORAB=(REF INT lhs,INT i)VOID: lhs:=lhs XOR i;
 
OP INC=(REF INT lhs)VOID: lhs+:=1;
OP DEC=(REF INT lhs)VOID: lhs-:=1;
OP POSTINC=(REF INT lhs)INT:(INT out=lhs;lhs+:=1;out);
OP POSTDEC=(REF INT lhs)INT:(INT out=lhs;lhs-:=1;out);
OP PREINC=(REF INT lhs)INT: lhs+:=1;
OP PREDEC=(REF INT lhs)INT: lhs-:=1;
 
PRIO BOR=2,BAND=3;# Caution: should be 3.2 and 3.3 #
OP BOR=(INT a,b)INT:ABS (SBIN a OR SBIN b);
OP BAND=(INT a,b)INT:ABS (SBIN a&SBIN b);
OP BOR=(INT a,BOOL b)INT: a BOR ABS b;
OP BOR=(BOOL a,INT b)INT: ABS a BOR b;
OP BAND=(INT a,BOOL b)INT: a BAND ABS b;
OP BAND=(BOOL a,INT b)INT: ABS a BAND b;
 
OP NOT=(INT i)INT: ABS(i=0);
 
PROC ww=VOID: BEGIN
  bb:=b;
# FOR # INT p:=21;WHILE p<99 DO
# Uncomment 'unicode' to show graphics in Linux, Jul/04/2011 O.T.G. #
    piece OF element[p]:=#unicode# pieces[ii[p] BAND z];
    moved OF element[p]:=p=bb;
    p+:=(SBA(p%*x-8)|1|3)
  OD
END;
 
PROC xx=(INT w,c,h,e,ss,s)INT: BEGIN
  INT out;
  INT t,o,ll,ee,d,oo:=e,
  INT nn:=-mm*mm,
  INT kk:=78-h<<x,p,g,n,m,aa,q,r,cc,jj,a:=(SBA y|-x|x);
 
  y XORAB 8;
  INC gg;
  d:=ABS(SBA w OREL ((SBA s ANDTH s>=h ) ANDTH xx(0,0,0,21,0,0)>mm ));
  WHILE (
    IF SBA(o:=ii[p:=oo])THEN
      q:=o BAND z XOR y;
      IF q<7 THEN
        aa:=(SBA(POSTDEC q BAND 2)|8|4);
        cc:=(SBA(o-9 BAND z)|(q+1|53,47,61,51,47,47)|57);
        WHILE (
          r:=ii[p+:=l[cc]];
          IF SBA(NOT w BOR p=w)THEN
            g:=(SBA(q BOR p+a-ss)|0|ss);
            IF ((SBA(NOT r BAND SBA(NOT NOT q BOR aa<3)) OREL SBA NOT NOT g) OREL ((r+1 BAND z XOR y)>9 ANDTH SBA(q BOR aa>2)))THEN
              IF SBA(m:=NOT (r-2 BAND 7))THEN y XORAB 8;ii[POSTDEC gg]:=oo;out:=kk;return FI;
              jj:=n:=o BAND z;
              ee:=ii[p-a] BAND z;
              t:=(SBA(q BOR ee-7)|n|n+:=2;6 XOR y);
              WHILE n<=t DO
                ll:=(SBA r|l[r BAND 7 BOR 32]-h-q|0);
                IF SBA s THEN ll+:=(SBA(1-q)|
                  l[(p-p%*x)%x+37]-l[(oo-oo%*x)%x+37]+ l[p%*x+38]*(SBA q|1|2)-l[oo%*x+38]+ (o BAND 16)%2|NOT NOT m*9)+ (SBA NOT q|
                NOT (ii[p-1] XOR n)+NOT (ii[p+1] XOR n)+ l[n BAND 7 BOR 32]-99+ NOT NOT g*99+ABS(aa<2)|0)+ NOT (ee XOR y XOR 9) FI;
                IF s>h OREL ((1<s #B#&s=h ) ANDTH SBA(ll>z BOR d)) THEN
                  ii[p]:=n;ii[oo]:=(SBA m|(ii[g]:=ii[m];ii[m]:=0)|(SBA g|ii[g]:=0|0));
                  ll-:=xx((SBA(s>h BOR d#?#)|0|p),ll-nn,h+1,ii[gg+1],jj:=(SBA(q BOR aa>1)|0|p),s);
                  IF SBA NOT ((((SBA h OREL SBA(s-1 BOR bb-oo) ) BOR i-n ) BOR p-b ) BOR ll<-mm) THEN ww;DEC gg;u:=jj;out:=u;return FI;
                  jj:=ABS(((SBA(q-1 BOR aa<7) OREL SBA m) OREL SBA(NOT s BOR d BOR r BOR o<z) ) OREL xx(0,0,0,21,0,0)>mm);
                  ii[oo]:=o;
                  ii[p]:=r;
                  (SBA m|(ii[m]:=ii[g];ii[g]:=0)|(SBA g|ii[g]:=9 XOR y|0) )
                FI;
                IF ll>nn OREL (((s>1 ANDTH ll=nn) ANDTH SBA NOT h) ANDTH next random<.4) THEN
                  ii[gg]:=oo;
                  IF s>1 THEN
                    IF SBA h ANDTH c-ll<0 THEN y XORAB 8;DEC gg;out:=ll;return FI;
                    IF SBA NOT h THEN i:=n;bb:=oo;b:=p FI
                  FI;
                  nn:=ll
                FI;
                n+:=ABS(SBA jj OREL SBA (g:=p;m:=(p<oo|g-3|g+2);((SBA(ii[m]<z BOR ii[ m+oo-p])) OREL SBA ii[p+:=p-oo])|1|0))
              OD
            FI
          FI;
        # WHILE # (SBA(NOT r BAND ABS(q>2)) OREL (p:=oo;SBA(q BOR aa>2 BOR o>z BAND NOT r) ANDTH SBA(PREINC cc * PREDEC aa)))
        ) DO ~ OD
      FI
    FI;
  # WHILE # SBA(PREINC oo>98|oo:=20|e-oo)
  ) DO ~ OD;
  y XORAB 8;DEC gg;out:=(SBA(nn+mm*mm) ANDTH SBA(ABS(nn>-kk+1924) BOR d)|nn|0);
  return: out
END;
bb:=i:=y:=u:=0;
WHILE POSTINC bb<120 DO
  ii[bb-1]:=(SBA(bb%*x)|
    (bb%x%*x<2 #B#OR bb%*x<2|7|
      (SBA(bb%x BAND 4)|0|l[POSTINC i] BOR 16) )
|7)
OD;
 
MODE ELEMENT=STRUCT (
  STRING piece,
  BOOL moved,
  INT index
);
 
[0:98#?#]ELEMENT element;
FOR i FROM LWB element TO UPB element DO # ~ Extra #
  element[i]:=("",FALSE,0)
OD;
 
PROC print page=VOID:(
  STRING a:=" ";
  FOR i TO 8 DO a+:=" "+REPR(ABS "a"+i-1) OD;
  a+:=REPR 10;
  FOR bb FROM 0 TO 8-1 DO
    a+:=whole(8-bb,-0);
    STRING sep:=" ";
    FOR i FROM 21 TO 29-1 DO
      INT id=bb*x+i;
      STRING sq:=piece OF element[id];
      ((ODD bb=ODD id)&sq=" "|sq:="+" );
      IF moved OF element[id] THEN
        a+:="["+sq+"]";sep:=""
      ELSE
        a+:=sep+sq;sep:=" "
      FI
    OD;
    a+:=sep+REPR 10
  OD;
  print(a); print(new line)
);
 
[]STRING pieces=[]STRING(" ","♟","♚","♞","♝","♜","♛",~,~,"♙","♔","♘","♗","♖","♕")[@0],
   ascii pieces=[]STRING(" ","p","k","n","b","r","q",~,~,"P","K","N","B","R","Q")[@0];

 
ww;
 
PROC yy=(INT s)VOID: BEGIN
  i:=(ii[s] XOR y) BAND z;
  IF i>8 THEN
    b:=s;
    ww
  ELIF SBA bb ANDTH i<9 THEN
    b:=s;
    i:=ii[bb] BAND z;
    IF (i BAND 7)=1 #B#& (b<29 #B#OR b>90) THEN i:=14-index OF element[0] XOR y FI;
    xx(0,0,0,21,u,1);
    IF SBA y THEN xx(0,0,0,21,u,3#ply#);xx(0,0,0,21,u,1) FI
  FI
END;
 
first random(ENTIER(seconds*1024));
 
WHILE
  [2]CHAR move;
  print page;
  print("Enter your move: ");
  read(move);print(new line);
# WHILE # NOT string in string(move,NIL,"win won lose loss draw stalemate quit exit") DO
  INT imove:=ABS move[1]-ABS "a"+(ABS "9" - ABS move[2])*10+11;
  IF LWB ii > imove ORF imove > UPB ii THEN
    print(("Enter moves as eg: g2<enter>g3<enter>..., or 'qu' to quit", new line))
  ELSE
    yy(imove)
  FI
OD

No comments:

Post a Comment