Code covered by the BSD License  

Highlights from
MATLAB Contest - Blockbuster

image thumbnail
from MATLAB Contest - Blockbuster by The MATLAB Contest Team
All the files needed to develop and score an entry for the MATLABĀ® Programming Contest.

blockBusterGUI(board,moves)
function blockBusterGUI(board,moves)
% BLOCKBUSTERGUI Play BLOCKBUSTER.
%
% Use left-mouse button to swap blocks by dragging them and the right-mouse
% button to pop a block and its same color neighbors.
%
% BLOCKBUSTERGUI               with no inputs generates a random board.
% BLOCKBUSTERGUI(PROBLEM)      PROBLEM is a struct with 'board' and 'nmoves'.
% BLOCKBUSTERGUI(BOARD,NMOVES) BOARD is a matrix and NMOVES a scalar.
% BLOCKBUSTERGUI([ROWS,COLUMNS,COLORS],NMOVES) All inputs are scalars.

% Copyright 2006 The MathWorks, Inc.

% defaults and input args
if nargin == 0; moves = 50; board = [25,15,4]; end % [rows,columns,colors]
if isstruct(board)
    moves = board.nmoves;
    board = board.board;
end
if numel(board)==3 %set a random board
    rows = board(1); columns = board(2); colors = board(3);
    S = struct('movesCtr',moves,'A',ceil(colors*rand(rows,columns)));
else
    [rows,columns] = size(board); colors = max(board(:));
    S = struct('movesCtr',moves,'A',board);
end
% initilize GUI
hf = figure('menubar','none','name','Blockbuster','NumberTitle','off');
set(hf,'WindowButtonDownFcn',@myClick,'WindowButtonUpFcn',@myRelease);
ha = axes('NextPlot','add','box','on','ydir','reverse');
hi = image(S.A+1);
ht = text(columns+2,0,{sprintf('Score = %d',sum(S.A(:)));...
        sprintf('Moves = %d',S.movesCtr)},'vertical','top','fontsize',20);
hbpatch = patch([1 1],[1 1],1,'CdataMapping','direct');
hpatch  = patch([1 1],[1 1],1,'CdataMapping','direct');    
uicontrol('String','Undo','Callback',@myUndo);
colormap([0 0 0;jet(colors)])
axis equal ; axis off
rp = [0;0]; % used later to save the reference block
N = false(rows,columns); % used later to find neighbors of a block
  
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function myRelease(h,e) 
  buttonType = get(hf,'SelectionType');
  set(hf,'WindowButtonMotionFcn',{});
  set([hpatch,hbpatch],'visible','off')
  cp = round(get(ha,'CurrentPoint').*[1 0 0;0 1 0])*[1 1 0]';
  if S.movesCtr>0 && all(cp>0) && all(cp<=[columns;rows]) && S.A(cp(2),cp(1))
    if strcmp(buttonType,'normal') && sum(abs(cp-rp))==1 %swapper
      S.undo = S;
      S.A([cp(2),rp(2)],[cp(1),rp(1)]) = S.A([rp(2),cp(2)],[rp(1),cp(1)]);
      S.movesCtr = S.movesCtr - 1;
      updateBoard
    elseif strcmp(buttonType,'alt') %buster
      N(:) = false;
      findNeighbors(cp(2),cp(1),S.A(cp(2),cp(1)));
      if sum(N(:))>1
          S.undo = S;
          for k = 1:columns
            S.A(:,k) = [zeros(sum(N(:,k)),1);S.A(~N(:,k),k)];
          end
          S.score = sum(S.A(:));
          S.movesCtr = S.movesCtr - 1;
          updateBoard
      end
    end % of "swapper" or "buster"
  end % of "it's a legal move"
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function myClick(h,e) 
  buttonType = get(hf,'SelectionType');
  cpf = (get(ha,'CurrentPoint').*[1 0 0;0 1 0])*[1 1 0]';
  cp = round(cpf);
  if S.movesCtr>0 && all(cp>0) && all(cp<=[columns;rows]) && S.A(cp(2),cp(1))
    if strcmp(buttonType,'normal') %start dragging
      rp = cp;
      cpf = min(max(cpf,[1;1]),[columns;rows]);
      set(hbpatch,'XData',cp(1)-[1 -1 -1 1 1]/2,'YData',cp(2)-[1 1 -1 -1 1]/2,'visible','on')
      set(hpatch,'XData',cpf(1)-[1 -1 -1 1 1]/2,'YData',cpf(2)-[1 1 -1 -1 1]/2,'Cdata',S.A(cp(2),cp(1))+1,'visible','on')
      set(hf,'WindowButtonMotionFcn',@myMotion);
    end
  end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function myMotion(h,e) 
  cpf = min(max(get(ha,'CurrentPoint').*[1 0 0;0 1 0]*[1 1 0]',1),[columns;rows]);
  set(hpatch,'XData',cpf(1)-[1 -1 -1 1 1]/2,'YData',cpf(2)-[1 1 -1 -1 1]/2)
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function myUndo(h,e) 
  if isfield(S,'undo')
    S = S.undo;
    updateBoard
  end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function updateBoard
  set(hi,'Cdata',S.A+1)
  set(ht,'string',{sprintf('Score = %d',sum(S.A(:)));sprintf('Moves = %d',S.movesCtr)})
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function findNeighbors(i,j,c)
  if ~N(i,j);   
    N(i,j) = true; 
    if i>1       && S.A(i-1,j)==c; findNeighbors(i-1,j,c), end
    if j<columns && S.A(i,j+1)==c; findNeighbors(i,j+1,c), end
    if i<rows    && S.A(i+1,j)==c; findNeighbors(i+1,j,c), end
    if j>1       && S.A(i,j-1)==c; findNeighbors(i,j-1,c), end
  end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end % of blockBusterGUI and nested functions



Contact us at files@mathworks.com