Code covered by the BSD License  

Highlights from
Numeric Keypad Maze

image thumbnail
from Numeric Keypad Maze by Per-Anders Ekstrom
GUI for playing the Numeric Keypad Maze game

numpadmaze(cmd)
function numpadmaze(cmd)
%NUMPADMAZE  GUI for playing the Numeric Keypad Maze game.
% In this game you will use the numeric keypad. Num Lock should be active
% before you start. You have to find your way to the maze's exit by
% pressing the right keys. You have to press the number in the square where
% you want to move. The player can only move up, down, left and right. If
% you get stuck, the game ends.
% The game consist of five different mazes which are created randomly. The
% game gets harder for each level, first level has 0-5 as options and the
% fifth level has 0-9 as options. The goal is to get to the exit as quick
% as possible with the least amount of keypresses.
% Every wrong keypress counts as three keypresses.
% You have 60 seconds and 100 keypresses on you to get to the exit of each
% maze. The score that is counted at the end is the sum of remaining
% seconds and remaining keypresses. At the end of the fifth maze you can
% your score is saved if it beats the highscore. Improve your results and
% be the numeric keypad master!
%
% Idea and text taken from <a href="http://www.platinagames.com/game5.html">http://www.platinagames.com</a>
%
% Example:
%   numpadmaze             % Start the Numeric Keypad Maze Game

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

if ~nargin
    eval([mfilename,'(''init'')'])
    return;
end
if ~(ischar(cmd)||isscalar(cmd))
    return;
end

