Printing Command Line Unicode Chess Board Let me preface this by detailing some of my design philosophy. The intent is to view the board from the perspective of the active player. Player moves are also factored into the design. When determining move logic, all that needs to happen is comparing against '0'. For checking the whiteness or blackness of a piece, ord(c) % 265 should help by pulling the remainder and checking if it's in range(4,10) or range(10,16). Anyway, any optimizations and critique is welcome! I'm particularly interested if it involves numpy, scipy | bitwise operators.

chess.py

import numpy as np

chrs = {
    'b_checker': u'\u25FB',
    'b_pawn': u'\u265F',
    'b_rook': u'\u265C',
    'b_knight': u'\u265E',
    'b_bishop': u'\u265D',
    'b_king': u'\u265A',
    'b_queen': u'\u265B',
    'w_checker': u'\u25FC',
    'w_pawn': u'\u2659',
    'w_rook': u'\u2656',
    'w_knight': u'\u2658',
    'w_bishop': u'\u2657',
    'w_king': u'\u2654',
    'w_queen': u'\u2655'
}


def get_checkers():
    bw_row = [chrs['b_checker'], chrs['w_checker']]*4
    bw_checkers = []

    for i in range(8):
        bw_checkers.append(bw_row if i % 2 == 0 else bw_row[::-1])

    bw_checkers = np.array(bw_checkers)
    wb_checkers = bw_checkers[::-1]
    return {'W': wb_checkers, 'B': bw_checkers}


def get_board():

    def get_army(user):
        u = user.lower()
        guard = [chrs[u+'_rook'], chrs[u+'_knight'], chrs[u+'_bishop']]
        rear = guard + [chrs[u+'_king'], chrs[u+'_queen']] + guard[::-1]
        front = [chrs[u+'_pawn']]*8

        if user == 'B':
            return [rear, front]
        else:  # since white moves first
            return [front, rear]

    board = [squad for squad in get_army('B')]

    for _ in range(4):
        board.append(['0']*8)

    board += get_army('W')

    return np.array(board)


def print_board(board, checkers, user):
    chks = checkers[user]
    temp = board.copy() if user == 'W' else board.copy()[::-1]

    for i, row in enumerate(temp):
        for j, c in enumerate(row):
            print('', chks[i][j] if c == '0' else c, end='', flush=True)
        print()


if __name__ == "__main__":
    checkers = get_checkers()
    board = get_board()
    user = 'W'
    print_board(board, checkers, user)


Present Output:

White's Perspective




♜ ♞ ♝ ♚ ♛ ♝ ♞ ♜
♟ ♟ ♟ ♟ ♟ ♟ ♟ ♟
◼ ◻ ◼ ◻ ◼ ◻ ◼ ◻
◻ ◼ ◻ ◼ ◻ ◼ ◻ ◼
◼ ◻ ◼ ◻ ◼ ◻ ◼ ◻
◻ ◼ ◻ ◼ ◻ ◼ ◻ ◼
♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙
♖ ♘ ♗ ♔ ♕ ♗ ♘ ♖



Black's Perspective




♖ ♘ ♗ ♔ ♕ ♗ ♘ ♖
♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙
◻ ◼ ◻ ◼ ◻ ◼ ◻ ◼
◼ ◻ ◼ ◻ ◼ ◻ ◼ ◻
◻ ◼ ◻ ◼ ◻ ◼ ◻ ◼
◼ ◻ ◼ ◻ ◼ ◻ ◼ ◻
♟ ♟ ♟ ♟ ♟ ♟ ♟ ♟
♜ ♞ ♝ ♚ ♛ ♝ ♞ ♜
numpy
In this case there is no need to use. For an 8 by 8 board, filled with strings, there is no advantage to using it, apart from the possibility to index row and column at the same time
enums
You have a few properties wich would be best presented as an enum. The color and the type of the piece
import enum


class Color(enum.Enum):
    WHITE = 0
    BLACK = 1


