millie
millie

Reputation: 1

Simple way in matlab to count number of adjacent non-zero values in matrix?

I am fairly new at Matlab, and I have to create a minesweeper game on matlab where I generate a random matrix A of ones and zeroes, where ones are mines and zeroes are not. Then I have to create a matrix B, where each element has to be the number of adjacent mines (or ones) from matrix A. The ones (or mines) become 10s in matrix B.

for example if A = [0 1 0 1 0 1]

B= [2 10 2 10 3 10]

I don't know how to set up matrix B so that it can count the number of adjacent ones of matrix A and set that for each element. Is there a simple way to do that?

Upvotes: 0

Views: 1318

Answers (2)

kkuilla
kkuilla

Reputation: 2256

You could also use convolution

A=[0 1 0 1 0 1];
B=ones(1,3);
B(2) = 0;
R=conv(A,B, 'same');
R(find(A==1))= 10      

R =

1   10    2   10    2   10

B is the neighbourhood you would like to take into account. You want the two closest neighbours plus the actual value, hence B is a 1x3 vector.

A=[0 1 0 1 0 1];
B=ones(1,3);

You only want the adjacent values so set the centre point to zero

 B(2) = 0;

Convolve the A and B. Use the same option so that the output has the same size as your input.

R=conv(A,B, 'same');

Replace your mines with 10.

R(find(A==1))= 10 

Two dimensions

You may want to get the mines count around your current cell in two dimensions. Then you just create a 9x9 neighbourhood of 1 and convolve A and B in 2D.

A=ones(10);
A(2:2:end, 2:2:end) = 0 % Create your grid. Every other cell is a mine.
B=ones(3);
B(2,2) = 0  % Exclude the current cell
R=conv2(A,B,'same');

Upvotes: 2

David
David

Reputation: 8459

I think your B vector should be [1 10 2 10 2 10].

For your vector case, you can do the following.

B=zeros(size(A)); %// to initialise the B vector as 0's

Then to get how many mines are adjacent to each location, you can just add up the number to the left and right of that location. Remember that at the end-points there can only be mines to the left or right.

B(2:end-1)=A(1:end-2)+A(3:end); %// counting mines on both sides
B(1)=A(2); %// only on the right of the first location
B(end)=A(end-1); %// only on the end at the last location

Then to put 10's where the mines are, you can just find the 1's in A and make those locations in B become 10, using logical indexing.

B(A==1)=10; %// find where A=1 (mines) and set the element of B to 10

The same approach works for matrices, but you have to be careful with taking all the elements surrounding each location, and you have to be careful with the boundaries as well.

Upvotes: 2

Related Questions