switch cmd
    case 'init'
        scrsz = get(0,'ScreenSize');
        hFigure = figure( ...
            'Name','Numeric Keypad Maze', ...
            'Menubar','none',...
            'NumberTitle','off', ...
            'KeyPressFcn',[mfilename,'(double(get(gcbf,''Currentcharacter'')))'], ...
            'Units','pixels', ...
            'Position',[(scrsz(3)-780)/2 (scrsz(4)-400)/2 780 400], ...
            'Color',[.95 .95 .95], ...
            'Colormap',[1 1 1;[0.2 0.3 0.5]], ...
            'Visible','on', ...
            'CloseRequestFcn',@closeRequestFcn);
        FileMenu = uimenu(hFigure,'Label','File');
        uimenu(FileMenu,'Label','New Game','Accelerator','N',...
            'Callback',[mfilename,'(''NewGame'')']);
        uimenu(FileMenu,'Label','Exit','Accelerator','Q',...
            'Separator','on','Callback',@closeRequestFcn);
        HelpMenu = uimenu(hFigure,'Label','Help');
        uimenu(HelpMenu,'Label','Help','Accelerator','H',...
            'Callback',['helpwin ',mfilename]);
        uimenu(HelpMenu,'Label','About',...
            'Callback',[mfilename,'(''About'')'],'Separator','on');
        setappdata(hFigure,'axes',axes( ...
            'Parent',hFigure, ...
            'Units','normalized', ...
            'Position',[-.05 0 1.05 1]));
        setappdata(hFigure,'surface',surface( ...
            zeros(11,20),zeros(10,19), ...
            'Parent',gca, ...
            'EdgeColor',[0.6,0.6,0.6], ...
            'LineWidth',1));
        axis off
        hold on
        patch([4.5,4.5,16.5,16.5,4.5],[10.5,10.9,10.9,10.5,10.5],[1,1,1],...
            'EdgeColor',[0,0,0],'FaceAlpha',0.4)
        setappdata(hFigure,'HighScoreText',text('Position',[5,10.5],...
            'String','','FontUnits','Normalized',...
            'HorizontalAlignment','left',...
            'VerticalAlignment','bottom','Color',[0,0,0]))
        setappdata(hFigure,'MazeText',text('Position',[7.8,10.5],...
            'String','','FontUnits','Normalized',...
            'HorizontalAlignment','left',...
            'FontWeight','bold',...
            'VerticalAlignment','bottom','Color',[0,0,0]))
        setappdata(hFigure,'ScoreText',text('Position',[9.6,10.5],...
            'String','','FontUnits','Normalized',...
            'HorizontalAlignment','left',...
            'VerticalAlignment','bottom','Color',[0,0,0]))
        setappdata(hFigure,'TimeText',text('Position',[11.6,10.5],...
            'String','','FontUnits','Normalized',...
            'HorizontalAlignment','left',...
            'VerticalAlignment','bottom','Color',[0,0,0]))
        setappdata(hFigure,'KeyPressesText',text('Position',[13.4,10.5],...
            'String','','FontUnits','Normalized',...
            'HorizontalAlignment','left',...
            'VerticalAlignment','bottom','Color',[0,0,0]))
        setappdata(hFigure,'timer',...
            timer('TimerFcn',@timerFcn,'Period',1,...
            'ExecutionMode','FixedRate','UserData',hFigure))
        [X,Y] = pol2cart(linspace(0,2*pi,100),ones(1,100)*.3);
        setappdata(hFigure,'Xpos',X+0.5)
        setappdata(hFigure,'Ypos',Y+0.5)
        setappdata(hFigure,'positionpatch',patch(1,1,[1,0.3,0.3],...
            'EdgeColor',[0.6,0.6,0.6]*0.5))
        if exist([mfilename,'.highscore'],'file')
            try
                setappdata(hFigure,'HighScore',...
                    getfield(load([mfilename,'.highscore'],'-mat'),'highscore'))  %#ok<GFLD>
            catch
                setappdata(hFigure,'HighScore',0)
            end
        else
            setappdata(hFigure,'HighScore',0)
        end
        eval([mfilename,'(''NewGame'')'])

    case 'NewGame'
        setappdata(gcf,'level',5)
        createLevel(5)
        drawCurrentPosition()
        setappdata(gcf,'Maze',1)
        setappdata(gcf,'Score',0)
        setappdata(gcf,'Time',0)
        setappdata(gcf,'KeyPresses',0)
        updateText()
        stop(getappdata(gcf,'timer'));
        setappdata(gcf,'start',clock)
        start(getappdata(gcf,'timer'));

    case 'About'
        ico = ones(13)*3; % create simple icon matrix
        ico(:,1:4:13) = 1;
        ico(1:4:13,:) = 1;
        ico(2:4,10:12) = 2;
        ico(6:8,2:4) = 2;
        ico(10:12,10:12) = 2;
        map = [0 0 0;0.2 0.3 0.5;1 1 1];
        msgbox(sprintf([...
            'Graphical User Interface for playing the Numeric Keypad Maze game.\n\n'...
            'Developed by Per-Anders Ekstrm, 2003-2008 Facilia AB\n'...
            'E-mail: peranders.ekstrom@facilia.se']),...
            'About: Numeric Keypad Maze','custom',ico,map)

    case {48,49,50,51,52,53,54,55,56,57}
        if(strcmp(get(getappdata(gcf,'timer'),'Running'),'on'))
            if(getappdata(gcf,'KeyPresses')>=100)
                stop(getappdata(gcf,'timer'));
                msgbox(sprintf('Game Over, to many keypresses!\nPlease try again.'))
                return;
            end
            board = getappdata(gcf,'board');
            [i,j] = find(board==-1);
            iswitch = [-1 1 0 0];
            jswitch = [0 0 -1 1];
            for tmp=1:4
                iind = iswitch(tmp)+i;
                jind = jswitch(tmp)+j;
                if(jind>0 && board(iind,jind)==cmd-48)
                    board(i,j) = NaN;
                    board(iind,jind) = -1;
                    setappdata(gcf,'board',board)
                    delete(getappdata(gcf,['text',num2str(iind*19+jind)]))
                    setappdata(gcf,'KeyPresses',getappdata(gcf,'KeyPresses')+1)
                    updateText()
                    drawCurrentPosition()
                    if(jind==19)
                        ingoal()
                    end
                    return;
                end
            end
            setappdata(gcf,'KeyPresses',getappdata(gcf,'KeyPresses')+3)
            updateText()
            if(getappdata(gcf,'KeyPresses')>=100)
                stop(getappdata(gcf,'timer'));
                msgbox(sprintf('Game Over, to many keypresses!\nPlease try again.'))
                return;
            end
        end
end

function ingoal()
stop(getappdata(gcf,'timer'));
level = getappdata(gcf,'level')+1;
setappdata(gcf,'Score',getappdata(gcf,'Score')+...
    100-getappdata(gcf,'KeyPresses')+...
    60-getappdata(gcf,'Time'))