class Piece(enum.Enum):
    EMPTY = enum.auto()
    PAWN = enum.auto()
    ROOK = enum.auto()
    KNIGHT = enum.auto()
    BISHOP = enum.auto()
    KING = enum.auto()
    QUEEN = enum.auto()

tuple
You have a chrs dictionary with keys that contain both the color and the piece. A better approach here would be to use tuples as keys
chrs = {
    (Color.WHITE, Piece.EMPTY): &quot;\u25FB&quot;,
    (Color.WHITE, Piece.PAWN): &quot;\u265F&quot;,
    (Color.WHITE, Piece.ROOK): &quot;\u265C&quot;,
    (Color.WHITE, Piece.KNIGHT): &quot;\u265E&quot;,
    (Color.WHITE, Piece.BISHOP): &quot;\u265D&quot;,
    (Color.WHITE, Piece.KING): &quot;\u265A&quot;,
    (Color.WHITE, Piece.QUEEN): &quot;\u265B&quot;,
    (Color.BLACK, Piece.EMPTY): &quot;\u25FC&quot;,
    (Color.BLACK, Piece.PAWN): &quot;\u2659&quot;,
    (Color.BLACK, Piece.ROOK): &quot;\u2656&quot;,
    (Color.BLACK, Piece.KNIGHT): &quot;\u2658&quot;,
    (Color.BLACK, Piece.BISHOP): &quot;\u2657&quot;,
    (Color.BLACK, Piece.KING): &quot;\u2654&quot;,
    (Color.BLACK, Piece.QUEEN): &quot;\u2655&quot;,
}

board
You keep a black and a white board. Better would be to keep one board, and just flip it at the time of presentation.
def board_begin():
    return (
        [
            [
                (Color.WHITE, Piece.ROOK),
                (Color.WHITE, Piece.KNIGHT),
                (Color.WHITE, Piece.BISHOP),
                (Color.WHITE, Piece.QUEEN),
                (Color.WHITE, Piece.KING),
                (Color.WHITE, Piece.BISHOP),
                (Color.WHITE, Piece.KNIGHT),
                (Color.WHITE, Piece.ROOK),
            ],
            [(Color.WHITE, Piece.PAWN) for _ in range(8)],
            *[[None] * 8 for _ in range(4)],
            [(Color.BLACK, Piece.PAWN) for _ in range(8)],
            [
                (Color.BLACK, Piece.ROOK),
                (Color.BLACK, Piece.KNIGHT),
                (Color.BLACK, Piece.BISHOP),
                (Color.BLACK, Piece.QUEEN),
                (Color.BLACK, Piece.KING),
                (Color.BLACK, Piece.BISHOP),
                (Color.BLACK, Piece.KNIGHT),
                (Color.BLACK, Piece.ROOK),
            ],
        ]
    )

Here I use None to represent an empty tile, and replace it by a white or black tile at the time of display.
flip board
If you use numpy to keep your board, you can np.flip, or a simple routine like this:
def flip(board):
    return [
        row[::-1] for row in reversed(board)
    ]

display the board
Here a simple routine, which takes a boolean flag on whether to flip it:
def display_board(board, flip_board=False):
    for i, row in enumerate(board if not flip_board else flip(board)):
        row_strings = [
            chrs.get(tile, chrs[(Color((i + j) % 2), Piece.EMPTY)])
            for j, tile in enumerate(row)
        ]
        print(&quot;&quot;.join(row_strings))

using dict.get to replace the empty tiles by the correct squares

board = board_begin()


