1

Are there any software programs or tools available that can display the number of pieces attacking each square?

1 Answer 1

3

This python script will show how many white/black attackers on every square.

It will also generate an image in png format where the attacked square is marked with X and the attacker locations are colored green.

Edit: Added code to generate an attack heatmap. Edit: Update attack heatmap board labels.

Code

"""
pip install chess
pip install cairosvg
"""

import chess
import chess.svg
from cairosvg import svg2png


def main():
    fen = 'rn1r3k/pp2qpp1/1bb1p3/6p1/2BP4/P4N2/1PQ1RPPP/4R1K1 w - - 0 19'

    board = chess.Board(fen)
    print(board)
    print()

    for square in range(64):
        sq_name = chess.square_name(square)
        w_attackers = board.attackers(chess.WHITE, square)
        b_attackers = board.attackers(chess.BLACK, square)

        svg = chess.svg.board(
            board,
            fill=dict.fromkeys((w_attackers | b_attackers), "#00FF00"),
            squares=(chess.SquareSet([square])),
            size=350,
        )

        png_fn = f'{sq_name}_board.png'
        svg2png(bytestring=svg, write_to=png_fn)

        print(f'sq: {sq_name}, wattackers: {len(list(w_attackers))}, battackers: {len(list(b_attackers))}')


if __name__ == '__main__':
    main()

Sample Image Output

a4_board.png

enter image description here


e6_board.png

enter image description here


Sample Text Output

r n . r . . . k
p p . . q p p .
. b b . p . . .
. . . . . . p .
. . B P . . . .
P . . . . N . .
. P Q . R P P P
. . . . R . K .

sq: a1, wattackers: 1, battackers: 0
sq: b1, wattackers: 2, battackers: 0
sq: c1, wattackers: 2, battackers: 0
sq: d1, wattackers: 2, battackers: 0
sq: e1, wattackers: 2, battackers: 0
sq: f1, wattackers: 2, battackers: 0
sq: g1, wattackers: 2, battackers: 0
sq: h1, wattackers: 1, battackers: 0
sq: a2, wattackers: 1, battackers: 0
sq: b2, wattackers: 1, battackers: 0
sq: c2, wattackers: 1, battackers: 0
sq: d2, wattackers: 3, battackers: 0
sq: e2, wattackers: 3, battackers: 0
sq: f2, wattackers: 2, battackers: 0
sq: g2, wattackers: 1, battackers: 0
sq: h2, wattackers: 2, battackers: 0
sq: a3, wattackers: 1, battackers: 1
sq: b3, wattackers: 2, battackers: 0
sq: c3, wattackers: 2, battackers: 0
sq: d3, wattackers: 2, battackers: 0
sq: e3, wattackers: 2, battackers: 0
sq: f3, wattackers: 1, battackers: 1
sq: g3, wattackers: 2, battackers: 0
sq: h3, wattackers: 1, battackers: 0
sq: a4, wattackers: 1, battackers: 1
sq: b4, wattackers: 1, battackers: 1
sq: c4, wattackers: 1, battackers: 0
sq: d4, wattackers: 1, battackers: 2
sq: e4, wattackers: 2, battackers: 1
sq: f4, wattackers: 0, battackers: 1
sq: g4, wattackers: 0, battackers: 0
sq: h4, wattackers: 1, battackers: 1
sq: a5, wattackers: 0, battackers: 1
sq: b5, wattackers: 1, battackers: 1
sq: c5, wattackers: 1, battackers: 2
sq: d5, wattackers: 1, battackers: 3
sq: e5, wattackers: 3, battackers: 0
sq: f5, wattackers: 1, battackers: 1
sq: g5, wattackers: 1, battackers: 1
sq: h5, wattackers: 0, battackers: 0
sq: a6, wattackers: 1, battackers: 2
sq: b6, wattackers: 0, battackers: 1
sq: c6, wattackers: 0, battackers: 2
sq: d6, wattackers: 0, battackers: 2
sq: e6, wattackers: 2, battackers: 2
sq: f6, wattackers: 0, battackers: 2
sq: g6, wattackers: 1, battackers: 1
sq: h6, wattackers: 0, battackers: 1
sq: a7, wattackers: 0, battackers: 2
sq: b7, wattackers: 0, battackers: 2
sq: c7, wattackers: 0, battackers: 2
sq: d7, wattackers: 0, battackers: 4
sq: e7, wattackers: 0, battackers: 0
sq: f7, wattackers: 0, battackers: 1
sq: g7, wattackers: 0, battackers: 1
sq: h7, wattackers: 1, battackers: 1
sq: a8, wattackers: 0, battackers: 0
sq: b8, wattackers: 0, battackers: 2
sq: c8, wattackers: 0, battackers: 1
sq: d8, wattackers: 0, battackers: 2
sq: e8, wattackers: 0, battackers: 3
sq: f8, wattackers: 0, battackers: 2
sq: g8, wattackers: 0, battackers: 2
sq: h8, wattackers: 0, battackers: 1

You have to change the FEN in the code for other positions.

Updated code to generate an attack heatmap

The map is saved in html file.

"""
pip install chess
pip install cairosvg
pip install numpy
pip install plotly
"""

import chess
import chess.svg
from cairosvg import svg2png
import plotly.express as px
import numpy


def main():
    fen = 'rn1r3k/pp2qpp1/1bb1p3/6p1/2BP4/P4N2/1PQ1RPPP/4R1K1 w - - 0 19'

    board = chess.Board(fen)
    print(board)
    print()

    att = {i: 0 for i in range(64)}

    for square in range(64):
        sq_name = chess.square_name(square)
        w_attackers = board.attackers(chess.WHITE, square)
        b_attackers = board.attackers(chess.BLACK, square)

        att[square] += len(w_attackers) + len(b_attackers)

        svg = chess.svg.board(
            board,
            fill=dict.fromkeys((w_attackers | b_attackers), "#00FF00"),
            squares=(chess.SquareSet([square])),
            size=350,
        )

        png_fn = f'{sq_name}_board.png'
        svg2png(bytestring=svg, write_to=png_fn)

        print(f'sq: {sq_name}, wattackers: {len(list(w_attackers))}, battackers: {len(list(b_attackers))}')

    # Create a heatmap using plotly.
    att_list = []
    for k, v in att.items():
        att_list.append(v)

    np_arr = numpy.array(att_list)
    np_arr_8_by_8 = np_arr.reshape(8, 8)
    np_arr_8_by_8_flip = numpy.flip(np_arr_8_by_8, 0)

    fig = px.imshow(np_arr_8_by_8_flip, text_auto=True,
                labels=dict(color='numattacks'),
                x=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],
                y=['8', '7', '6', '5', '4', '3', '2', '1'])
    fig.write_html('attack_heatmap.html')
    # fig.show()


if __name__ == '__main__':
    main()

Output

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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