setappdata(gcf,'Time',0)
setappdata(gcf,'KeyPresses',0)
updateText()
if level<10
    setappdata(gcf,'Maze',level-4)
    setappdata(gcf,'level',level)
    createLevel(level)
    drawCurrentPosition()
    setappdata(gcf,'start',clock)
    start(getappdata(gcf,'timer'));
else
    score = getappdata(gcf,'Score');
    highscore = getappdata(gcf,'HighScore');
    if score>highscore
        highscore = score;
        try %#ok<TRYNC>
            save([mfilename,'.highscore'],'highscore')
        end
        setappdata(gcf,'HighScore',highscore);
        updateText()
        msgbox(sprintf('Congratulations, we have a new High Score!'))
    else
        msgbox(sprintf('You didn''t beat the High Score\n Please try again.'))
    end
end

function createLevel(level)
delete(findobj(gcf,'tag','text'))
board = getNewBoard(level);
set(getappdata(gcf,'surface'),'CData',isnan(board)+1)
setappdata(gcf,'board',board);
for i=2:9
    for j=1:19
        if ~(isnan(board(i,j))||board(i,j)==-1)
            setappdata(gcf,['text',num2str(i*19+j)],text( ...
                'Position',[j i]+.5, ...
                'String',board(i,j), ...
                'Color',[0.2 0.3 0.5], ...
                'FontSize',12,...
                'Tag','text',...
                'FontUnits','Normalized',...
                'HorizontalAlignment','center'))
        end
    end
end

function updateText()
set(getappdata(gcf,'HighScoreText'),'String',...
    sprintf('High Score: %d',getappdata(gcf,'HighScore')))
set(getappdata(gcf,'MazeText'),'String',...
    sprintf('Maze: %d',getappdata(gcf,'Maze')))
set(getappdata(gcf,'ScoreText'),'String',...
    sprintf('Score: %3d',getappdata(gcf,'Score')))
set(getappdata(gcf,'KeyPressesText'),'String',...
    sprintf('Keypresses: %3d',getappdata(gcf,'KeyPresses')))

function drawCurrentPosition()
board = getappdata(gcf,'board');
set(getappdata(gcf,'surface'),'CData',isnan(board)+1)
[i,j] = find(board==-1);
set(getappdata(gcf,'positionpatch'),...
    'XData',getappdata(gcf,'Xpos')+j,...
    'YData',getappdata(gcf,'Ypos')+i)

function timerFcn(varargin)
hFigure = get(varargin{1},'UserData');
setappdata(hFigure,'Time',floor(etime(clock,getappdata(hFigure,'start'))))
set(getappdata(hFigure,'TimeText'),...
    'String',sprintf('Time: %d',getappdata(hFigure,'Time')))
if(getappdata(hFigure,'Time')>=60)
    stop(getappdata(hFigure,'timer'));
    msgbox(sprintf('Game Over, time is up!\nPlease try again.'))
end


function closeRequestFcn(varargin)
htimer = getappdata(gcf,'timer');
% stop the timer
try %#ok<TRYNC>
    stop(htimer)
    delete(htimer)
end
% close the figure window
closereq

function board = getNewBoard(level)
levelrand = @()(ceil(rand*(level+1))-1);
board = zeros(10,19)-1;
board(2,2) = levelrand();
for i=3:9
    r = levelrand();
    while(board(i-2,2)==r)
        r = levelrand();
    end
    board(i,2) = r;
end
for j=3:19
    for i=2:9
        r = levelrand();
        while(isempty(setdiff(r,[board(i,j-2),board(i-1,j-1),...
                board(i+1,j-1),board(i-1,j),board(max(1,i-2),j)])))
            r = levelrand();
        end
        board(i,j) = r;
    end
end
endpos = 1:10;
endpos(ceil(8*rand)+1) = [];
board(endpos,19) = NaN;
board(:,1) = NaN;
board([1,10],:) = NaN;
for i=3:2:17
    bricks = randperm(8)+1;
    board(bricks(1:3),i) = NaN;
end
board(bricks(8),1) = -1;


Contact us at files@mathworks.com