text-based chess board in python

Question:

I have just started a python project where I make a text-based chess game. When I print out the board, things do not look very good. The characters are way to small, which gives it the look of being spaced out. Plus, the board is way more thin than it is tall. How would I actually make a good-looking chess board?

My code looks like this:

import os, readchar, time, threading, random
global arrowKey
global speed
newchar = ''
arrowKey = {'x1b[A': 'up'}
class Array:
    def __init__(self, x=16, y=8, board=None):
        self.pos = ()
        self.x = x
        self.y = y
        grid = [' ' + '_' * self.x]
        for _ in range(y):
            row = ['|']
            for _ in range(x):
                row.append(' ')
            row.append('|')
            grid.append(row)
        grid.append(' ' + '‾' * self.x)
        self.grid = grid
        if board != None:
            self.grid = board
    def reload(self, say=None):
        os.system('clear')
        if say != None:
            print(say)
        p = ''
        for i in self.grid:
            p = p + ''.join([x for x in i]) + 'n'
        print(p)
    def insert(self, char, x, y):
        self.pos = (x, y)
        self.grid[y][x] = char
    def move(self, direction, char):
        poslist = []
        for y, i in enumerate(self.grid):
            for x, j in enumerate(i):
                if j == char:
                    poslist.append((x, y))
        count = 0
        for posx, posy in poslist:
            if direction == 'down':
                if self.grid[posy + 1][posx] != '‾':
                    self.insert(' ', posx, posy)
                    self.insert(char, posx, posy + 1)
                    self.pos = (posx, posy + 1)
            if direction == 'up':
                if self.grid[posy - 1][posx] != '_':
                    self.insert(' ', posx, posy)
                    self.insert(char, posx, posy - 1)
                    self.pos = (posx, posy - 1)
            if direction == 'left':
                if self.grid[posy][posx - 1] != '|':
                    self.insert(' ', posx, posy)
                    self.insert(char, posx - 1, posy)
                    self.pos = (posx - 1, posy)
            if direction == 'right':
                if self.grid[posy][posx + 1] != '|':
                    self.insert(' ', posx, posy)
                    self.insert(char, posx + 1, posy)
                    self.pos = (posx + 1, posy)
            count += 1
    def getpos(self, char):
        poslist = []
        for y, i in enumerate(self.grid):
            for x, j in enumerate(i):
                if j == char:
                    poslist.append((x, y))
        count = 0
        return poslist
class Chess(Array):
    def __init__(self):
        board = [['|' if i % 2 == 0 else ' ' for i in range(17)] if x % 2 == 0 else ['+' if i % 2 == 0 else '—' for i in range(17)] for x in range(16)]
        board.insert(0, ['+' if i % 2 == 0 else '—' for i in range(17)])
        super().__init__(board=board)
        self.array = super()
board = Chess()
board.array.reload()

Sorry if some of the code looks out of context, I reused some of the code from my previous chrome dino game and my tic-tac-toe game. I mostly expected a good looking chess board, but as I said, it looked really weird.

The output looks like this:

Output

Maybe someething like this would be cool.

Asked By: Mark Wilson

||

Answers:

You can experiment with board cell width, and then you can get something more or less square-like.
Also you can make turns by cutting-paste figures on the board. E.g.:

BOARD = """     A     B     C     D     E     F     G     H
  |—————|—————|—————|—————|—————|—————|—————|—————|
8 |  r  |  n  |  b  |  q  |  k  |  b  |  n  |  r  | 8
  |—————|—————|—————|—————|—————|—————|—————|—————|
7 |  p  |  p  |  p  |  p  |  p  |  p  |  p  |  p  | 7
  |—————|—————|—————|—————|—————|—————|—————|—————|
6 |     |     |     |     |     |     |     |     | 6
  |—————|—————|—————|—————|—————|—————|—————|—————|
5 |     |     |     |     |     |     |     |     | 5
  |—————|—————|—————|—————|—————|—————|—————|—————|
4 |     |     |     |     |     |     |     |     | 4
  |—————|—————|—————|—————|—————|—————|—————|—————|
3 |     |     |     |     |     |     |     |     | 3
  |—————|—————|—————|—————|—————|—————|—————|—————|
2 |  P  |  P  |  P  |  P  |  P  |  P  |  P  |  P  | 2
  |—————|—————|—————|—————|—————|—————|—————|—————|
1 |  R  |  N  |  B  |  Q  |  K  |  B  |  N  |  R  | 1
  |—————|—————|—————|—————|—————|—————|—————|—————|
     A     B     C     D     E     F     G     H"""
