Fun challenge for best cool code

Discussion of chess software programming and technical issues.

Moderators: Harvey Williamson, bob, hgm

Forum rules
This textbox is used to restore diagrams posted with the [d] tag before the upgrade.
Post Reply
User avatar
Rebel
Posts: 5694
Joined: Thu Aug 18, 2011 10:04 am

Fun challenge for best cool code

Post by Rebel » Thu Feb 28, 2019 7:10 am

Recently I analyzed 14 million EPD positions with Stockfish at 1000ms which took me 4½ days to complete. Then I noticed I had forgotten the "50-move counter" and "move-number" tags, usualy "0" and "1".

Code: Select all

rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - id sf10; bm e2e4; ce 55; acd 18;
While it should have been:

Code: Select all

rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 id sf10; bm e2e4; ce 55; acd 18;
I did not like to run it for 4½ days again so I decided to write a little tool to insert the "0 1".

Code: Select all

char s [1000] = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - id sf10; bm e2e4; ce 55; acd 18;\n";
char h [1000];
char *q;
int x;

q=strstr(s,"id "); 
if (q==NULL) { something is wrong }
q[-1]=0;                                       // cuts string till "id"
x=0;
while (q[x] != 10) { h[x]=q[x]; x++; h[x]=0; } // copy rest of string to h
strcat(s," 0 1 ");                             // add the missing  "50-move counter" and "move-number" tags.
strcat(s,h);                                   // combine the 2 strings, mission accomplished
I am sure there are more elegant solutions.
90% of coding is debugging, the other 10% is writing bugs.

LocutusOfPenguin
Posts: 32
Joined: Thu Sep 28, 2017 4:52 pm
Location: Karlsruhe, Germany
Full name: Jürgen Précour
Contact:

Re: Fun challenge for best cool code

Post by LocutusOfPenguin » Thu Feb 28, 2019 7:30 am

On Linux systems y can use (for example) this:

sed 's/- id/- 0 1 id/' filename.epd >newfile.epd

Exchanges the "- id" with "- 0 1 id" (so leave correct lines intact)

Jürgen
Create a dedicated chess computer based on tiny ARM computers with the DGT e-board on picochess.com

Ferdy
Posts: 4296
Joined: Sun Aug 10, 2008 1:15 pm
Location: Philippines

Re: Fun challenge for best cool code

Post by Ferdy » Thu Feb 28, 2019 10:49 am

Rebel wrote:
Thu Feb 28, 2019 7:10 am

Code: Select all

rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - id sf10; bm e2e4; ce 55; acd 18;
To make that a compliant epd it should be

Code: Select all

rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - id "sf10"; bm e4; ce 55; acd 18;
Added double quotes to id name and convert bm LAN to bm SAN.

If you want to add hmvc and fmvn

Code: Select all

rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - id "sf10"; bm e4; ce 55; acd 18; hmvc 0; fmvn 1;

If you want to make all your epd's compliant here is the script to change its format.

Code: Select all

# -*- coding: utf-8 -*-
"""
modify_epd_1.py

Read epd file and fix epd lines to make it epd compliant.

* Add double quotes to id name
* Convert bm LAN to bm SAN
* Add hmvc and fmvn
* Write to a new epd file

Requirements:
    python 3
    python-chess v0.26.0

"""


import chess
        

def main():
    inepdfn = 'big.epd'
    outepdfn = 'out_' + inepdfn
            
    with open(outepdfn, 'w') as w:
        with open(inepdfn, 'r') as f:
            for line in f:
                epd = line.rstrip()
                
                # Modify bm LAN to bm SAN in orig epd                
                epd1 = ' '.join(epd.split()[0:4])
                bm_lan = epd.split('bm')[1].strip().split(';')[0]
                pos = chess.Board()
                pos.set_epd(epd1)
                bm_san = pos.san(chess.Move.from_uci(bm_lan))                
                a = 'bm ' + bm_lan
                b = 'bm ' + bm_san
                updated_epd = epd.replace(a, b)
                
                # Add double quotes to id name
                id_name = updated_epd.split('id')[1].strip().split(';')[0]
                updated_id_name = '\"' + id_name + '\"'
                a = 'id ' + id_name
                b = 'id ' + updated_id_name
                updated_epd = updated_epd.replace(a, b)                
                
                
                # Convert bm LAN to bm SAN and add hmvc and fmvn                
                pos, epd_info = chess.Board().from_epd(updated_epd)
                new_epd = pos.epd(id=epd_info['id'], 
                                  bm=epd_info['bm'],                                  
                                  ce=epd_info['ce'],
                                  acd=epd_info['acd'],
                                  hmvc=pos.halfmove_clock,
                                  fmvn=pos.fullmove_number)
                
                # print(new_epd)
                w.write('%s\n' % (new_epd))


if __name__ == "__main__":
    main()

