function moves = solver(board,nMoves)
%SOLVER Solve the Blockbuster Contest problem
%
% MOVES = SOLVER(BOARD,NMOVES) BlockBuster solver.
%
% MOVES -> [row,column,action]
% action -> 0 busts, 1 swap up, 2 swap right, 3 swap down, 4 swap left
[n m]=size(board);
moves=[0 0 0];
jm=1;flg=true;
for jm=1:nMoves
h=[abs(board(:,2:end)-board(:,1:(end-1))) ones(n,1)];
v=[abs(board(2:end,:)-board(1:(end-1),:));ones(1,m)];
h2=[abs(board(:,3:end)-board(:,1:(end-2))) ones(n,2)];
v2=[abs(board(3:end,:)-board(1:(end-2),:));ones(2,m)];
j=find(~(h2+v2+h+v)&board);
if isempty(j)
j=find(~(v2+h+v)&board);
if isempty(j)
j=find(~(h2+h+v)&board);
if isempty(j)
j=find(~(h+v)&board);
if isempty(j)
j=find(~(h2+h)&board);
if isempty(j)
j=find(~(v2+v)&board);
if isempty(j)
j=find(~h&board);
if isempty(j)
j=find(~v&board);
end
end
end
end
end
end
end
if isempty(j)
moves(jm,3)=3;
j=find(~v2&board);
if isempty(j)
moves(jm,3)=2;
j=find(~h2&board);
if isempty(j)
j=find(board(:,1:m-1)&board(:,2:m));
if isempty(j)
moves(jm,3)=3;
j=find([board(1:n-1,:);zeros(1,m)]&[ones(1,m);board(2:n,:)]);
if isempty(j)
j=find(board(j));
end
end
end
end
[u jj]=max(board(j));
[moves(jm,1) moves(jm,2)]=ind2sub([n m],j(jj)); u=board(moves(jm,1),moves(jm,2));
board(moves(jm,1),moves(jm,2))=board(moves(jm,1)+(moves(jm,3)==3),moves(jm,2)+(moves(jm,3)==2));
board(moves(jm,1)+(moves(jm,3)==3),moves(jm,2)+(moves(jm,3)==2))=u;
else
[u jj]=max(board(j));
[moves(jm,1) moves(jm,2)]=ind2sub([n m],j(jj));
board=evolve(board,moves(jm,:));
end
end
end %end of solver
function A= evolve(A,mv)
% N=1, E=2, S=3, W=4
I = [-1 0 1 0 ];
J = [ 0 1 0 -1 ];
N = false(size(A));
k = 1;
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
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 evolve (subfunction)
|