Code covered by the BSD License  

Highlights from
MATLAB Hexxagon

image thumbnail
from MATLAB Hexxagon by Per-Anders Ekstrom
Graphical User Interface for playing the Ataxx clone Hexxagon.

hexxagon
function hexxagon
%HEXXAGON  Graphical User Interface for playing the Ataxx clone Hexxagon.
%   Hexxagon is an abstract strategy board game which involves play by two
%   parties on a hexagonal board. The object of the game is to make your
%   pieces constitute a majority of the pieces on the board at the end of
%   the game, by converting as many of your opponent's pieces as possible.
%
%   Each player begins with three pieces for the first player and second
%   player respectively. The game starts with the six pieces on the six
%   corners of the board.
%
%   During their turn players must first select the piece they wish to
%   move, the source, and then select an empty square, the destination,
%   that is either adjacent to, or having a distance of less than three,
%   from the source. Diagonal distances are equivalent to orthogonal
%   distances, i.e. it is legal move to a square who's relative position
%   is two squares away both vertically and horizontally. If the
%   destination is adjacent to the source, a new piece is created on the
%   empty destination square. Otherwise the piece on the source moves to
%   the destination. After the move, all of the opponent player's pieces
%   adjacent to the destination piece are converted to the color of the
%   moving player. Players must move unless no legal move is possible,
%   in which case they must pass.
%
%   The game ends when all positions of the board have been filled or one
%   of the players has no remaining pieces. The player with the most
%   pieces wins. A draw may occur when the number of squares are even.
%
%   (text above has been adapted from Wikipedia)
%
%   Hexxagon has single and double player modes, score tracking and sound
%   effects.
%
%   Example:
%       hexxagon    % Start Hexxagon Interface
%

%   Developed by Per-Anders Ekstrm, 2003-2007 Facilia AB.

