Are there any software programs or tools available that can display the number of pieces attacking each square?
1 Answer
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
e6_board.png
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