Unicode chessboard in a terminal

Gribouillis 3 Tallied Votes 6K Views Share

This python 2 code snippet uses unicode chess symbols and box drawings symbols to display a chessboard in a terminal. With a terminal profile having a monospace font of size 20 or more, it looks quite usable to play chess.

maxvanden commented: good +0
#!/usr/bin/env python
# -*-coding: utf8-*-
# Title: chessboard.py
# Author: Gribouillis
# Created: 2012-05-19 22:18:09.909216 (isoformat date)
# License: Public Domain
# Use this code freely.

version_info = (0, 1)
version = ".".join(map(str, version_info))

# some noise

pieces = u''.join(unichr(9812 + x) for x in range(12))
pieces = u' ' + pieces[:6][::-1] + pieces[6:] 
allbox = u''.join(unichr(9472 + x) for x in range(200))
box = [ allbox[i] for i in (2, 0, 12, 16, 20, 24, 44, 52, 28, 36, 60) ]
(vbar, hbar, ul, ur, ll, lr, nt, st, wt, et, plus) = box

h3 = hbar * 3

# useful constant unicode strings to draw the square borders

topline = ul + (h3 + nt) * 7 + h3 + ur
midline = wt + (h3 + plus) * 7 + h3 + et
botline = ll + (h3 + st) * 7 + h3 + lr

tpl = u' {0} ' + vbar

def inter(*args):
    """Return a unicode string with a line of the chessboard.
    
    args are 8 integers with the values
        0 : empty square
        1, 2, 3, 4, 5, 6: white pawn, knight, bishop, rook, queen, king
        -1, -2, -3, -4, -5, -6: same black pieces
    """
    assert len(args) == 8
    return vbar + u''.join((tpl.format(pieces[a]) for a in args))
    


print pieces
print ' '.join(box)
print

start_position = (
    [
        (-4, -2, -3, -5, -6, -3, -2, -4),
        (-1,) * 8,
    ] +
    [ (0,) * 8 ] * 4 +
    [
        (1,) * 8,
        (4, 2, 3, 5, 6, 3, 2, 4),
    ]
)

def _game(position):
    yield topline
    yield inter(*position[0])
    for row in position[1:]:
        yield midline
        yield inter(*row)
    yield botline
game = lambda squares: "\n".join(_game(squares))
game.__doc__ = """Return the chessboard as a string for a given position.

    position is a list of 8 lists or tuples of length 8 containing integers
"""

if __name__ == "__main__":
    print game(start_position)
Gribouillis 1,391 Programming Explorer Team Colleague

I tried to attach an image to the code snippet, but it does not seem to work :(

opprogrammer 0 Newbie Poster

I tried running the code in Python 2.5, but there was an error:

 ♙♘♗♖♕♔♚♛♜♝♞♟
│ ─ ┌ ┐ └ ┘ ┬ ┴ ├ ┤ ┼

Traceback (most recent call last):
  File "C:/Users/Owen/Desktop/chess/chess8.py", line 52, in <module>
    print game(start_position)
  File "C:/Users/Owen/Desktop/chess/chess8.py", line 47, in <lambda>
    game = lambda squares: "\n".join(_game(squares))
  File "C:/Users/Owen/Desktop/chess/chess8.py", line 42, in _game
    yield inter(*position[0])
  File "C:/Users/Owen/Desktop/chess/chess8.py", line 24, in inter
    return vbar + u''.join((tpl.format(pieces[a]) for a in args))
  File "C:/Users/Owen/Desktop/chess/chess8.py", line 24, in <genexpr>
    return vbar + u''.join((tpl.format(pieces[a]) for a in args))
AttributeError: 'unicode' object has no attribute 'format'

What version of Python are you using?

Gribouillis 1,391 Programming Explorer Team Colleague

It has been a long time since I last used python 2.5. Can't you upgrade to 2.7 ? The following should work for 2.5: replace line 28 with tpl = u' %s ' + vbar and replace tpl.format(pieces[a]) with tpl % pieces[a] in line 39. The format() method appeared in 2.6. It is now widely used.

Kyril 0 Newbie Poster

Hi, I am probably having some compability issues with my python 3, but if I run the script I get the following error message:

File "/home/user/Dokumente/Python/scripts/PyEncyclopedia/Snippets/chessboard.py", line 15
    pieces = u''.join(unichr(9812 + x) for x in range(12))
               ^
SyntaxError: invalid syntax

I checked it, and as far as I can see everything seems fine. Any ideas?
But thanks for the snippet at any rate, I was able to take quite a lot for myself from it!

TrustyTony 888 ex-Moderator Team Colleague Featured Poster

Python 3 has only unicode strings and does not use u'' but only ''

pieces = u''.join(unichr(9812 + x) for x in range(12))

>>> pieces = ''.join(chr(9812 + x) for x in range(12))
>>> pieces
'♔♕♖♗♘♙♚♛♜♝♞♟'
Kyril 0 Newbie Poster

Ah, thanks, that was the issue! Did not think of that.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.