3

I would like to do a simple project by looking at the pieces at play when checkmate occurs.

I have been scouring the internet for a dataset of standard chess games from which I can retrieve the final board representation, where a checkmate has been played to it's conclusion.

At this point, any board representation would have to be fine, although I'm not trying to generate moves or anything, thus array based would be ideal.

I'd need to have the graphical representation (i.e., like a screenshot a way to load up the games to view them), so I could organize by hand. Well, by sight, actually.

If anyone has any ideas, I'd be grateful.

Monica

  • I'd just like to point out that most (>95%) of chess games, even at amateur level, aren't played out until checkmate. – Glorfindel Mar 19 '18 at 20:23
  • I know, that is definitely an issue. Could be a major wrinkle in my plans :( – Monica Heddneck Mar 19 '18 at 20:38
1

To get you started, here's one way you could do this on your own in Python with the python-chess module:

  • In the example we're loading a simple pgn-file for illustration (which you generalize to reading pgns from a loaded database using the same module) and extracting its final position as a bitboard.
  • Then we check if it's a checkmate position, if true, you can extract the pieces on the board as a Square Set.
  • From that, you can then transform the data in any form, e.g. as lists or arrays of the piece symbols and corresponding squares (shown below), or however else it suits your follow-up purposes best.

Here's the snippet for that:

import chess
import chess.pgn
import sys

arguments = sys.argv
pgnfilename = str(arguments[1])

#Read pgn file:
with open(pgnfilename) as f:
    game = chess.pgn.read_game(f)

#Go to the end of the game and create a chess.Board() from it:
game = game.end()
board = game.board()

if board.is_checkmate():
    print "checkmate found: "
    print board

    white_pieces = [(board.piece_at(sq),sq) for sq in chess.SquareSet(board.occupied_co[1])]
    black_pieces = [(board.piece_at(sq),sq) for sq in chess.SquareSet(board.occupied_co[0])]

    print "white pieces: "
    for el in white_pieces:
        print el[0].symbol(), " on ", chess.SQUARE_NAMES[el[1]]

    print "---------------------"
    print "black pieces: "
    for el in black_pieces:
        print el[0].symbol(), " on ", chess.SQUARE_NAMES[el[1]]

Which gives the following output for the downloaded PGN of this game between Alexander Alekhine vs Oscar Tenner:

r . . q . . . r
p p p . . B p p
. . . . . . . .
. . B . k R . n
. . . . P . . .
. . . P . . . .
P P P . . . P P
R . . b . . K .
white pieces:
R  on  a1
K  on  g1
P  on  a2
P  on  b2
P  on  c2
P  on  g2
P  on  h2
P  on  d3
P  on  e4
B  on  c5
R  on  f5
B  on  f7
---------------------
black pieces:
b  on  d1
k  on  e5
n  on  h5
p  on  a7
p  on  b7
p  on  c7
p  on  g7
p  on  h7
r  on  a8
q  on  d8
r  on  h8

Additional details and ways of extension:

  • Conventionally, capital and small symbols are used for white and black pieces respectively. For a better display of the board, you can use the Unicode symbols for chess pieces and encode them appropriately (depending on your python installation or possibly OS) for printing. In our example above, you could have immediately retained the Unicode of each piece instead of its symbol, board.piece_at(sq).unicode_symbol()
  • Given a PGN-formatted database (e.g., using TWIC PGNS), you can easily load it by reading it in python and extracting the starting/ending line indices of each game[*] in the database, and in a loop over all games, you pass each game as a PGN file to chess.pgn.read_game and the rest follows similarly as in the snippet above.

Feel free to ask in comments if you have any questions about the snippet and other ways of extending it.

[*]: All this depends on the database you're trying to work with, but once the formatting known, then you can e.g., parse games based on a keyword that occurs at the start of each game in the database, for instance in the TWIC ones, there's always a line with Event .. in the headers of the PGN, or even the empty lines between the games. However you go about it, once you know the starting and ending line indices of a game within the file, you can pass it to chess.pgn.read_game as a file-like object with cStringIO.StringIO in python. It's not the most efficient way necessarily, but it does the trick.

  • wow this is amazing, couldn't have asked for a better assist in the right direction from someone knowledgeable. Thanks!! – Monica Heddneck Mar 19 '18 at 21:40
  • 1
    My pleasure, sounds like a potentially cool project :) Let me know if you face any obstacles in trying to run the snippet or have any follow up questions. – Phonon Mar 19 '18 at 21:48

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.