INDEXES = {'e2': 766, 'e4': 554}

cell_start, cell_end = input('Your turn: ').split(' ')
index_start = INDEXES[cell_start]
index_end = INDEXES[cell_end]
figure = BOARD[index_start]
BOARD = BOARD[:index_end] + figure + BOARD[index_end+1:]
BOARD = BOARD[:index_start] + ' ' + BOARD[index_start+1:]
print(BOARD)

Output:

Your turn: e2 e4
     A     B     C     D     E     F     G     H
  |—————|—————|—————|—————|—————|—————|—————|—————|
8 |  r  |  n  |  b  |  q  |  k  |  b  |  n  |  r  | 8
  |—————|—————|—————|—————|—————|—————|—————|—————|
7 |  p  |  p  |  p  |  p  |  p  |  p  |  p  |  p  | 7
  |—————|—————|—————|—————|—————|—————|—————|—————|
6 |     |     |     |     |     |     |     |     | 6
  |—————|—————|—————|—————|—————|—————|—————|—————|
5 |     |     |     |     |     |     |     |     | 5
  |—————|—————|—————|—————|—————|—————|—————|—————|
4 |     |     |     |     |  P  |     |     |     | 4
  |—————|—————|—————|—————|—————|—————|—————|—————|
3 |     |     |     |     |     |     |     |     | 3
  |—————|—————|—————|—————|—————|—————|—————|—————|
2 |  P  |  P  |  P  |  P  |     |  P  |  P  |  P  | 2
  |—————|—————|—————|—————|—————|—————|—————|—————|
1 |  R  |  N  |  B  |  Q  |  K  |  B  |  N  |  R  | 1
  |—————|—————|—————|—————|—————|—————|—————|—————|
     A     B     C     D     E     F     G     H
Answered By: Alderven

You can increase the size of the characters used to represent the chess pieces and the board by changing the size of the characters used in the Array class. For example, you can use the following code to increase the size of the characters by a factor of 2:

class Array:
    def __init__(self, x=16, y=8, board=None):
        self.pos = ()
        self.x = x
        self.y = y
        grid = [' ' + '_' * (self.x * 2)]
        for _ in range(y):
            row = ['|']
            for _ in range(x):
                row.append('  ')
            row.append('|')
            grid.append(row)
        grid.append(' ' + '‾' * (self.x * 2))
        self.grid = grid
        if board != None:
            self.grid = board

You can use Unicode characters for chess pieces by replacing the characters used in the Chess class with Unicode characters. For example, you can use the following code to represent the chess pieces with Unicode characters:

class Chess(Array):
    def __init__(self):
        board = [['|' if i % 2 == 0 else ' ' for i in range(17)] if x % 2 == 0 else ['+' if i % 2 == 0 else '—' for i in range(17)] for x in range(16)]
        board.insert(0, ['+' if i % 2 == 0 else '—' for i in range(17)])
        super().__init__(board=board)
        self.array = super()
        self.grid[1][1] = '♜'
        self.grid[1][2] = '♞'
        self.grid[1][3] = '♝'
        self.grid[1][4] = '♛'
        self.grid[1][5] = '♚'
        self.grid[1][6] = '♝'
        self.grid[1][7] = '♞'
        self.grid[1][8] = '♜'
        for i in range(1, 9):
            self.grid[2][i] = '♟︎'
        self.grid[8][1] = '♖'
        self.grid[8][2] = '♘'
        self.grid[8][3] = '♗'
        self.grid[8][4] = '♕'
        self.grid[8][5] = '♔'
        self.grid[8][6] = '♗'
        self.grid[8][7] = '♘'
        self.grid[8][8] = '♖'
        for i in range(1, 9):
            self.grid[7][i] = '♙'

Answered By: Tommy Olsen
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.