Encoding chess rules into chess pieces

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
maksimKorzh
Posts: 771
Joined: Sat Sep 08, 2018 5:37 pm
Location: Ukraine
Full name: Maksim Korzh

Encoding chess rules into chess pieces

Post by maksimKorzh »

Hi guys, so here's what I did:

I've encoded ascii character representation, color, piece weight, (one helper flag) and most notably - move offsets into a single integer for every piece:

Code: Select all

###########################################################
#
#                      PIECE BIT MAP
#
###########################################################
#
#   0000 0000 0000 0000 0000 0000 0000 0111 1111 ASCII
#   0000 0000 0000 0000 0000 0000 0000 1000 0000 Color
#   0000 0000 0000 0000 0000 0000 1111 0000 0000 Weight
#   0000 0000 0000 0000 0000 0001 0000 0000 0000 Size
#   0000 0000 0000 0000 0011 1110 0000 0000 0000 offset 1
#   0000 0000 0000 0111 1100 0000 0000 0000 0000 offset 2
#   0000 0000 1111 1000 0000 0000 0000 0000 0000 offset 3
#   0001 1111 0000 0000 0000 0000 0000 0000 0000 offset 4
#
###########################################################
Eventually I came up with these values:

Code: Select all

###########################################################
#
#                      PIECE ENCODING
#
###########################################################
#
#   Piece code    ASCII  Color  Weigt  Size   Offests   
#
#   2854580560    P      0      1      1      11 9 20 10 
#   5279650638    N      0      3      1      8 12 21 19 
#   2958146       B      0      3      0      9 11 
#   345426        R      0      5      0      10 1 
#   355285329     Q      0      9      1      9 11 10 1 
#   355283019     K      0      0      1      9 11 10 1 
#   2854580720    p      1      1      1      11 9 20 10 
#   5279650798    n      1      3      1      8 12 21 19 
#   2958306       b      1      3      0      9 11 
#   345586        r      1      5      0      10 1 
#   355285489     q      1      9      1      9 11 10 1 
#   355283179     k      1      0      1      9 11 10 1
#
###########################################################
Obviously I didn't do it by hands so here's a python script to achieve this:
https://github.com/maksimKorzh/toyfish/ ... _pieces.py

initially I had 2 files (it was made for a youtube tutorial):
source code: https://github.com/maksimKorzh/toyfish/ ... toyfish.py
data file: https://github.com/maksimKorzh/toyfish/ ... tings.json

finally here's the minified version of the eventual engine:

Code: Select all

m={'P':'♙','N':'♘','B':'♗','R':'♖','Q':'♕','K':'♔','p':'♟','n':'♞','b':'♝','r':'♜','q':'♛','k':'♚','.':'·',' ':' '}
P,N,B,R,Q,K=2854580560,5279650638,2958146,345426,355285329,355283019;C=127
p,n,b,r,q,k=2854580720,5279650798,2958306,345586,355285489,355283179;S=120
w=lambda s:[32]+s+[32];z=lambda p:[p]*8;e=[32]+[46]*8+[32];o=[32]*10;f=range;
b=o*2+w([r,n,b,q,k,b,n,r])+w(z(p)+w(e*4)+z(P))+w([R,N,B,Q,K,B,N,R])+o*2+[0,0,0]
O=lambda: print(''.join([' '+m[chr(b[i]&C)] if i%10 else '\n' for i in f(S)]));O()
def X(x):
 if x==0:
  v=0
  for s in f(120):
   t=b[s]
   if chr(t&C) not in ' .':
    v+=((t>>8)&15)*100 * (1 if chr(t&C).isupper() else -1)
    if chr(t&C).isupper():v+=j[s]
    if chr(t&C).islower():v-=j[s]
  return -v if b[-1] else v
 u,g,l=-1,-1,-10000
 for s in f(S):
  t=b[s]
  if chr(t&C) not in ' .' and (t>>7)&1==b[-1]:
   d=[(t>>13),[]]
   for a in f(4 if (t>>12)&1 else 2):d[1].append(d[0]&31);d[0]>>=5
   n=[-d for d in d[1]]
   if t==P:d[1]=n
   elif t!=p:d[1]+=n 
   for a in d[1]:
     h=s
     while 1:
      h+=a;c=b[h]
      if c==32:break
      if c!=46 and (c>>7)&1==b[-1]:break
      if chr(t&C) in 'Pp' and a in [9,11,-9,-11] and c == 46:break
      if chr(t&C) in 'Pp' and a in [10,20,-10,-20] and c != 46:break
      if t==P and a==-20 and s not in f(81,89):break
      if t==P and a==-20 and b[s-10] != 46:break
      if t==p and a==20 and s not in f(31,39):break
      if t==p and a==20 and b[s+10] != 46:break
      if chr(c&C) in 'Kk': return 10000
      b[s]=46;b[h]=t;b[-1]^=1
      if t==P and s in f(31,39):b[h]=Q
      if t==p and s in f(81,89):b[h]=q
      v=-X(x-1);b[s]=t;b[h]=c;b[-1]^=1;b[-2]=s;b[-3]=h
      if v>l:l=v;u=s;g=h;
      if c!=46 and (c>>7)&1==b[-1]^1:break
      if chr(t&C) in 'PpNnKk': break
 b[-2]=u;b[-3]=g
 return l
