function [score,A] = grade(A,movesCtr,mv)
%GRADE Make sure the answer is valid and compute its score.
% Copyright 2006 The MathWorks, Inc.
% N=1, E=2, S=3, W=4
I = [-1 0 1 0 ];
J = [ 0 1 0 -1 ];
N = false(size(A));
% Check maximum number of moves allowed
if size(mv,1)>movesCtr || size(mv,2)~=3
error('Too many rows (more than NMOVES).')
end
% First (second) column of moves should be integer values from 1 to
% num_rows (num_columns)
if ~all(ismember(mv(:,1),1:size(A,1))) || ~all(ismember(mv(:,2),1:size(A,2)))
error('Indices are outside the bounds of the board.');
end
% Third column of moves should be integer values from 0 to 4
if ~all(ismember(mv(:,3),0:4))
error('Third column must have only integer values from 0 to 4');
end
for k = 1:size(mv,1) % for every move
cp = mv(k,1:2);
if A(cp(1),cp(2))>0 %current block must be a non-empty space
if mv(k,3) % swap ?
np = cp + [I(mv(k,3)) J(mv(k,3))];
% swap block must be within the bounds of the board and a non-empty space
if all(np>=1) && all(np<=size(A)) && A(np(1),np(2))>0
A([cp(1),np(1)],[cp(2),np(2)]) = A([np(1),cp(1)],[np(2),cp(2)]);
else
warning('Swap to an empty space or beyond the bounds of the board.')
end
else % remove block and neighbors
N(:) = false;
findNeighbors(cp(1),cp(2),A(cp(1),cp(2)));
if sum(N(:))>1
anyN = any(N);
for j = 1:size(A,2)
if anyN(j)
tmp = A(~N(:,j),j);
A(:,j) = 0;
A(end-sum(~N(:,j))+1:end,j) = tmp;
end
end
else
warning('You cannot pop single blocks.')
end
end
else
warning('Indices point to an empty space.')
end
end
score = sum(A(:));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function findNeighbors(i,j,c)
if ~N(i,j);
N(i,j) = true;
if i>1 && A(i-1,j)==c; findNeighbors(i-1,j,c); end
if j<size(A,2) && A(i,j+1)==c; findNeighbors(i,j+1,c); end
if i<size(A,1) && A(i+1,j)==c; findNeighbors(i+1,j,c); end
if j>1 && A(i,j-1)==c; findNeighbors(i,j-1,c); end
end
end % end of findNeighbors (nested function)
end % end of grade (subfunction)