If you really just want to insert the hmvc and fmvn

Code: Select all

# -*- coding: utf-8 -*-
"""
modify_epd_0.py

Insert 0 1 after epd's e.p field

Requirements:
    python 3

"""
        

def main():
    inepdfn = 'big.epd'  # Your input epd file
    outepdfn = 'out_' + inepdfn
            
    with open(outepdfn, 'w') as w:
        with open(inepdfn, 'r') as f:
            for epd in f:
                # Get the first 4 fields and add '0 1'
                first4field = ' '.join(epd.split()[0:4])
                others = ' '.join(epd.split()[4:])
                new_epd = first4field + ' 0 1 ' + others
                
                # print(new_epd)
                w.write('%s\n' % (new_epd))


if __name__ == "__main__":
    main()

User avatar
hgm
Posts: 25076
Joined: Fri Mar 10, 2006 9:06 am
Location: Amsterdam
Full name: H G Muller
Contact:

Re: Fun challenge for best cool code

Post by hgm » Thu Feb 28, 2019 12:31 pm

EPDs have no 50-move or move-number fields. Only FENs have that...
Get rid of the shit: vote for SHID!

Dann Corbit
Posts: 11627
Joined: Wed Mar 08, 2006 7:57 pm
Location: Redmond, WA USA
Contact:

Re: Fun challenge for best cool code

Post by Dann Corbit » Thu Feb 28, 2019 7:23 pm

hgm wrote:
Thu Feb 28, 2019 12:31 pm
EPDs have no 50-move or move-number fields. Only FENs have that...
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - fmvn 1; hmvc 0;
They have them, but they are decorated with a label.
Taking ideas is not a vice, it is a virtue. We have another word for this. It is called learning.
But sharing ideas is an even greater virtue. We have another word for this. It is called teaching.

User avatar
hgm
Posts: 25076
Joined: Fri Mar 10, 2006 9:06 am
Location: Amsterdam
Full name: H G Muller
Contact:

Re: Fun challenge for best cool code

Post by hgm » Fri Mar 01, 2019 5:44 am

Sure. But they are optional, and 0, 1 are their default values.
Get rid of the shit: vote for SHID!

chrisw
Posts: 3841
Joined: Tue Apr 03, 2012 2:28 pm

Re: Fun challenge for best cool code

Post by chrisw » Fri Mar 01, 2019 9:58 am

Dann Corbit wrote:
Thu Feb 28, 2019 7:23 pm
hgm wrote:
Thu Feb 28, 2019 12:31 pm
EPDs have no 50-move or move-number fields. Only FENs have that...
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - fmvn 1; hmvc 0;
They have them, but they are decorated with a label.
I put that in as an issue to Python Chess about a week or so ago.

One more item: many online FEN strings come without the two final fields (moves since, movenum). the FEN reader complains. Might be useful if it added 0, 1, with some documentation explanation.

Response back: I need this quite frequently myself, but never got around to do it. Now implemented in 65e8729. Defaults to 0 1.

So, I think Python Chess now accepts both:
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq x, y

and appends an 0, 1 if x, y missing. It used to just issue an error, "fen strings have six fields"
I'm not sure what happens if fmvn is specifically used as an identifier.

User avatar
hgm
Posts: 25076
Joined: Fri Mar 10, 2006 9:06 am
Location: Amsterdam
Full name: H G Muller
Contact:

Re: Fun challenge for best cool code

Post by hgm » Fri Mar 01, 2019 11:38 am

I hate pedantic interfaces. WinBoard just uses a default value 0 for the ply counter if it is missing, and ignores the move number anyway, when it parses a FEN.

I guess stupid old NotePad would not even have a problem doing this; just do a 'Replace All' on " id " for " 0 1 id " if you insist on beraking the EPDs that way.
Get rid of the shit: vote for SHID!

niklasf
Posts: 42
Joined: Sat May 16, 2015 9:41 pm

Re: Fun challenge for best cool code

Post by niklasf » Fri Mar 01, 2019 1:53 pm

chrisw wrote:
Fri Mar 01, 2019 9:58 am
So, I think Python Chess now accepts both:
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq x, y
Yeah, on the master branch it now even defaults to

Code: Select all

w - - 0 1
respectively. Not sure if that's a bit too relaxed ... in any case a user could parse, regenerate, compare to do strict validation.
chrisw wrote:
Fri Mar 01, 2019 9:58 am
I'm not sure what happens if fmvn is specifically used as an identifier.
This always worked as expected:

Code: Select all

>>> import chess
>>> board, ops = chess.Board.from_epd("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - fmvn 2; hmvc 3;")
>>> board
Board('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 3 2')
>>> ops
{'fmvn': 2, 'hmvc': 3}
However it will still reject

Code: Select all

id unquoted_string
because it attempts to parse this as a number or move.

Post Reply