counting surrounding true's in numpy matrix (python)

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



counting surrounding true's in numpy matrix (python)



I want to make something similiar to minesweeper



input matrix:


matrix = [[true, false, false],
[false, true, false],
[false, false, false]]



if a bomb is on the field I do not count it as bomb is surrounding.



I thought about doing it with numpy convolve somehow but I am struggling with how to go through the matrix and always check the left, top, right and bottom fields of the actual field (in the case of a border I check "empty" fields which is 0 for sure)



enter image description here





2d convolution with a donut-shaped seed.
– Daniel F
Aug 10 at 8:57





no it doesn't have to be numpy, but I thought that this would be the best solution, just not sure how to get it to work. @DanielF hmm how that?
– Dominik Lemberger
Aug 10 at 8:58




3 Answers
3



Here is a solution using scipy.signal.convolve2d :


scipy.signal.convolve2d


import scipy
import numpy as np

# Input matrix, can be left as boolean
matrix = np.array([[True, False, False],
[False, True, False],
[False, False, False]])

# Our dougnut filter
W = np.array([[1, 1, 1],
[1, 0, 1],
[1, 1, 1]])

# Single convolve
res = convolve2d(matrix, W, 'same')



We get the exact result:


res
array([[1, 2, 1],
[2, 1, 1],
[1, 1, 1]])





Dang, got FGITW'd. You can do all the padding and slicing using the boundary and mode parameters of convolve2d though.
– Daniel F
Aug 10 at 9:14


boundary


mode


convolve2d





thanks, exactly what I was looking for :P
– Dominik Lemberger
Aug 10 at 9:19





mode=same is enough, doesnt need the boundary tho :P - boundary wrap makes the output actually wrong as it makes 1,2,1 to 2,1,2
– Dominik Lemberger
Aug 10 at 9:24






Updated! no more boundary
– ibarrond
Aug 10 at 9:52



using only numpy, including nd_window from here


numpy


nd_window


m_pad = np.pad(matrix, ((1,1),(1,1)), 'constant', constant_values=(False, False))
filter = np.array([[1,1,1],[1,0,1],[1,1,1]], dtype = bool)
adj_matrix = np.einsum('ijkl,kl->ij', nd_window(m_pad, 3), filter)



Also, you can use scipy.signal.convolve2d


scipy.signal.convolve2d


adj_matrix = convolve2d(matrix, filter, 'same', fillvalue = False)



To keep it simple : using numpy you can simply use the sum() method (https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.matrix.sum.html).


numpy


sum()



np.matrix(matrix).sum() will count all the True in your matrix.


np.matrix(matrix).sum()


True



So np.matrix(matrix).sum() - matrix[1][1] should return the number of mine around a cell.


np.matrix(matrix).sum() - matrix[1][1]



And for me the easiest way to remove the border problem is to complete your matrix with False cells all around it.


False






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard