python-chess
python-chess copied to clipboard
Board.__str__ including grid labels
To me, it's easier to see/understand a board's printed representation with the rank/file shown.
In [1]: import chess
In [2]: board = chess.Board()
In [3]: print(board)
r n b q k b n r
p p p p p p p p
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
P P P P P P P P
R N B Q K B N R
It would be nice to support the ability to show the grid:
In [4]: print(board.grid())
| a b c d e f g h
- + ---------------
8 | r n b q k b n r
7 | p p p p p p p p
6 | . . . . . . . .
5 | . . . . . . . .
4 | . . . . . . . .
3 | . . . . . . . .
2 | P P P P P P P P
1 | R N B Q K B N R
Alternately, an instance attribute verbose
could be added that somehow enables behaviors like this when __str__
is invoked.
I think this looks good. I wonder if it's acceptable to just change __str__
, or if that would be considered a breaking change.
Yeah I think it would be fine to change __str__
too.
One question is, how do you see board.mirror()
affecting things?
One question is, how do you see
board.mirror()
affecting things?
board.mirror()
should not need special consideration. It's not to be confused with changing the orientation of looking at the board - chess.Board()
has no concept of that. board.mirror()
returns a different position, that happens to have pieces in mirrored positions.
For reference, here is a prettifying wrapper I use around str(Board)
:
def diagram(b, *, flipped=False, labels=0, pretty=False):
# pylint: disable=multiple-statements,consider-using-f-string
assert isinstance(b, Board), f"Not a Board: {repr(b)}"
string = b.unicode(empty_square='.') if pretty else str(b)
if flipped:
rows = [''.join(reversed(row)) for row in reversed(string.split('\n'))]
if labels == 0: return '\n'.join(rows)
elif labels == 1: return '\n'.join('%d %s' % (i,row) for i,row in enumerate(rows, start=1)) + '\n h g f e d c b a'
elif labels == -1: return ' h g f e d c b a\n' + '\n'.join(' %s %d' % (row,i) for i,row in enumerate(rows, start=1))
else: return ' h g f e d c b a\n + --------------- +\n' + '\n'.join('%d | %s | %d' % (i,row,i) for i,row in enumerate(rows, start=1)) + '\n + --------------- +\n h g f e d c b a'
else:
rows = string.split('\n')
if labels == 0: return '\n'.join(rows)
# pylint: disable=consider-using-in
elif labels == 1 or labels == -1: return '\n'.join('%d %s' % (8-i,row) for i,row in enumerate(rows)) + '\n a b c d e f g h'
else: return ' a b c d e f g h\n + --------------- +\n' + '\n'.join('%d | %s | %d' % (8-i,row,8-i) for i,row in enumerate(rows)) + '\n + --------------- +\n a b c d e f g h'
Use pretty=True
to get Unicode pieces. Use flipped=True
to invert the perspective (putting black on bottom). Use labels=1
to get row/column labels to the left and bottom of the board. When flipped=True
, you can also use labels=-1
to get labels on the top and right of the board instead. (When flipped=False
, labels=-1
works just like labels=1
.)
No grid lines. But this is a starting point that someone can use to write something more full-featured.
@dubiousjim I like your support of unicode, nice! I am using this now 👍, with a few mods:
- I changed
labels
arg name toverbosity
and only support[0, 1, 2]
- I moved from
"\n"
toos.linesep
- From this comment above:
board.mirror()
should not need special consideration.
I think this means no need to support flipped
capability, just rely on the caller previously invoking board.apply_mirror()
or board.mirror()
.
One possible improvement for labels
/verbosity=2
: maybe add the player whose turn it is with *
or .
as the corner. This can be discerned with board.turn == chess.WHITE
and board.turn == chess.BLACK
.
For example, if it's white player's turn, note the *
:
a b c d e f g h
. --------------- .
8 | r . b q k b . r | 8
7 | p p . n p p . p | 7
6 | . . p p . n p . | 6
5 | . . . . . . . . | 5
4 | . . . . P . . . | 4
3 | . . N . . N . P | 3
2 | P P P P B P P . | 2
1 | R . B Q K . . R | 1
* --------------- *
a b c d e f g h
Flipped board just displays the 8 rank at the bottom, it doesn't change any piece positions. (White K still starts at e1, this is just now displayed at the top instead of at the bottom.) Mirrored board moves the piece that was at a6 instead to a3. These are different concepts.
Okay I see, sorry I didn't scrutinize that much. I think the default chess
behavior is 8th rank on the top.
One other cool feature in a display function would be to highlight captures, check, or checkmates, possibly via colors. This behavior could be turned on with an additional color
flag.
I would be interested in taking on this issue!
I would also be interested in taking this, if someone already is in development though, please say