j=[(3-abs(int(int(str(s)[0])-5.5)))**2+((3-abs(int(int(str(s)[1])-4.5))))**2 if b[s]!=32 else 0 for s in f(120)]
while 1:
 y=input(' Your move: ')
 u=(10-(ord(y[1])-ord('0')))*10+ord(y[0])-ord('a')+1
 g=(10-(ord(y[3])-ord('0')))*10+ord(y[2])-ord('a')+1
 b[g]=b[u];b[u]=46;
 if b[g]==P and u in f(31,39):b[g]=Q
 O();b[-1]^=1;s=X(3);b[b[-3]]=b[b[-2]];b[b[-2]]=46;
 if b[b[-3]]==p and b[-2] in f(81,89):b[b[-3]]=q
 O();b[-1]^=1
 if abs(s) == 10000: print(' Checkmate!'); break
Demo of how it works and source code explanations:
User avatar
hgm
Posts: 27787
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Encoding chess rules into chess pieces

Post by hgm »

This appears to assume pieces are point symmetric, except that Pawns obviously aren't, and still use the system.

Note that the 'color' bit is redundant; you could use bit 5 of the ascii code (which distinguishes upper and lower case) for that.
User avatar
maksimKorzh
Posts: 771
Joined: Sat Sep 08, 2018 5:37 pm
Location: Ukraine
Full name: Maksim Korzh

Re: Encoding chess rules into chess pieces

Post by maksimKorzh »

hgm wrote: Fri Jul 23, 2021 5:31 pm This appears to assume pieces are point symmetric, except that Pawns obviously aren't, and still use the system.

Note that the 'color' bit is redundant; you could use bit 5 of the ascii code (which distinguishes upper and lower case) for that.
I didn't know about 5th bit of ascii code)
Offsets are initialized dynamically to add the negative directions to all pieces but pawns
and for pawns - black are left untouched while white pawns' offsets are negated.

I know this is a weird idea but I just wanted to write something similar to micro-Max with my own design)
I know it has more characters involved than micro-Max and it plays incomparably much worse but one
thing I can say about this code - I wrote it completely on my own!

P.S. I just started working on coding chess for zx spectrum to run it on emulator.
Using BASIC comiler (it exists!) is easier but I couldn't find how to type in bitshift operators
within the zx spectrum emulator... So I would probably just go for an extra mile to init offsets to array instead.
Not sure whether I fit into memory size or not. Btw will there be a difference in with following scenarios:
1. Imagine chess written in sinclair BASIC and compiled to binary (assume it's running on emulator)
2. Imagine I type this same program line by line into the emulator
May it happen that in second case I run out of memory?
User avatar
mclane
Posts: 18748
Joined: Thu Mar 09, 2006 6:40 pm
Location: US of Europe, germany
Full name: Thorsten Czub

Re: Encoding chess rules into chess pieces

Post by mclane »

It would be an interesting idea to get a new chess engine for the sinclair zx spectrum.
Running it in Fuse or on sinclair spectrum next or n-go machines would be very interesting.
What seems like a fairy tale today may be reality tomorrow.
Here we have a fairy tale of the day after tomorrow....