playerColor = [1,0.6,0.6;0.6,0.6,1];
yellow  = [1,1,0];
green   = [0,1,0];
gray    = [0.8,0.8,0.8];
turn    = 0;
soundOn = true;
playerChangeSound = @()soundsc(sin(0:302),12522);
patchClickSound   = @()soundsc(sin(0:30),14555);
movedSound        = @()soundsc(cos(2:32),3425);
killSound         = @()soundsc(cos(2:32),4425);
twoPlayerOn = false;
run = false;
selected = 0;
animatedPatch = [];
playerText = [0,0];
createFigure()
pBit = resetPlyBit();
bjBit = createBoardJumpBit();
handle = drawBoard();
rulesText  = addRulesText();
menuText  = addMenuText();
turnText  = addTurnText();
scoreText = addScoreText();
soundButton = addSoundButton();
set(gcf,'ResizeFcn',@resizeWindow)
resetGame()
createMenu()
resizeWindow(gcf)

    function createFigure()
        scrsz = get(0,'ScreenSize');
        % Initialize figure window
        figure('Name','Hexxagon',...
            'Numbertitle','off',...
            'Menubar','none',...
            'DoubleBuffer','on',...
            'Color',[.95 .95 .95],...
            'ResizeFcn','', ...
            'Position',[(scrsz(3)-450)/2 (scrsz(4)-450)/2 450 450]);
    end
    function createMenu()
        set([rulesText,menuText,turnText,scoreText],'visible','off')
        v = axis;
        drawnow
        patch([v(1),v(2),v(2),v(1),v(1)],[v(3),v(3),v(4),v(4),v(3)],...
            [1 1 1],'FaceAlpha',.6,'tag','menu');
        text(sum(v(1:2))/2.1*0.99,sum(v(3:4))/2*0.99,'Hexxagon',...
            'Horizontalalignment','center','FontSize',55,...
            'FontUnits','Normalized',...
            'FontName','FixedWidth','Color',[.6,.6,.6],...
            'FontWeight','bold','tag','menu');
        text(sum(v(1:2))/2.1,sum(v(3:4))/2,'Hexxagon',...
            'Horizontalalignment','center','FontSize',55,...
            'FontUnits','Normalized',...
            'FontName','FixedWidth','FontWeight','bold','tag','menu');
        playerText(1)=text(sum(v(1:2))/2,sum(v(3:4))/3*1.12,...
            ' Human Vs. Computer ','Verticalalignment','bottom',...
            'Horizontalalignment','left','FontSize',8,...
            'EdgeColor','black','FontUnits','Normalized',...
            'FontWeight','bold','BackgroundColor',[.9 .9 .9],...
            'ButtonDownFcn',{@changeNumberOfPlayer,false},'tag','menu');
        playerText(2)=text(sum(v(1:2))/2.1,sum(v(3:4))/3*1.12,...
            ' Human Vs. Human ','Verticalalignment','bottom',...
            'Horizontalalignment','right','FontSize',8,...
            'EdgeColor','black','FontUnits','Normalized',...
            'FontWeight','bold','BackgroundColor',[.9 .9 .9],...
            'ButtonDownFcn',{@changeNumberOfPlayer,true},'tag','menu');
        set(playerText(twoPlayerOn+1),'EdgeColor','red',...
            'BackgroundColor',[1 .9 .9],'LineWidth',1.5)
        text(sum(v(1:2))/2.1,sum(v(3:4))/3,' START GAME ',...
            'Verticalalignment','top','Horizontalalignment','center',...
            'FontSize',8,'FontWeight','bold','Color','white',...
            'FontUnits','Normalized',...
            'BackgroundColor',[1 .5 .5],'EdgeColor','black',...
            'ButtonDownFcn',@startGame,'tag','menu');
    end
    function handle = drawBoard()
        patch([-1 9 9 -1 -1],[0 0 12 12 0],[1 1 1],...
            'FaceColor',[.97,.97,.97]);
        x = 1.1*[repmat(0,1,5),repmat(0.745,1,6),repmat(1.49,1,7),...
            repmat(2.235,1,7),repmat(2.98,1,8),repmat(3.725,1,7),...
            repmat(4.47,1,7),repmat(5.215,1,6),repmat(5.96,1,5)];
        y = -.1+1.1*[7 6 5 4 3 7.5 6.5 5.5 4.5 3.5 2.5 8 7 6 5 4 3 2 ...
            8.5 7.5 6.5 5.5 3.5 2.5 1.5 9 8 7 5 4 3 2 1 8.5 7.5 6.5 5.5 ...
            3.5 2.5 1.5 8 7 6 5 4 3 2 7.5 6.5 5.5 4.5 3.5 2.5 7 6 5 4 3];
        createPolygonAt = @(i,j)patch([0,0.255,0.745,1,0.745,0.255,0]+i,...
            [0.5,0,0,0.5,1,1,0.5]+j,[1 1 1],'Visible','off');
        % ARRAYFUN not used for backward compatibility
        %handle = arrayfun(@(i)createPolygonAt(x(i),y(i)),1:58);
        handle = zeros(1,58);
        for i=1:58
            handle(i) = createPolygonAt(x(i),y(i));
        end
        set(handle,'ButtonDownFcn',@patchButtonDownFcn,'Visible','on');
        animatedPatch = createPolygonAt(-1,-1);
        axis square
        axis off
        set(gca,'Units','Pixels','DrawMode','fast',...
            'XLim',[-1 9],'YLim',[0 12])

    end
    function button = addSoundButton()
        button = uicontrol('style','pushbutton','CData',getSoundCData(),...
            'Callback',@changeSound);
    end
    function txt = addRulesText()
        txt = text(1,1,'Rules','Color',[1 1 1],'Units','Pixels',...
            'BackgroundColor',gray,'FontWeight','bold',...
            'EdgeColor','black','Margin',5,'Horizontalalignment','left',...
            'Verticalalignment','top','visible','on',...
            'ButtonDownFcn',@showRules,'visible','off');
    end
    function txt = addMenuText()
        txt = text(1,1,'Menu','Color',[1 1 1],'Units','Pixels',...
            'BackgroundColor',gray,'FontWeight','bold',...
            'EdgeColor','black','Margin',5,'Horizontalalignment','left',...
            'Verticalalignment','top','visible','on',...
            'ButtonDownFcn',@quitGame,'visible','off');
    end
    function txt = addTurnText()
        txt = text(10,10,['Player ' num2str(turn+1)],'Color',[1 1 1],...
            'Units','Pixels','BackgroundColor',playerColor(1,:),...
            'FontWeight','bold','EdgeColor','black','Margin',5,...
            'Horizontalalignment','left','Verticalalignment','bottom',...
            'visible','off');
    end
    function txt = addScoreText()
        v = axis;
        txt(1) = text(v(2),0,'3','Color',[1 1 1],'Units','Pixels',...
            'BackgroundColor',playerColor(1,:),'FontWeight','bold',...
            'EdgeColor','black','Horizontalalignment','right',...
            'Verticalalignment','top','visible','off');
        txt(2) = text(v(2),v(4),'3','Color',[1 1 1],'Units','Pixels',...
            'BackgroundColor',playerColor(2,:),'FontWeight','bold',...
            'EdgeColor','black','Horizontalalignment','right',...
            'Verticalalignment','bottom','visible','off');
    end
    function resetGame()
        run = false;
        turn = 1;
        selected = 0;
        changeTurn()
        set(animatedPatch,'Visible','off')
        pBit = resetPlyBit();
        updateScoreText()
        set(handle,'FaceColor',gray);
        set(handle(1==(bitget(pBit(1),1:58))),...
            'FaceColor',playerColor(1,:));
        set(handle(1==(bitget(pBit(2),1:58))),...
            'FaceColor',playerColor(2,:));
        delete(findall(gca,'Type','line')) % clear all selected
    end
    function pBit = resetPlyBit()
        pBit = uint64([0,0]);
        pBit(1) = bitset(pBit(1),1);
        pBit(1) = bitset(pBit(1),33);
        pBit(1) = bitset(pBit(1),54);
        pBit(2) = bitset(pBit(2),5);
        pBit(2) = bitset(pBit(2),26);
        pBit(2) = bitset(pBit(2),58);
    end
    function showRules(varargin)
        helpdlg(help(mfilename),'Hexxagon Rules')
    end
    function changeSound(varargin)
        soundOn = ~soundOn;
        set(soundButton,'CData',getSoundCData())
    end
    function changeNumberOfPlayer(varargin)
        if nargin==3&&varargin{3}~=twoPlayerOn
            twoPlayerOn = ~twoPlayerOn;
            set(playerText(twoPlayerOn+1),'EdgeColor','red',...
                'BackgroundColor',[1 .9 .9],'LineWidth',1.5)
            set(playerText(~twoPlayerOn+1),'EdgeColor','black',...
                'BackgroundColor',[.9 .9 .9],'LineWidth',.5)
            if soundOn
                playerChangeSound()
            end
        end
    end
    function quitGame(varargin)
        answer = 'Yes';
        if run
            answer = questdlg(...
                'Do you really want to end the current game?', ...
                'Hexxagon Quit', ...
                'Yes', 'No','No');
        end
        switch answer,
            case 'Yes',
                resetGame()
                set(findall(gcf,'tag','menu'),'Visible','on')
                set([rulesText,menuText,turnText,scoreText],...
                    'visible','off')
            case 'No',
        end % switch
    end
    function startGame(varargin)
        set(findall(gcf,'tag','menu'),'Visible','off')
        set([rulesText,menuText,turnText,scoreText],'visible','on')
        run = true;
    end

    function patchButtonDownFcn(varargin)
        if run&&(twoPlayerOn||(~twoPlayerOn&&~turn))
            ind = find(varargin{1}==handle);
            if bitget(pBit(turn+1),ind) % this turn players pos
                if soundOn
                    patchClickSound()
                end
                delete(findall(gca,'Type','line')) % clear all selected
                if selected==ind
                    selected = 0;
                else
                    selected = ind;
                    patchborder = @(h,color)line(get(h,'XData'),...
                        get(h,'YData'),'Color',color,'Linewidth',3);
                    patchborder(handle(ind),yellow)
                    empty_bit = bitand(bitnot(pBit(1)),bitnot(pBit(2)));
                    % ARRAYFUN not used for backward compatibility
                    % arrayfun(@(x)patchborder(handle(x),green),...
                    %    find(bitget(bitand(bjBit(1,ind),empty_bit),1:58)))
                    % arrayfun(@(x)patchborder(handle(x),yellow),...
                    %    find(bitget(bitand(bjBit(2,ind),empty_bit),1:58)))
                    greenpos = find(bitget(bitand(bjBit(1,ind),...
                        empty_bit),1:58));
                    for i=1:length(greenpos)
                        patchborder(handle(greenpos(i)),green)
                    end
                    yellowpos = find(bitget(bitand(bjBit(2,ind),...
                        empty_bit),1:58));
                    for i=1:length(yellowpos)
                        patchborder(handle(yellowpos(i)),yellow)
                    end
                end
            elseif ~bitget(pBit(~turn+1),ind) % no-ones pos
                if selected
                    if soundOn
                        patchClickSound()
                    end
                    if any(find(bitget(bjBit(1,selected),1:58))==ind)
                        move(selected,ind)
                    elseif any(find(bitget(bjBit(2,selected),1:58))==ind)
                        move(selected,ind)
                    end
                end
            end
        end
    end
    function move(from,to)
        if bitget(bjBit(2,from),to)==1 % if it is a jump
            set(handle(from),'FaceColor',gray)
            pBit = bitset(pBit(:),from,0);
        end
        delete(findall(gca,'Type','line'))
        selected = 0;
        n = 20;
        fromXData = get(handle(from),'XData');
        fromYData = get(handle(from),'YData');
        toXData = get(handle(to),'XData');
        toYData = get(handle(to),'YData');
        set(animatedPatch,'XData',fromXData,'YData',fromYData,...
            'Visible','on','FaceColor',playerColor(turn+1,:))
        pathX = linspace(0,toXData(1)-fromXData(1),n);
        pathY = linspace(0,toYData(1)-fromYData(1),n);
        for i=1:n
            t0 = clock;
            set(animatedPatch,'XData',fromXData+pathX(i),...
                'YData',fromYData+pathY(i))
            while etime(clock,t0)<1/(6*n)
                drawnow
            end
        end
        if soundOn
            movedSound()
        end
        set(handle(to),'FaceColor',playerColor(turn+1,:))

        pBit(turn+1) = bitset(pBit(turn+1),to);
        pBit(~turn+1) = bitset(pBit(~turn+1),to,0);
        kill = find(bitget(bitand(bjBit(1,to),pBit(~turn+1)),1:58));
        for i=1:length(kill)
            if soundOn
                pause(.1)
                killSound()
            end
            set(handle(kill(i)),'FaceColor',playerColor(turn+1,:))

            pBit(turn+1) = bitset(pBit(turn+1),kill(i));
            pBit(~turn+1) = bitset(pBit(~turn+1),kill(i),0);
        end
        set(animatedPatch,'XData',[-22 -24 -26],'YData',[-22 -22 -26],...
            'Visible','off')
        drawnow
        changeTurn()
    end
    function changeTurn(varargin)
        turn = ~turn;
        set(turnText,'String',['Player ' num2str(turn+1)],...
            'BackgroundColor',playerColor(turn+1,:))
        updateScoreText()
        if run&&isempty(find(bitget(bitand(bitnot(pBit(1)),...
                bitnot(pBit(2))),1:58)==1,1))
            pl1 = sum(bitget(pBit(1),1:58)==1);
            pl2 = sum(bitget(pBit(2),1:58)==1);
            if pl1>pl2
                str = sprintf('Player 1 WINS!\n%d against %d points',...
                    pl1,pl2);
            elseif pl2>pl1
                if twoPlayerOn
                    str = sprintf('Player 2 WINS!\n%d against %d points',...
                        pl2,pl1);
                else
                    str = sprintf('Computer WINS!\n%d against %d points',...
                        pl2,pl1);
                end
            else
                str = sprintf('DRAW!\n%d-%d',pl1,pl2);
            end
            msgbox(str,'Hexxagon Winner')
            run = false;
            return
        elseif run&&~canMove()
            changeTurn()
        elseif run&&~twoPlayerOn&&turn
            computerMove();
        end
    end
    function status = canMove()
        status = false;
        empty_bit = bitand(bitnot(pBit(1)),bitnot(pBit(2)));
        positions = find(bitget(pBit(turn+1),1:58)==1);
        for i=1:length(positions)
            if ~isempty(find(bitget(bitand(bjBit(1,positions(i)),...
                    empty_bit),1:58)==1,1))
                status = true;
                return
            end
            if ~isempty(find(bitget(bitand(bjBit(2,positions(i)),...
                    empty_bit),1:58)==1,1))
                status = true;
                return
            end
        end
    end
    function computerMove()
        empty_bit = bitand(bitnot(pBit(1)),bitnot(pBit(2)));
        positions = find(bitget(pBit(2),1:58)==1);
        bestpos = 0;
        bestmove = 0;
        bestscore = 0;
        for i=1:length(positions)
            freesinglespots = find(bitget(bitand(bjBit(1,...
                positions(i)),empty_bit),1:58)==1);
            for j=1:length(freesinglespots)
                kills = length(find(bitget(bitand(bjBit(1,...
                    freesinglespots(j)),pBit(1)),1:58)))+1;
                if kills>=bestscore+rand-.5
                    bestpos = positions(i);
                    bestmove = freesinglespots(j);
                    bestscore = kills;
                end
            end
        end
        for i=1:length(positions)
            freedoublespots = find(bitget(bitand(bjBit(2,...
                positions(i)),empty_bit),1:58)==1);
            for j=1:length(freedoublespots)
                kills = -1+length(find(bitget(bitand(bjBit(1,...
                    freedoublespots(j)),pBit(1)),1:58)));
                if kills>=bestscore+rand-.5
                    bestpos = positions(i);
                    bestmove = freedoublespots(j);
                    bestscore = kills;
                end
            end
        end
        if bestscore>0
            move(bestpos,bestmove)
        else
            changeTurn()
        end
    end
    function updateScoreText()
        score = @(player)sum(bitget(pBit(player),1:58)==1);
        setText = @(player,score)set(scoreText(player),...
            'String',[repmat(' ',1,score-3-(score>9)),num2str(score)]);
        setText(1,score(1))
        setText(2,score(2))
    end
    function newbit = bitnot(bit)%since bitcmp doesn't work on 64 bits uint
        truthpos = find(~bitget(bit,1:58));
        newbit = uint64(0);
        for i=1:length(truthpos)
            newbit = bitset(newbit,truthpos(i));
        end
    end
    function bjBit = createBoardJumpBit()
        singles = {[2 6 7],[1 3 7 8],[2 4 8 9],[3 5 9 10],[4 10 11],...
            [1 7 12 13],[1 2 6 8 13 14],[2 3 7 9 14 15],...
            [3 4 8 10 15 16],[4 5 9 11 16 17],[5 10 17 18],[6 13 19 20],...
            [6 7 12 14 20 21],[7 8 13 15 21 22],[8 9 14 16 22],...
            [9 10 15 17 23],[10 11 16 18 23 24],[11 17 24 25],...
            [12 20 26 27],[12 13 19 21 27 28],[13 14 20 22 28],...
            [14 15 21 29],[16 17 24 30 31],[17 18 23 25 31 32],...
            [18 24 32 33],[19 27 34],[19 20 26 28 34 35],...
            [20 21 27 35 36],[22 30 37],[23 29 31 38],...
            [23 24 30 32 38 39],[24 25 31 33 39 40],[25 32 40],...
            [26 27 35 41],[27 28 34 36 41 42],[28 35 37 42 43],...
            [29 36 43 44],[30 31 39 45 46],[31 32 38 40 46 47],...
            [32 33 39 47],[34 35 42 48],[35 36 41 43 48 49],...
            [36 37 42 44 49 50],[37 43 45 50 51],[38 44 46 51 52],...
            [38 39 45 47 52 53],[39 40 46 53],[41 42 49 54],...
            [42 43 48 50 54 55],[43 44 49 51 55 56],[44 45 50 52 56 57],...
            [45 46 51 53 57 58],[46 47 52 58],[48 49 55],[49 50 54 56],...
            [50 51 55 57],[51 52 56 58],[52 53 57]};
        doubles = { [3 8 14 13 12],[6 13 14 15 9 4],[1 7 14 15 16 10 5],...
            [2 8 15 16 17 11],[3 9 16 17 18],[19 20 21 14 8 2],...
            [12 20 21 22 15 9 3],[1 6 13 21 22 16 10 4],...
            [2 7 14 22 23 17 11 5],[3 8 15 23 24 18],[4 9 16 23 24 25],...
            [26 27 28 21 14 7 1],[19 27 28 22 15 8 2 1],...
            [1 6 12 20 28 29 16 9 3 2],[23 17 10 4 3 2 7 13 21],...
            [30 31 24 18 11 5 4 3 8 14 22],[30 31 32 25 5 4 9 15],...
            [5 10 16 23 31 32 33],[34 35 28 21 13 6],...
            [26 34 35 36 22 14 7 6],[19 27 35 36 29 15 8 7 6 12],...
            [20 28 37 30 16 9 8 7 13],[29 38 39 32 25 18 11 10 9 15],...
            [30 38 39 40 33 11 10 16],[11 17 23 31 39 40],...
            [41 35 28 20 12],[41 42 36 21 13 12],...
            [26 34 41 42 43 37 22 14 13 12 19],...
            [36 43 44 38 31 23 15 14 21],[22 37 45 46 39 32 24 17 16],...
            [29 45 46 47 40 33 25 18 17 16],[30 38 46 47 18 17 23],...
            [18 24 31 39 47],[19 20 28 36 42 48],...
            [26 19 20 21 37 43 49 48],[29 21 20 27 34 41 48 49 50 44],...
            [30 22 28 35 42 49 50 51 45],...
            [29 44 51 52 53 47 40 32 24 23],[45 52 53 33 25 24 23 30],...
            [25 24 31 38 46 53],[26 27 28 36 43 49 54],...
            [34 27 28 37 44 50 55 54],[54 48 41 35 28 29 45 51 56 55],...
            [36 42 49 56 57 52 46 38 29],...
            [37 43 50 56 57 58 53 47 39 31 30],...
            [44 51 57 58 40 32 31 30],[58 52 45 38 31 32 33],...
            [34 35 36 43 50 55],[41 35 36 37 44 51 56],...
            [54 48 42 36 37 45 52 57],[55 49 43 37 38 46 53 58],...
            [56 50 44 38 39 47],[57 51 45 38 39 40],[41 42 43 50 56],...
            [48 42 43 44 51 57],[54 49 43 44 45 52 58],[55 50 44 45 53],...
            [56 51 45 46 47]};
        bjBit = uint64(zeros(2,58));
        for ii=1:58
            single = singles{ii};
            for jj=1:length(single)
                bjBit(1,ii) = bitset(bjBit(1,ii),single(jj));
            end
            double = doubles{ii};
            for jj=1:length(double)
                bjBit(2,ii) = bitset(bjBit(2,ii),double(jj));
            end
        end
    end
    function CData = getSoundCData()
        CData = [...
            0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0;
            0 0 0 0 0 0 1 1 0 0 0 1 1 0 0 0;
            0 0 0 0 0 1 1 1 0 0 0 0 0 1 0 0;
            0 0 0 0 1 1 1 1 0 0 1 0 0 1 0 0;
            0 0 0 1 1 1 1 1 0 0 0 1 0 0 1 0;
            0 0 1 1 1 1 1 1 0 1 0 0 1 0 1 0;
            1 1 1 1 1 1 1 1 0 0 1 0 1 0 1 0;
            1 1 1 1 1 1 1 1 0 0 1 0 1 0 1 0;
            1 1 1 1 1 1 1 1 0 0 1 0 1 0 1 0;
            1 1 1 1 1 1 1 1 0 0 1 0 1 0 1 0;
            0 0 1 1 1 1 1 1 0 1 0 0 1 0 1 0;
            0 0 0 1 1 1 1 1 0 0 0 1 0 0 1 0;
            0 0 0 0 1 1 1 1 0 0 1 0 0 1 0 0;
            0 0 0 0 0 1 1 1 0 0 0 0 0 1 0 0;
            0 0 0 0 0 0 1 1 0 0 0 1 1 0 0 0;
            0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0];
        if ~soundOn
            CData(:,9:end)=0;
        end
        CData = repmat(CData,[1 1 3]);
        CData(CData==1)=.7;
        CData(CData==0)=.97;
    end
    function resizeWindow(varargin)
        posf = get(varargin{1}, 'Position');
        posf(3:4) = max(min(posf(3:4)),350);
        set(varargin{1},'Position',posf);
        set(menuText,'Position',[7,posf(4)-24])
        set(rulesText,'Position',[54,posf(4)-24])
        set(soundButton,'Position',[85,16,16,16])
        set(turnText,'Position',[7,8])
        set(scoreText(1),'Position',[posf(3)-21,posf(4)-20])
        set(scoreText(2),'Position',[posf(3)-21,4])
        set(gca, 'Position',[10 10 posf(3)-21 posf(4)-21])
    end
end

Contact us at files@mathworks.com