[[(&lt;Color.WHITE: 0&gt;, &lt;Piece.ROOK: 3&gt;),
        (&lt;Color.WHITE: 0&gt;, &lt;Piece.KNIGHT: 4&gt;),
        (&lt;Color.WHITE: 0&gt;, &lt;Piece.BISHOP: 5&gt;),
        (&lt;Color.WHITE: 0&gt;, &lt;Piece.QUEEN: 7&gt;),
        (&lt;Color.WHITE: 0&gt;, &lt;Piece.KING: 6&gt;),
        (&lt;Color.WHITE: 0&gt;, &lt;Piece.BISHOP: 5&gt;),
        (&lt;Color.WHITE: 0&gt;, &lt;Piece.KNIGHT: 4&gt;),
        (&lt;Color.WHITE: 0&gt;, &lt;Piece.ROOK: 3&gt;)],
       [(&lt;Color.WHITE: 0&gt;, &lt;Piece.PAWN: 2&gt;),
        (&lt;Color.WHITE: 0&gt;, &lt;Piece.PAWN: 2&gt;),
        (&lt;Color.WHITE: 0&gt;, &lt;Piece.PAWN: 2&gt;),
        (&lt;Color.WHITE: 0&gt;, &lt;Piece.PAWN: 2&gt;),
        (&lt;Color.WHITE: 0&gt;, &lt;Piece.PAWN: 2&gt;),
        (&lt;Color.WHITE: 0&gt;, &lt;Piece.PAWN: 2&gt;),
        (&lt;Color.WHITE: 0&gt;, &lt;Piece.PAWN: 2&gt;),
        (&lt;Color.WHITE: 0&gt;, &lt;Piece.PAWN: 2&gt;)],
       [None, None, None, None, None, None, None, None],
       [None, None, None, None, None, None, None, None],
       [None, None, None, None, None, None, None, None],
       [None, None, None, None, None, None, None, None],
       [(&lt;Color.BLACK: 1&gt;, &lt;Piece.PAWN: 2&gt;),
        (&lt;Color.BLACK: 1&gt;, &lt;Piece.PAWN: 2&gt;),
        (&lt;Color.BLACK: 1&gt;, &lt;Piece.PAWN: 2&gt;),
        (&lt;Color.BLACK: 1&gt;, &lt;Piece.PAWN: 2&gt;),
        (&lt;Color.BLACK: 1&gt;, &lt;Piece.PAWN: 2&gt;),
        (&lt;Color.BLACK: 1&gt;, &lt;Piece.PAWN: 2&gt;),
        (&lt;Color.BLACK: 1&gt;, &lt;Piece.PAWN: 2&gt;),
        (&lt;Color.BLACK: 1&gt;, &lt;Piece.PAWN: 2&gt;)],
       [(&lt;Color.BLACK: 1&gt;, &lt;Piece.ROOK: 3&gt;),
        (&lt;Color.BLACK: 1&gt;, &lt;Piece.KNIGHT: 4&gt;),
        (&lt;Color.BLACK: 1&gt;, &lt;Piece.BISHOP: 5&gt;),
        (&lt;Color.BLACK: 1&gt;, &lt;Piece.QUEEN: 7&gt;),
        (&lt;Color.BLACK: 1&gt;, &lt;Piece.KING: 6&gt;),
        (&lt;Color.BLACK: 1&gt;, &lt;Piece.BISHOP: 5&gt;),
        (&lt;Color.BLACK: 1&gt;, &lt;Piece.KNIGHT: 4&gt;),
        (&lt;Color.BLACK: 1&gt;, &lt;Piece.ROOK: 3&gt;)]]


display_board(board, flip_board=False)


♜♞♝♛♚♝♞♜
♟♟♟♟♟♟♟♟
◻◼◻◼◻◼◻◼
◼◻◼◻◼◻◼◻
◻◼◻◼◻◼◻◼
◼◻◼◻◼◻◼◻
♙♙♙♙♙♙♙♙
♖♘♗♕♔♗♘♖


display_board(board, flip_board=True)


♖♘♗♔♕♗♘♖
♙♙♙♙♙♙♙♙
◻◼◻◼◻◼◻◼
◼◻◼◻◼◻◼◻
◻◼◻◼◻◼◻◼
◼◻◼◻◼◻◼◻
♟♟♟♟♟♟♟♟
♜♞♝♚♛♝♞♜


Board class
If you want to incorporate moves etc, it might pay to make a Class of the board, with it's own display, __getitem__ and move routines