chess.com api and the continuing search for en passant checkmate

chess.com api and the continuing search for en passant checkmate

Last time we worked out how to get info for all the games played by titled players in a particular month. Today, we have three objectives:

First of all, I wrote a little function to get the pgn from the games we downloaded. I added this KeyError exception, but if I’m honest I’m not sure why I was getting this error. Maybe, chess.com doesn’t store pgn for all games? I don’t know.

def get_pgns(games):
    pgns = []
    for game in games:
        try:
            pgn = game['pgn']
            pgns.append(pgn)
        except KeyError:
            print('key error um')
    return pgns

Now we have this list of pgns, the next goal is to write them to a file so we theoretically only have to run the stuff from last post once. All the analysis we do on the games can then just be done on the files we save without any talking to the internet required.

def write_pgns(pgns):
    with open(month.replace('/','_')+'.csv', 'w') as f:
        for pgn in pgns:
	    f.write(pgn)

Now a pgn looks something like this if it’s just printed as a string:

image alt text

It contains lots of very useful info but for our purposes of finding en passant checkmates, we would ideally just have a list of each move looking something like this:

moves = [ 'e4', 'e5', 'Bc4', 'Nc6', 'Qh5', 'Nf6', 'Qxf7#']

We don’t need the headers, we don’t need the result, and we don’t really need the move numbers (these can be deduced from the list indexes). So the challenge is how to convert the pgn to a list; this is the slightly janky solution I came up wtih.

def get_move_list(pgn):
    x = pgn.split()
    moves = []
    for item in x:
        # start fresh list at move 1 - effectively skipping the headers from the list
        if item == '1.':
            moves = []
            moves.append(item)
        # gets rid of clock bits and bobs
        elif item[0] == '{' or item[-1] == '}':
            pass
        else:
            moves.append(item)
    #remove even indexes from list
    #this gets rid of move numbers and the result of the game
    del moves[::2]
    return moves

I don’t doubt it could be done more elegantly but it works I guess. Next time, we’ll deal with working out what a list containing an en passant checkmate would look like.