Code covered by the BSD License  

Highlights from
Boggle (V2.0)

image thumbnail

Boggle (V2.0)

by

 

08 Aug 2011 (Updated )

The traditional Boggle Master Game from Hasbro

boggle
function boggle
%Function to make the boggle grid and run the show
%SCd 08/03/2011
%
%Version 2.0. Goals: make and display grid, rotate letters, store them,
%   insure words (including words with 'qu'), new game, some useful
%   warnings, scores, delete words by clicking them, timed game with
%   editable times, add minutes when seconds exceed 60.
%
%Goals for future versions: game IDs, rotate whole grid, optional draw path,
%   store results and load results so you can play against others and compare,
%   better description of how to play, draw 'u' on the Q
%
%Usage:
%    -Just call >>boggle it is self contained from there
%
%For Rules See:
%  web('http://en.wikipedia.org/wiki/Boggle','-browser');
%

    %Make the figure and its stuff
    rand('twister',sum(clock)); %randomize
    bgcol = [0.8 0.8 0.8]; %background color
    H.fig = figure('units','pix','position',[300 300 900 450],'keyreleasefcn',@krfun ,...
        'resize','off','name','Boggle!','menubar','none','numbertitle','off'); 
    H.imax = axes('units','pix','position',[200 60 380 380],'xtick',[],'ytick',[]); %image axis
    H.wdbx = uicontrol('style','listbox','units','pix','position',[10 60 150 350],...
        'backgroundcolor','w','selected','off','callback',@delete_word);
    uicontrol('style','text','string','Word Bank','units','pix',...
        'position',[35 410 100 30],'backgroundcolor',bgcol);
    uipanel('units','pix','position',[620 10 250 200],'title','Settings:','backgroundcolor',bgcol);
    H.wmsg = uicontrol('style','text','string',[],'units','pix',...
        'position',[10 10 250 30],'backgroundcolor',bgcol,'foregroundcolor','r',...
        'fontunits','pix','fontsize',15);
    H.cwbx = uicontrol('style','text','string',[],'units','pix',...
        'position',[300 10 250 40],'fontunits','pix','fontsize',40);    
    H.rotbx = uicontrol('style','check','string','    Allow Letters to Be Rotated',...
        'units','pix','position',[630,120,220,20]);
    H.min_lenbx = uicontrol('units','pix','style','edit','position',[630 155 40 30],...
        'string','4','callback',@valid_min_len,'backgroundcolor','w');
    uicontrol('style','text','string','Minimum Word Length','units','pix',...
        'position',[675 145 150 30],'backgroundcolor',bgcol);
    H.newg = uicontrol('style','push','units','pix','string','New Game!','position',...
        [700 220 100 40],'callback',@newGame);
    H.timed = uicontrol('units','pix','style','check','position',[630 85 240 30],...
        'callback',@timed_game,'backgroundcolor','w','string','    Timed Game','value',false);
    H.tminbx = uicontrol('units','pix','style','edit','position',[630 55 40 30],...
        'string','4','callback',@valid_time,'backgroundcolor','w','enable','off');
    H.tsecbx = uicontrol('units','pix','style','edit','position',[730 55 40 30],...
        'string','0','callback',@valid_time,'backgroundcolor','w','enable','off');
    uicontrol('style','text','string','minutes','units','pix',...
        'position',[670 47 50 30],'backgroundcolor',bgcol);
    uicontrol('style','text','string','seconds','units','pix',...
        'position',[770 47 55 30],'backgroundcolor',bgcol);
    H.time_left = uicontrol('style','text','string','Time Remaining: ','units','pix',...
        'position',[600 400 205 30],'backgroundcolor',bgcol,'visible','off');  
        
    %Start your engine!
    newGame;
    
    function newGame(~,~)
        old_timers = timerfind('tag','T');
        if ~isempty(old_timers)
            set(old_timers(:),'stopfcn',''); %Change the stopfcn so no time elasped window is displayed
            stop(old_timers)
            delete(old_timers);
        end
        %New Game
        G = makeGrid;
        imshow(gridImage(G,get(H.rotbx,'value')));
        set(H.fig,'userdata',G);
        set(H.wmsg,'string',[]); %Get rid of warning
        set(H.wdbx,'string',{'Score: 0'},'value',1);
        set(H.newg,'userdata',true);
        set(H.cwbx,'string',[]);
        
        %Is the game timed?
        if get(H.timed,'value')
            tmin = str2double(get(H.tminbx,'string'));
            tsec = str2double(get(H.tsecbx,'string'));
            T = timer('ExecutionMode','fixedrate','Period',1,...
                'timerfcn',{@update_time,tmin,tsec},'taskstoexecute',tmin*60+tsec,...
                'tag','T','stopfcn','warndlg(''Time Has Elapsed!'');');
            start(T);
        end
        
        %Fancy way to deactivate button: (Thank you Jan!)
        set(H.newg, 'Enable', 'off');
        drawnow;
        set(H.newg, 'Enable', 'on');

    end

    function krfun(~,event)
        %While typing!      
        persistent word G %score words
        
        %Was there a warning?
        if ~isempty(get(H.wmsg,'string'));
            set(H.wmsg,'string',[]); %Get rid of it
        end
        
        if get(H.newg, 'userdata');
            %retrieve and unpack game parts
            G = get(H.fig,'userdata');
            word = [];
            set(H.newg,'userdata',false);
        end
        
        %Handle new stuff
        if strcmp(event.Key,'return')
            %New word entered
            [bool, ~] = insureWord(G,word); %see if it's actually a word
            if bool
                %It was!  
                if length(word)<str2double(get(H.min_lenbx,'string'))
                    %Too short 
                    set(H.wmsg,'string',sprintf('Word: %s, is too short',word))
                
                elseif ismember(word,get(H.wdbx,'string'))
                     %Already have it
                     set(H.wmsg,'string',sprintf('Word: %s, is already present',word))
                
                else    
                    %Add to box
                    words = get(H.wdbx,'string');
                    words2score = [words(1:end-1);{word}];
                    words = score_it(words2score);
                    set(H.wdbx,'string',words,'value',length(words)); 
                
                end
            else
                %Nope
                set(H.wmsg,'string',sprintf('Word: %s, not present :(',word))
            end    
            word = []; %clear word
            
        elseif strcmp(event.Key,'backspace')
            %Backspace
            word = word(1:end-1);
            
        elseif any(ismember(event.Key,'a':'z'))&&isscalar(event.Key);
            %They entered a letter, add it
            word = [word upper(event.Key)];
            
        elseif strcmp(event.Key,'uparrow')
            %Up arrow pulls up last word 
            words = get(H.wdbx,'string');
            if length(words)>1 %there's already a word
                word = words{end-1};
            end
       
        end % else?  ohwell do nothing
        set(H.cwbx,'string',word);
    end

    function valid_min_len(~,~)
        %Insure minimum length is a number
        minlen = str2double(get(H.min_lenbx,'string'));
        if isnan(minlen)||~isnumeric(minlen)||minlen<1
            set(H.min_lenbx,'string',4);
        end
    end

    function delete_word(~,~)
        idx = get(H.wdbx,'value');
        len = length(get(H.wdbx,'string'));
        if idx~=len
            words = get(H.wdbx,'string');
            words(idx) = [];
            words = score_it(words(1:end-1));
            set(H.wdbx,'string',words);
            set(H.wdbx,'value',len-1);
        end    
        set(H.wdbx, 'Enable', 'off');
        drawnow;
        set(H.wdbx, 'Enable', 'on');
    end

    function timed_game(~,~)
        if get(H.timed,'value')
            set(H.tminbx,'enable','on');
            set(H.tsecbx,'enable','on');
            set(H.time_left,'visible','on');
            set(H.time_left,'string',...
                sprintf('Time Remaining: %s min, %s sec',get(H.tminbx,'string'),get(H.tsecbx,'string')));
            %other stuff for a timed game
        else
            set(H.tminbx,'enable','off');
            set(H.tsecbx,'enable','off');
            set(H.time_left,'visible','off');
            %other stuff for an untimed game
        end    
    end 

    function valid_time(src,~)
        %Insure time is a valid number
        time = str2double(get(src,'string'));
        if isnan(time)||~isnumeric(time)||time<0
            if src==H.tminbx %minutes
                set(src,'string',4);
            else %seconds
                set(src,'string',0);
            end
        end
        %Do we need to add minutes and subtract seconds?
        secs = str2double(get(H.tsecbx,'string'));
        if secs >= 60
            set(H.tsecbx,'string',rem(secs,60));
            set(H.tminbx,'string',str2double(get(H.tminbx,'string'))+floor(secs/60));
        end    
    end   

    function update_time(src,~,mins,secs)
        TasksExecuted = get(src,'tasksexecuted');
        t_tot = mins*60+secs;
        t_tot = t_tot-TasksExecuted;
        mins = floor(t_tot/60);
        secs = rem(t_tot,60);
        set(H.time_left,'string',...
            sprintf('Time Remaining: %i min, %i sec',mins,secs));
    end
end
function words = score_it(words2score)
    %calculate score
    vals = [0 0 1 1 2 3 4 11]; %score values
    score = sum(vals(min(max(cellfun('prodofsize',words2score),1),8)));  %extract score
    words = vertcat(words2score,{sprintf('Score: %i',score)});

end

Contact us