Я внес некоторые коррективы в ваш код. Главным образом я пытался избежать циклов и использовал scipys
convolve2d()
для создания sol_mat
. Основным преимуществом этого метода является то, что вам не нужно беспокоиться о крайних случаях изображения. Использование 3x3 kernel
из ones
для логического массива бомб дает точное количество соседних бомб (флаги в тральщике).
import numpy as np
from scipy.signal import convolve2d
grid_size = (7, 7)
n_bombs = 5
bomb_mat = np.zeros(grid_size, dtype=int)
bomb_mat[np.random.randint(low=1, high=grid_size[0]-1, size=n_bombs),
np.random.randint(low=1, high=grid_size[1]-1, size=n_bombs)] = 1
# array([[0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 1, 0, 0],
# [0, 0, 1, 0, 0, 0, 0],
# [0, 1, 1, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0],
# [0, 0, 1, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0]])
sol_mat = convolve2d(bomb_mat, np.ones((3, 3)), mode='same').astype(int)
sol_mat[bomb_mat.astype(bool)] = 10
# array([[ 0, 0, 0, 1, 1, 1, 0],
# [ 0, 1, 1, 2, 10, 1, 0],
# [ 1, 3, 10, 3, 1, 1, 0],
# [ 1, 10, 10, 2, 0, 0, 0],
# [ 1, 3, 3, 2, 0, 0, 0],
# [ 0, 1, 10, 1, 0, 0, 0],
# [ 0, 1, 1, 1, 0, 0, 0]])
Вы можете использовать np.tril()
и np.triu()
, чтобы получить нижний и верхний треугольник массива. Построив пересечение булевых треугольников с условием sol_mat == 0
, вы получите искомые индексы:
lower0 = np.logical_and(np.tril(np.ones(grid_size)), sol_mat == 0)
# lower0.astype(int)
# array([[1, 0, 0, 0, 0, 0, 0],
# [1, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 0, 1, 0, 0],
# [1, 0, 0, 0, 1, 1, 0],
# [1, 0, 0, 0, 1, 1, 1]])
upper0 = np.logical_and(np.triu(np.ones(grid_size)), sol_mat == 0)
# upper0.astype(int)
# array([[1, 1, 1, 0, 0, 0, 1],
# [0, 0, 0, 0, 0, 0, 1],
# [0, 0, 0, 0, 0, 0, 1],
# [0, 0, 0, 0, 1, 1, 1],
# [0, 0, 0, 0, 1, 1, 1],
# [0, 0, 0, 0, 0, 1, 1],
# [0, 0, 0, 0, 0, 0, 1]])
Вы можете получить индексы этих массивов через np.nonzero()
:
lower0_idx = np.array(np.nonzero(lower0))
# array([[0, 1, 4, 5, 5, 5, 6, 6, 6, 6],
# [0, 0, 4, 0, 4, 5, 0, 4, 5, 6]])
upper0_idx = np.array(np.nonzero(upper0))
# array([[0, 0, 0, 0, 1, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6],
# [0, 1, 2, 6, 6, 6, 4, 5, 6, 4, 5, 6, 5, 6, 6]])