Code covered by the BSD License  

Highlights from
Super Sudoku V2

image thumbnail
from Super Sudoku V2 by Yi Cao
New version of Super Sudoku with an updated solver.

superSudoku(varargin)
function varargout = superSudoku(varargin)
% SUPERSUDOKU M-file for superSudoku.fig
%      SUPERSUDOKU, by itself, creates a new SUPERSUDOKU or raises the existing
%      singleton.
%
%      SUPERSUDOKU(Puzzle) open the game with the specified puzzle. If the
%      board is open, the specified puzzle will be shown on the board. 
%      
% Four ways to play the game:
%      
%      1) Open with a puzzle as above, then start to play strightawy.
%      2) Open an empty board, then click "New Game" button. You can select
%         three different levels to generate a new puzzle or select a puzzle
%         from the supplied library.
%      3) Open an empty board, then manually set the puzzle by selecting 
%         both "Construct" and "on/off" checkboxes, and selecting one of the 
%         number buttons, then click a grid box, where you wish to put the number. 
%         Continue this process until all numbers are set. Finally, click 
%         "Verify Game" button to start the game.
%      4) Open an empty board, then load a puzzle from a file
%
% All verified new game will be automatically added into the library. You can also
% click "Save" button to save the current game to a separated file (no to the library).
%
% To play the game, de-select "Construct" checkbox, and select "on/off"
% checkboxes if you wish to put a number in a grid box, or de-select
% "on/off" checkboxes if you wish to remove a number from a grid box.
% At the end of game, click "Verify Solution" button to finish.
%
% During play, you can click "Undo" and "Redo" button to alter current
% solution, or click "Restart" button to restart the game.
%
% During the play, you can also get a hint by click "Hint Marks" button. Four 
% different hint levels are available: 
%      1) Direct Single
%      2) Indirect Single
%      3) Paire
%      4) Recursive
% Once you get some valid hint marks, you can either fix these marks make
% them become part of the solution or remove them by click "Fix Marks" and
% "Remove Marks" buttoms, respectively.
%
% by Yi Cao, Cranfield University, 13-Dec-2007
% Modified on 28-Dec-2007
%
% The origianl help created by GUIDE.
%
%      H = SUPERSUDOKU returns the handle to a new SUPERSUDOKU or the handle to
%      the existing singleton*.
%
%      SUPERSUDOKU('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in SUPERSUDOKU.M with the given input arguments.
%
%      SUPERSUDOKU('Property','Value',...) creates a new SUPERSUDOKU or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before superSudoku_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to superSudoku_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help superSudoku
% Last Modified by GUIDE v2.5 13-Dec-2007 22:49:23

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @superSudoku_OpeningFcn, ...
                   'gui_OutputFcn',  @superSudoku_OutputFcn, ...
                   'gui_LayoutFcn',  @superSudoku_LayoutFcn, ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
if nargin && isnumeric(varargin{1}) && numel(varargin{1})==81
    hSuperSudoku = getappdata(0, 'hSuperSudoku');
    Puzzle = reshape(double(varargin{1}),9,9);
    setappdata(hSuperSudoku, 'Puzzle', Puzzle);
    setappdata(hSuperSudoku, 'solution', Puzzle);
    setappdata(hSuperSudoku, 'currentHint', Puzzle);
    newmap(Puzzle);
    verifyGame_Callback; 
end


% --- Executes just before superSudoku is made visible.
function superSudoku_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to superSudoku (see VARARGIN)

% Choose default command line output for superSudoku
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);
setappdata(hObject,'actNumber',1);
setappdata(0,'hSuperSudoku',hObject);

% UIWAIT makes superSudoku wait for user response (see UIRESUME)
% uiwait(handles.mainSudoku);


% --- Outputs from this function are returned to the command line.
function varargout = superSudoku_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;


% --- Executes on button press in pushbutton1.
function newGame_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
hSuperSudoku = getappdata(0,'hSuperSudoku');
level = getappdata(hSuperSudoku,'Level');
if level==4 && getappdata(hSuperSudoku,'libenabled') %from library
    sudokulib=getappdata(hSuperSudoku,'sudokulib');
    libsize=getappdata(hSuperSudoku,'libsize');
    A=double(reshape(sudokulib(ceil(rand*libsize),:),9,[]));
else
    A = newpuzzle(level);
end
setappdata(hSuperSudoku,'Puzzle',A);
setappdata(hSuperSudoku,'solution',A);
setappdata(hSuperSudoku,'currentHint',A);
newmap(A);
verifyGame_Callback;

% --- Executes on button press in pushbutton2.
function saveGame_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
hSuperSudoku = getappdata(0, 'hSuperSudoku');
Puzzle = getappdata(hSuperSudoku, 'Puzzle');
if ~nnz(Puzzle>0)
    mesg('No valid puzzle.')
end
uisave('Puzzle');

% --- Executes on button press in pushbutton3.
function loadGame_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
hSuperSudoku = getappdata(0, 'hSuperSudoku');
fname = uigetfile('*.mat');
vlist = whos('-file',fname);
n=ceil(rand*numel(vlist));
if prod(vlist(n).size)~=81
    mesg('Not valid puzzle.')
    return
end
load(fname,vlist(n).name);
Puzzle=eval(vlist(n).name);
setappdata(hSuperSudoku, 'Puzzle', Puzzle);
setappdata(hSuperSudoku,'solution',Puzzle);
setappdata(hSuperSudoku,'currentHint',Puzzle);
newmap(Puzzle);
verifyGame_Callback;

% --- Executes on button press in pushbutton4.
function hintMark_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
hSuperSudoku = getappdata(0, 'hSuperSudoku');
hintLevel = getappdata(hSuperSudoku, 'hintLevel');
A = getappdata(hSuperSudoku,'currentHint');
if isempty(A)
    A = getappdata(hSuperSudoku, 'solution');
end
[B, err] = sudokuhint(A, hintLevel);
if err
    mesg('There is an error on the current board.');
end
[br,bc] = find(B>0 & ~A);
for k=1:numel(br)
    r=br(k);
    c=bc(k);
    n=B(r,c);
    sethintgrid(r,c,n);
end
setappdata(hSuperSudoku,'currentHint',B);

% --- Executes on selection change in popupmenu1.
function hintLevel_Callback(hObject, eventdata, handles)
% hObject    handle to popupmenu1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns popupmenu1 contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupmenu1
hSuperSudoku = getappdata(0, 'hSuperSudoku');
hintLevel = get(hObject, 'Value');
setappdata(hSuperSudoku, 'hintLevel', hintLevel);


% --- Executes during object creation, after setting all properties.
function hintLevel_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupmenu1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
hSuperSudoku = get(get(hObject, 'Parent'), 'Parent');
hintLevel = 1;
setappdata(hSuperSudoku, 'hintLevel', hintLevel);
set(hObject, 'Value', hintLevel);


% --- Executes on button press in pushbutton5.
function eraseMark_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton5 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
hSuperSudoku = getappdata(0, 'hSuperSudoku');
A = getappdata(hSuperSudoku,'currentHint');
if isempty(A)
    return
end
solution = getappdata(hSuperSudoku,'solution');
[pr,pc]=find(A>0 & ~solution);
for k=1:numel(pr)
    r=pr(k);
    c=pc(k);
    cleargrid(r,c);
end
setappdata(hSuperSudoku,'currentHint',solution);

% --- Executes on selection change in popupmenu2.
function levelSelector_Callback(hObject, eventdata, handles)
% hObject    handle to popupmenu2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns popupmenu2 contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupmenu2

level = get(hObject, 'Value');
hSuperSudoku = getappdata(0, 'hSuperSudoku');
setappdata(hSuperSudoku, 'Level',level); 

% --- Executes during object creation, after setting all properties.
function levelSelector_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupmenu2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
level = 1;
set(hObject, 'Value', level);
hSuperSudoku = get(get(hObject, 'Parent'),'Parent');
setappdata(hSuperSudoku, 'Level',level);
setappdata(hSuperSudoku, 'hLevel',hObject);
try
    load('supersudokulib');
    [libsize,m]=size(sudokulib);
    if m~=81
        str = get(hObject,'String');
        set(hObject, 'String', str(1:3));
        setappdata(hSuperSudoku,'libenabled',0);
    end        
    setappdata(hSuperSudoku,'sudokulib',sudokulib);
    setappdata(hSuperSudoku,'libsize',libsize);
    setappdata(hSuperSudoku,'libenabled',1);
catch
    str = get(hObject,'String');
    set(hObject, 'String', str(1:3));
    setappdata(hSuperSudoku,'libenabled',0);
end
setappdata(hSuperSudoku,'libupdated',0);

% --- Executes on button press in pushbutton7.
function fixMark_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton7 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
hSuperSudoku = getappdata(0,'hSuperSudoku');
A = getappdata(hSuperSudoku, 'currentHint');
solution = getappdata(hSuperSudoku, 'solution');
[pr,pc]=find(A>0 & ~solution);
for k=1:numel(pr)
    r=pr(k);
    c=pc(k);
    n=A(r,c);
    setgrid(r,c,n);
end
setappdata(hSuperSudoku, 'solution', A);

% --- Executes on button press in pushbutton8.
function solvePuzzle_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton8 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
hSuperSudoku = getappdata(0,'hSuperSudoku');
Puzzle = getappdata(hSuperSudoku, 'Puzzle');
if ~nnz(Puzzle)
    mesg('No puzzle is available.');
    return
end
[solution,level,error]=sudoku(Puzzle);
if error
    mesg('This is not a valid puzzle.')
    return
end
setappdata(hSuperSudoku, 'solution', solution);
[pr,pc]=find(~Puzzle);
for k=1:numel(pr)
    setgrid(pr(k),pc(k),solution(pr(k),pc(k)));
end

% --- Executes on button press in pushbutton6.
function validSolution_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton6 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
hSuperSudoku = getappdata(0,'hSuperSudoku');
solution = getappdata(hSuperSudoku,'solution');
if any(~solution(:))
    mesg('Puzzle is not completed.')
    return
end
err = solvalid(solution);
if err
    mesg('Solution is not right.');
else
    if ~getappdata(hSuperSudoku,'playTime')
        t = etime(clock,getappdata(hSuperSudoku,'clockStart'));
%         t = cputime - getappdata(hSuperSudoku,'clockStart');
        setappdata(hSuperSudoku,'playTime',t);
    else
        t = getappdata(hSuperSudoku,'playTime');
    end
    mesg(sprintf('Congratulations!\n Puzzle is solved in %g seconds.', t));
end

% --- Executes during object creation, after setting all properties.
function board_CreateFcn(hObject, eventdata, handles)
% hObject    handle to axes1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
% Hint: place code in OpeningFcn to populate axes1
for k1 = 1:9, 
    for k2 = 1:9, 
        rectangle('Position',[k1-0.5,k2-0.5,1,1]); 
    end, 
end
for k1 = [1 4 7], 
    for k2 = [1 4 7], 
        rectangle('Position',[k1-0.5,k2-0.5,3,3],'LineWidth',2); 
    end, 
end
hSuperSudoku = get(hObject, 'Parent');
setappdata(hSuperSudoku,'hBoard',hObject);
h1=zeros(9);
for k1 = 1:9
    for k2 = 1:9
            h1(k1,k2) = text(k2,10-k1,' ','FontSize',32,'HorizontalAlignment','center',...
            'ButtonDownFcn','superSudoku(''board_ButtonDownFcn'',gcbo,[],guidata(gcbo))');
    end
end
setappdata(hSuperSudoku,'hGrids',h1);

function clearmap
hGrids = getappdata(getappdata(0,'hSuperSudoku'),'hGrids');
for k = 1:81
    set(hGrids(k),'String',' ','Color','black');
end

function newmap(A)
clearmap;
hSuperSudoku=getappdata(0,'hSuperSudoku');
hGrids = getappdata(hSuperSudoku,'hGrids');
pA=A>0;
for k = find(pA)'
    set(hGrids(k),'String',num2str(A(k)),'Color','black');
end
setappdata(hSuperSudoku,'playHistory',zeros(nnz(pA),3));
setappdata(hSuperSudoku,'currentPlay',1);

function setgrid(r,c,n)
hGrids = getappdata(getappdata(0,'hSuperSudoku'),'hGrids');
set(hGrids(r,c),'String',num2str(n),'color','black');

function cleargrid(r,c)
hGrids = getappdata(getappdata(0,'hSuperSudoku'),'hGrids');
set(hGrids(r,c),'String',' ','Color','black');

function sethintgrid(r,c,n)
hGrids = getappdata(getappdata(0,'hSuperSudoku'),'hGrids');
set(hGrids(r,c),'String',num2str(n),'Color','red');

% --- Executes during object creation, after setting all properties.
function text2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to text2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

hSuperSudoku = get(get(hObject, 'Parent'), 'Parent');
setappdata(hSuperSudoku, 'hMsg', hObject);

function mesg(text)

hSuperSudoku=getappdata(0,'hSuperSudoku');
hMsg = getappdata(hSuperSudoku,'hMsg');
set(hMsg,'String',text);
wav = tts(text,'LH Michelle',-4,44100);
if ~isempty(wav),
    wavplay(wav,44100,'async');
end;  

% --- Executes on button press in checkbox4.
function numberOn_Callback(hObject, eventdata, handles)
% hObject    handle to checkbox4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of checkbox4
playStatus = get(hObject,'Value');
hSuperSudoku = getappdata(0, 'hSuperSudoku');
setappdata(hSuperSudoku, 'playStatus', playStatus);


% --- Executes during object creation, after setting all properties.
function numberOn_CreateFcn(hObject, eventdata, handles)
% hObject    handle to checkbox4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
hSuperSudoku = get(get(hObject, 'Parent'), 'Parent');
setappdata(hSuperSudoku, 'playStatus', get(hObject,'Value'));
setappdata(hSuperSudoku, 'hStatus', hObject);


% --- Executes when selected object is changed in playbuttons.
function playbuttons_SelectionChangeFcn(hObject, eventdata, handles)
% hObject    handle to the selected object in playbuttons 
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
hSuperSudoku = getappdata(0,'hSuperSudoku');
actNumber = str2double(get(hObject, 'String'));
setappdata(hSuperSudoku,'actNumber',actNumber);

% --- Executes on mouse press over axes background.
function board_ButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to axes1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

post = ceil(get(hObject,'Position')-0.5);
r = 10 - post(2);
c = post(1);
hSuperSudoku = getappdata(0, 'hSuperSudoku');
playStatus = getappdata(hSuperSudoku, 'playStatus');
Puzzle = getappdata(hSuperSudoku,'Puzzle');
Construct = getappdata(hSuperSudoku,'Construct');
switch Construct
    case 0
        if Puzzle(r,c)>0
            return
        end
        solution = getappdata(hSuperSudoku,'solution');
        playHistory = getappdata(hSuperSudoku, 'playHistory');
        currentPlay = getappdata(hSuperSudoku, 'currentPlay');
        if ~playStatus
            if ~solution(r,c)
                return
            end
            solution(r,c)=0;
            cleargrid(r,c);
            setappdata(hSuperSudoku,'solution',solution);
            setappdata(hSuperSudoku,'currentHint',solution);
            k=find(playHistory(:,1)==r & playHistory(:,2)==c);
            playHistory(k:end-1,:)=playHistory(k+1:end,:);
            currentPlay = currentPlay-1;
            setappdata(hSuperSudoku,'playHistory',playHistory);
            setappdata(hSuperSudoku,'currentPlay',currentPlay);
            return
        end
        if solution(r,c)>0
            return
        end
        actNumber = getappdata(hSuperSudoku, 'actNumber');
        solution(r,c) = actNumber;
        setgrid(r,c,actNumber);
        setappdata(hSuperSudoku,'solution',solution);
        setappdata(hSuperSudoku,'currentHint',solution);
        playHistory(currentPlay,:) = [r,c,actNumber];
        currentPlay = currentPlay + 1;
        setappdata(hSuperSudoku,'playHistory',playHistory);
        setappdata(hSuperSudoku,'currentPlay',currentPlay);
    case 1
        if isempty(Puzzle)
            Puzzle = zeros(9);
        end
        if ~playStatus
            if ~Puzzle(r,c)
                return
            end
            Puzzle(r,c)=0;
            cleargrid(r,c);
            setappdata(hSuperSudoku,'Puzzle',Puzzle);
            return
        end
        if Puzzle(r,c)>0
            return
        end
        actNumber = getappdata(hSuperSudoku, 'actNumber');
        Puzzle(r,c) = actNumber;
        setgrid(r,c,actNumber);
        setappdata(hSuperSudoku,'Puzzle',Puzzle);
end

% --- Executes on button press in pushbutton10.
function restart_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton10 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
hSuperSudoku = getappdata(0, 'hSuperSudoku');
A = getappdata(hSuperSudoku, 'Puzzle');
newmap(A);
setappdata(hSuperSudoku,'solution',A);
setappdata(hSuperSudoku,'currentHint',A);


% --- Executes on button press in pushbutton11.
function undo_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton11 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
hSuperSudoku = getappdata(0, 'hSuperSudoku');
currentPlay = getappdata(hSuperSudoku, 'currentPlay') - 1;
if ~currentPlay
    return
end
playHistory = getappdata(hSuperSudoku, 'playHistory');
r=playHistory(currentPlay,1);
c=playHistory(currentPlay,2);
cleargrid(r,c);
setappdata(hSuperSudoku, 'currentPlay', currentPlay);
solution = getappdata(hSuperSudoku,'solution');
solution(r,c)=0;
setappdata(hSuperSudoku, 'solution', solution);
setappdata(hSuperSudoku, 'currentHint', solution);


% --- Executes on button press in pushbutton12.
function redo_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton12 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
hSuperSudoku = getappdata(0, 'hSuperSudoku');
currentPlay = getappdata(hSuperSudoku, 'currentPlay');
playHistory = getappdata(hSuperSudoku, 'playHistory');
if currentPlay>size(playHistory,1) || ~all(playHistory(currentPlay,:))
    return
end
r=playHistory(currentPlay,1);
c=playHistory(currentPlay,2);
n=playHistory(currentPlay,3);
setgrid(r,c,n);
setappdata(hSuperSudoku, 'currentPlay', currentPlay+1);
solution = getappdata(hSuperSudoku,'solution');
solution(r,c)=n;
setappdata(hSuperSudoku, 'solution', solution);
setappdata(hSuperSudoku, 'currentHint', solution);


% --- Executes on button press in pushbutton13.
function about_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton13 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
mesg('superSudoku V2.0 developed by Yi Cao,  28 December 2007.');

function flag=solvalid(A)
flag=0;
if numel(unique(A))~=9, 
    flag=1; 
    return; 
end
h = reshape(1:9,3,3);
g = ceil((1:9)/3);
block = h(g,g);
[dum,K]=sort(block(:));
S=[A A' reshape(A(K),9,[])];
if any(diff(sum(S))), 
    flag=2; 
end

function A=newpuzzle(level)
h = reshape(1:9,3,3);
g = ceil((1:9)/3);
block=h(g,g);
[I,J]=find(ones(9));
K=block(:);
A=zeros(9);
loc=randperm(81);
v=randperm(9);
A(loc(1:9))=v;
B=A;
C=setC(B,I,J,K);
A1=A;
C1=C;
while nnz(~B)>0
    loc=find(sum(C,2)>1);
    n=length(loc);
    B0=B;
    C0=C;
    wz=loc(ceil(rand*n));
    xz=find(C(wz,:));
    nzV=randperm(numel(xz));
    for k=nzV
        flag=false;
        v=xz(k);
        B(wz)=v;
        C(wz,:)=false;
        C(wz,v)=true;
        [C,err]=setOneC(C,wz,I,J,K);
        if ~err
            switch level
                case 1
                    [B,C,err]=findone(B,C,I,J,K);
                case 2
                    [B,C,err]=nonrecsolver(B,C,I,J,K);
                otherwise
                    [B,C,err]=nonrecsolver(B,C,I,J,K);
                    if ~err && nnz(A)>17
                        [B,C,err]=branch(B,C,I,J,K,-1);
                    end
            end
        end
        if ~err
            A(wz)=v;
            if ~nnz(~B)
                return
            end
            flag=true;
            break
        end
        B=B0;
        C=C0;
    end
    if ~flag
        C=C1;
        A=A1;
        B=A;
    end
end

function [C,err]=setC(B,I,J,K)
err=false;
zB=~B(:);
C=false(81,9);
nc=find(~zB);
C(nc+(B(nc)-1)*81)=true;
C(zB,:)=true;
nB = nnz(B);
idxB = find(B);
for k=1:nB
    [C,err]=setOneC(C,idxB(k),I,J,K);
    if err
        return
    end
end

function [B,C,err,n]=updateBC(B,C,I,J,K,n)
zB=~B(:);
if nargin<6
    n=sum(zB);
end
newOne=sum(C(zB,:),2)==1;
err=false;
while sum(newOne)>0 && n>0
    zBidx=find(zB);
    newOne=zBidx(newOne);
%     [i,j]=find(C(newOne,:));
%     B(newOne(i))=j;
    for k=1:numel(newOne)
        z = newOne(k);
        B(z) = find(C(z,:));
        zB(z)=false;
        [C,err]=setOneC(C,z,I,J,K);
        n = n - 1;
        if err || ~n
            return
        end
    end
%     zB=~B;
    newOne=sum(C(zB(:),:),2)==1;
end

function [C,err]=setOneC(C,z,I,J,K)
zz = I==I(z) | J==J(z) | K==K(z);
zz(z) = false;
cc=C(z,:);
C(zz,cc)=false;
err=any(~any(C(zz,:),2));

function [B,C,err,n,level]=nonrecsolver(B,C,I,J,K,n)
if nargin<6
    n=sum(~B(:));
end
level=1;
[B,C,err,n]=findone(B,C,I,J,K,n);
if ~any(~B(:)) || err, return; end
level=2;
[B,C,err,n]=findtwo(B,C,I,J,K,n);

function [B,C,err,n]=findone(B,C,I,J,K,n)
if nargin<6
    n=sum(~B(:));
end
flag=true;
while flag
    [B,C,err,n]=updateBC(B,C,I,J,K,n);
    if err || ~sum(~B(:))
        return
    end
    [B,C,err,n]=findoneC(B,C,I,J,K,n);
    if err || ~sum(~B(:))
        return 
    end
    C0=C;
    [C,err]=crosscheck(C,~B,I,J,K);
    if err
        return
    end
    flag=~isequal(C,C0);
end

function [B,C,err,n]=findoneC(B,C,I,J,K,n)
zB=~B(:);
err=false;
flag=1;
if nargin<6
    n=sum(zB);
end
while any(zB) && flag && n>0,
    flag=0;
    zC=find(zB)';
    for z=zC,
        is=I==I(z); is(z)=false;
        js=J==J(z); js(z)=false;
        bs=K==K(z); bs(z)=false;
        cc = C(z,:) & (~any(C(is,:)) | ~any(C(js,:)) | ~any(C(bs,:)));
        if sum(cc)==1,
            flag=1;
            ks = (is | js | bs) & zB;
            C(z,:)=cc;
            C(ks,cc)=false;
            if any(~any(C(ks,:),2))
                err=true;
                return
            end
            [B,C,err,n]=updateBC(B,C,I,J,K,n);
            if err
                return
            end
            zB(z)=false;
            break;
        end
    end
end

function [C,err]=crosscheck(C,zB,I,J,K)
err=false;
N=1:9;
I(~zB)=0;
J(~zB)=0;
K(~zB)=0;
for k=1:9
    row=false(1,9);
    col=false(1,9);
    zK = K == k;
    Ik = I(zK);
    Jk = J(zK);
    row(Ik)=true;
    col(Jk)=true;
    for r=N(row)
        rI = I == r;
        zI = zK & rI;
        kI = zK & ~rI;
        pI = rI & ~zK;
        z = any(C(zI,:),1) & ~any(C(kI,:),1);
        if sum(z)>0
            C(pI,z)=false;
            if any(~any(C(pI,:),2))
                err=true;
                return
            end
        end
        z = any(C(zI,:),1) & ~any(C(pI,:),1);
        if sum(z)>0
            C(kI,z)=false;
            if any(~any(C(kI,:),2))
                err=true;
                return
            end
        end
    end
    for c=N(col)
        cJ = J == c;
        zJ = zK & cJ;
        kJ = zK & ~cJ;
        pJ = cJ & ~zK;
        z = any(C(zJ,:),1) & ~any(C(kJ,:),1);
        if sum(z)>0
            C(pJ,z)=false;
            if any(~any(C(pJ,:),2))
                err=true;
                return
            end
        end
        z = any(C(zJ,:),1) & ~any(C(pJ,:),1);
        if sum(z)>0
            C(kJ,z)=false;
            if any(~any(C(kJ,:),2))
                err=true;
                return
            end
        end
    end
end

function [B,C,err,n]=findtwo(B,C,I,J,K,n)
zB=~B(:);
if nargin<6
    n=sum(zB);
end
err=false;
C0=C;
C=find2sub(C,I,zB);
C=find2sub(C,J,zB);
C=find2sub(C,K,zB);
if isequal(C0,C)
    return
end
[B,C,err,n]=findone(B,C,I,J,K,n);    

function C=find2sub(C,I,zB)
I=I(zB);
% nB=find(zB);
C1=C(zB,:);
for c=1:9,
    kc=(I==c); %&zB;
%     zc=nB(kc);
    zc=find(kc)';
    nC=sum(C1,2);
    nz=numel(zc);
    if nz<3, 
        continue, 
    end
    for i=1:nz-1,
        ic=zc(i);
        kc(ic)=false;
        for j=i+1:nz,
            jc=zc(j);
            kc(jc)=false;
            if (nC(ic)>2 || nC(jc)>2)
                cc=C1(ic,:) & C1(jc,:);
                if sum(cc)>1,
                    cc=cc & ~any(C1(kc,:));
                    if sum(cc)==2
                        nC(ic)=2;
                        nC(jc)=2;
                        C1(ic,:)=cc;
                        C1(jc,:)=cc;
                    end
                end
            end
            if (nC(ic)==2 && nC(jc)==2 && isequal(C1(ic,:),C1(jc,:)))
                cc=~C1(ic,:);
                C1(kc,:)=C1(kc,:)&cc(ones(sum(kc),1),:);
                nC(kc)=sum(C1(kc,:),2);
            end
            kc(jc)=true;
        end
        kc(ic)=true;
    end
end
C(zB,:)=C1;

function [B,level,err]=sudoku(A)
h = reshape(1:9,3,3);
g = ceil((1:9)/3);
block=h(g,g);
level=1;
[I,J]=find(ones(9));
K=block(:);
B=A;
[C,err]=setC(B,I,J,K);
if err
    return
end
[B,C,err,n,level]=nonrecsolver(B,C,I,J,K);
if ~any(~B(:)) || err, return; end
level=3;
[B,C,err,n,nz]=branch(B,C,I,J,K);
level=level+nz-2;

function [B,C,err,n,nz0]=branch(B,C,I,J,K,n0)
C0=C;
B0=B;
if nargin<6
    n0=nnz(~B0);
end
sumC=sum(C,2);
sumC(sumC<2)=Inf;
[nz,wz]=min(sumC);
xz=find(C(wz,:));
for k=1:nz
    B(wz)=xz(k);
    C(wz,xz([1:k-1 k+1:end]))=false;
    [C1,err]=setOneC(C,wz,I,J,K);
    if ~err
        [B1,C1,err,n]=nonrecsolver(B,C1,I,J,K);
    end
    if ~err  %nnz(~B)
        if n>0 && n0>0
            [B1,C1,err,n,nz1]=branch(B1,C1,I,J,K);
        else
            nz1=0;
        end
        if n0~=1
            B=B1;
            C=C1;
        end
    end
    if ~err
        nz0=max(nz,nz1);
        return
    end
    B=B0;
    C=C0;
end
n=n0;
err=true;
nz0=nz;

function [B,err]=sudokuhint(B,level)
h = reshape(1:9,3,3);
g = ceil((1:9)/3);
block=h(g,g);
[I,J]=find(ones(9));
K=block(:);
% zB=~B;
% C=false(81,9);
% nc=find(~zB);
% C(nc+(B(nc)-1)*81)=true;
% C(zB,:)=true;
[C,err]=setC(B,I,J,K);
if err
    return
end
flag=1;
while flag
    [B,C,err,n]=updateBC(B,C,I,J,K,1);
    if ~any(~B(:)) || err || ~n || level<2, 
        return; 
    end
    [B,C,err,n]=findoneC(B,C,I,J,K,n);
    if ~any(~B(:)) || err || ~n, 
        return; 
    end
    C0=C;
    C=crosscheck(C,~B,I,J,K);
    flag=~isequal(C,C0);
end
if level<3
    return
end
[B,C,err,n]=findtwo(B,C,I,J,K,n);
if ~any(~B(:)) || err || level<4 || ~n, 
    return; 
end
[B,C,err]=branch(B,C,I,J,K,n);


% --- Executes on button press in pushbutton14.
function exit_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton14 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
hSuperSudoku=getappdata(0,'hSuperSudoku');
if getappdata(hSuperSudoku,'libenabled') && getappdata(hSuperSudoku,'libupdated')
    sudokulib=getappdata(hSuperSudoku,'sudokulib');
    save supersudokulib sudokulib
end
close(hSuperSudoku);

% --- Executes on button press in checkbox5.
function construct_Callback(hObject, eventdata, handles)
% hObject    handle to checkbox5 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of checkbox5
hSuperSudoku=getappdata(0,'hSuperSudoku');
Construct=get(hObject, 'Value');
setappdata(hSuperSudoku, 'Construct',Construct);

% --- Executes during object creation, after setting all properties.
function construct_CreateFcn(hObject, eventdata, handles)
% hObject    handle to checkbox5 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called
hSuperSudoku=get(get(hObject,'Parent'),'Parent');
set(hObject,'Value',0);
setappdata(hSuperSudoku,'Construct',get(hObject,'Value'));
setappdata(hSuperSudoku,'hConstruct',hObject);


% --- Executes on button press in pushbutton15.
function verifyGame_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton15 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
hSuperSudoku=getappdata(0,'hSuperSudoku');
Puzzle = getappdata(hSuperSudoku, 'Puzzle');
if isempty(Puzzle) || ~nnz(Puzzle)
    mesg('No puzzle.')
    return
end    
[B,level,err]=sudoku(Puzzle);
if err
    mesg('This is not a valid puzzle.')
    return
end
setappdata(hSuperSudoku, 'solution', Puzzle);
setappdata(hSuperSudoku, 'currentHint', Puzzle);
mesg(sprintf('A level %d puzzle is ready.',level));
setappdata(hSuperSudoku,'clockStart',clock);
setappdata(hSuperSudoku,'playTime',0);
set(getappdata(hSuperSudoku,'hConstruct'),'Value',0);
set(getappdata(hSuperSudoku,'hStatus'),'Value',1);
setappdata(hSuperSudoku,'playStatus',1);
Puzzle=uint8(Puzzle(:)');
maxSize=1e6;
if ~getappdata(hSuperSudoku,'libenabled')
    sudokulib=Puzzle;
    libsize=1;
    setappdata(hSuperSudoku,'libenabled',1);
    hLevel=getappdata(hSuperSudoku,'hLevel');
    str = get(hLevel,'String');
    str(4) = {'libaray'};
    set(hLevel,'String',str);
else
    sudokulib=getappdata(hSuperSudoku,'sudokulib');
    libsize=getappdata(hSuperSudoku,'libsize');
    A=repmat(Puzzle,libsize,1);
    if any(all(sudokulib==A,2))||libsize>=maxSize
        return
    end
    libsize=libsize+1;
    sudokulib(libsize,:)=Puzzle;
end
setappdata(hSuperSudoku,'sudokulib',sudokulib);
setappdata(hSuperSudoku,'libsize',libsize);
setappdata(hSuperSudoku,'libupdated',1);


% --- Creates and returns a handle to the GUI figure. 
function h1 = superSudoku_LayoutFcn(policy)
% policy - create a new figure or use a singleton. 'new' or 'reuse'.

persistent hsingleton;
if strcmpi(policy, 'reuse') & ishandle(hsingleton)
    h1 = hsingleton;
    return;
end
% load superSudoku.mat

appdata = [];
appdata.GUIDEOptions = struct(...
    'active_h', [], ...
    'taginfo', struct(...
    'figure', 2, ...
    'axes', 2, ...
    'pushbutton', 16, ...
    'popupmenu', 3, ...
    'text', 3, ...
    'edit', 3, ...
    'togglebutton', 2, ...
    'listbox', 2, ...
    'uipanel', 7, ...
    'checkbox', 6, ...
    'radiobutton', 19), ...
    'override', 0, ...
    'release', 13, ...
    'resize', 'none', ...
    'accessibility', 'callback', ...
    'mfile', 1, ...
    'callbacks', 1, ...
    'singleton', 1, ...
    'syscolorfig', 1, ...
    'blocking', 0);
appdata.lastValidTag = 'mainSudoku';
appdata.Level = 1;
appdata.hBoard = [];
appdata.hGrids = [];
appdata.hMsg = [];
appdata.playStatus = 0;
appdata.hintLevel = 1;
appdata.Construct = 0;
appdata.hConstruct = [];
appdata.hStatus = [];
appdata.hLevel = [];
appdata.libenabled = 0;
appdata.libupdated = 0;
appdata.initTags = struct(...
    'handle', [], ...
    'tag', 'mainSudoku');
appdata.GUIDELayoutEditor = [];

h1 = figure(...
'Units','characters',...
'PaperUnits',get(0,'defaultfigurePaperUnits'),...
'Color',[0.925490196078431 0.913725490196078 0.847058823529412],...
'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],...
'IntegerHandle','off',...
'InvertHardcopy',get(0,'defaultfigureInvertHardcopy'),...
'MenuBar','none',...
'Name','superSudoku',...
'NumberTitle','off',...
'PaperPosition',get(0,'defaultfigurePaperPosition'),...
'PaperSize',[20.98404194812 29.67743169791],...
'PaperType',get(0,'defaultfigurePaperType'),...
'Position',[103.8 19 176.2 42.4615384615385],...
'Resize','off',...%'UseHG2','off',...
'HandleVisibility','callback',...
'Tag','mainSudoku',...
'UserData',[],...
'Visible','on',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'axes1';

h2 = axes(...
'Parent',h1,...
'Units','characters',...
'Position',[4.6 3.92307692307692 90.2 34.6923076923077],...
'CameraPosition',[5 5 17.3205080756888],...
'CameraPositionMode',get(0,'defaultaxesCameraPositionMode'),...
'Color',get(0,'defaultaxesColor'),...
'ColorOrder',get(0,'defaultaxesColorOrder'),...
'LooseInset',[22.542 6.00769230769231 16.473 4.09615384615385],...
'XColor',get(0,'defaultaxesXColor'),...
'XTickLabel',blanks(0),...
'XTickLabelMode','manual',...
'YColor',get(0,'defaultaxesYColor'),...
'YTickLabel',blanks(0),...
'YTickLabelMode','manual',...
'ZColor',get(0,'defaultaxesZColor'),...
'ButtonDownFcn','superSudoku(''board_ButtonDownFcn'',gcbo,[],guidata(gcbo))',...
'CreateFcn', {@local_CreateFcn, 'superSudoku(''board_CreateFcn'',gcbo,[],guidata(gcbo))', appdata} ,...
'Tag','axes1',...
'Visible','off');

appdata = [];
appdata.SerializedAnnotationV7 = struct(...
    'LegendInformation', struct(...
    'IconDisplayStyle', 'on'));

h3 = get(h2,'title');

set(h3,...
'Parent',h2,...
'Units','data',...
'FontUnits','points',...
'BackgroundColor','none',...
'Color',[0 0 0],...%'DisplayName',blanks(0),...
'EdgeColor','none',...
'EraseMode','normal',...
'DVIMode','auto',...
'FontAngle','normal',...
'FontName','Helvetica',...
'FontSize',10,...
'FontWeight','normal',...
'HorizontalAlignment','center',...
'LineStyle','-',...
'LineWidth',0.5,...
'Margin',2,...
'Position',[5 10.1441241685144 1.00010919874411],...
'Rotation',0,...
'String',blanks(0),...
'Interpreter','tex',...
'VerticalAlignment','bottom',...
'ButtonDownFcn',[],...
'CreateFcn', {@local_CreateFcn, [], appdata} ,...
'DeleteFcn',[],...
'BusyAction','queue',...
'HandleVisibility','off',...
'HelpTopicKey',blanks(0),...
'HitTest','on',...
'Interruptible','on',...
'SelectionHighlight','on',...
'Serializable','on',...
'Tag',blanks(0),...
'UserData',[],...
'Visible','off',...
'XLimInclude','on',...
'YLimInclude','on',...
'ZLimInclude','on',...
'CLimInclude','on',...
'ALimInclude','on',...%'IncludeRenderer','on',...
'Clipping','off');

appdata = [];
appdata.SerializedAnnotationV7 = struct(...
    'LegendInformation', struct(...
    'IconDisplayStyle', 'on'));

h4 = get(h2,'xlabel');

set(h4,...
'Parent',h2,...
'Units','data',...
'FontUnits','points',...
'BackgroundColor','none',...
'Color',[0 0 0],...%'DisplayName',blanks(0),...
'EdgeColor','none',...
'EraseMode','normal',...
'DVIMode','auto',...
'FontAngle','normal',...
'FontName','Helvetica',...
'FontSize',10,...
'FontWeight','normal',...
'HorizontalAlignment','center',...
'LineStyle','-',...
'LineWidth',0.5,...
'Margin',2,...
'Position',[4.97782705099778 -0.232815964523279 1.00010919874411],...
'Rotation',0,...
'String',blanks(0),...
'Interpreter','tex',...
'VerticalAlignment','cap',...
'ButtonDownFcn',[],...
'CreateFcn', {@local_CreateFcn, [], appdata} ,...
'DeleteFcn',[],...
'BusyAction','queue',...
'HandleVisibility','off',...
'HelpTopicKey',blanks(0),...
'HitTest','on',...
'Interruptible','on',...
'SelectionHighlight','on',...
'Serializable','on',...
'Tag',blanks(0),...
'UserData',[],...
'Visible','off',...
'XLimInclude','on',...
'YLimInclude','on',...
'ZLimInclude','on',...
'CLimInclude','on',...
'ALimInclude','on',...%'IncludeRenderer','on',...
'Clipping','off');

appdata = [];
appdata.SerializedAnnotationV7 = struct(...
    'LegendInformation', struct(...
    'IconDisplayStyle', 'on'));

h5 = get(h2,'ylabel');

set(h5,...
'Parent',h2,...
'Units','data',...
'FontUnits','points',...
'BackgroundColor','none',...
'Color',[0 0 0],...%'DisplayName',blanks(0),...
'EdgeColor','none',...
'EraseMode','normal',...
'DVIMode','auto',...
'FontAngle','normal',...
'FontName','Helvetica',...
'FontSize',10,...
'FontWeight','normal',...
'HorizontalAlignment','center',...
'LineStyle','-',...
'LineWidth',0.5,...
'Margin',2,...
'Position',[-0.232815964523282 4.97782705099778 1.00010919874411],...
'Rotation',90,...
'String',blanks(0),...
'Interpreter','tex',...
'VerticalAlignment','bottom',...
'ButtonDownFcn',[],...
'CreateFcn', {@local_CreateFcn, [], appdata} ,...
'DeleteFcn',[],...
'BusyAction','queue',...
'HandleVisibility','off',...
'HelpTopicKey',blanks(0),...
'HitTest','on',...
'Interruptible','on',...
'SelectionHighlight','on',...
'Serializable','on',...
'Tag',blanks(0),...
'UserData',[],...
'Visible','off',...
'XLimInclude','on',...
'YLimInclude','on',...
'ZLimInclude','on',...
'CLimInclude','on',...
'ALimInclude','on',...%'IncludeRenderer','on',...
'Clipping','off');

appdata = [];
appdata.SerializedAnnotationV7 = struct(...
    'LegendInformation', struct(...
    'IconDisplayStyle', 'on'));

h6 = get(h2,'zlabel');

set(h6,...
'Parent',h2,...
'Units','data',...
'FontUnits','points',...
'BackgroundColor','none',...
'Color',[0 0 0],...%'DisplayName',blanks(0),...
'EdgeColor','none',...
'EraseMode','normal',...
'DVIMode','auto',...
'FontAngle','normal',...
'FontName','Helvetica',...
'FontSize',10,...
'FontWeight','normal',...
'HorizontalAlignment','right',...
'LineStyle','-',...
'LineWidth',0.5,...
'Margin',2,...
'Position',[-0.521064301552106 11.0753880266075 1.00010919874411],...
'Rotation',0,...
'String',blanks(0),...
'Interpreter','tex',...
'VerticalAlignment','middle',...
'ButtonDownFcn',[],...
'CreateFcn', {@local_CreateFcn, [], appdata} ,...
'DeleteFcn',[],...
'BusyAction','queue',...
'HandleVisibility','off',...
'HelpTopicKey',blanks(0),...
'HitTest','on',...
'Interruptible','on',...
'SelectionHighlight','on',...
'Serializable','on',...
'Tag',blanks(0),...
'UserData',[],...
'Visible','off',...
'XLimInclude','on',...
'YLimInclude','on',...
'ZLimInclude','on',...
'CLimInclude','on',...
'ALimInclude','on',...%'IncludeRenderer','on',...
'Clipping','off');

appdata = [];
appdata.lastValidTag = 'uipanel3';
appdata.Level = 1;
appdata.libenabled = 0;

h7 = uipanel(...
'Parent',h1,...
'Units','characters',...
'Title','Game Control',...
'Tag','uipanel3',...
'Clipping','on',...
'Position',[119.8 17.8461538461538 50.2 20.6923076923077],...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'pushbutton2';

h8 = uicontrol(...
'Parent',h7,...
'Units','characters',...
'Callback','superSudoku(''saveGame_Callback'',gcbo,[],guidata(gcbo))',...
'Position',[20 11.7692307692308 12 2],...
'String','Save',...
'TooltipString','save game to a file',...
'Tag','pushbutton2',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'pushbutton6';

h9 = uicontrol(...
'Parent',h7,...
'Units','characters',...
'Callback','superSudoku(''validSolution_Callback'',gcbo,[],guidata(gcbo))',...
'Position',[4 4.30769230769231 20.2 1.76923076923077],...
'String','Verify Solution',...
'TooltipString','verify solution of the game',...
'Tag','pushbutton6',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'text2';

h10 = uicontrol(...
'Parent',h7,...
'Units','characters',...
'Position',[4.4 0.615384615384615 40.8 3.15384615384615],...
'String','No puzzle',...
'Style','text',...
'CreateFcn', {@local_CreateFcn, 'superSudoku(''text2_CreateFcn'',gcbo,[],guidata(gcbo))', appdata} ,...
'Tag','text2');

appdata = [];
appdata.lastValidTag = 'pushbutton11';

h11 = uicontrol(...
'Parent',h7,...
'Units','characters',...
'Callback','superSudoku(''undo_Callback'',gcbo,[],guidata(gcbo))',...
'Position',[20 8 12 1.92307692307692],...
'String','Undo',...
'TooltipString','undo last move',...
'Tag','pushbutton11',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'pushbutton12';

h12 = uicontrol(...
'Parent',h7,...
'Units','characters',...
'Callback','superSudoku(''redo_Callback'',gcbo,[],guidata(gcbo))',...
'Position',[36.6 8.07692307692308 10.6 1.84615384615385],...
'String','Redo',...
'TooltipString','redo last move',...
'Tag','pushbutton12',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'pushbutton3';

h13 = uicontrol(...
'Parent',h7,...
'Units','characters',...
'Callback','superSudoku(''loadGame_Callback'',gcbo,[],guidata(gcbo))',...
'Position',[4 12 12.6 1.76923076923077],...
'String','Load',...
'TooltipString','load a game from a file',...
'Tag','pushbutton3',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'pushbutton1';

h14 = uicontrol(...
'Parent',h7,...
'Units','characters',...
'Callback','superSudoku(''newGame_Callback'',gcbo,[],guidata(gcbo))',...
'Position',[3.8 15.8461538461538 13.8 1.76923076923077],...
'String','New Game',...
'TooltipString','generate a new game',...
'Tag','pushbutton1',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'pushbutton10';

h15 = uicontrol(...
'Parent',h7,...
'Units','characters',...
'Callback','superSudoku(''restart_Callback'',gcbo,[],guidata(gcbo))',...
'Position',[3.8 8.07692307692308 12.6 1.84615384615385],...
'String','Restart',...
'TooltipString','re-start the game',...
'Tag','pushbutton10',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'popupmenu2';

h16 = uicontrol(...
'Parent',h7,...
'Units','characters',...
'BackgroundColor',[1 1 1],...
'Callback','superSudoku(''levelSelector_Callback'',gcbo,[],guidata(gcbo))',...
'Position',[25.2 16.0769230769231 19.8 1.53846153846154],...
'String',{  'easy'; 'normal'; 'difficult'; 'library' },...
'Style','popupmenu',...
'TooltipString','level of game to be generated',...
'Value',1,...
'CreateFcn', {@local_CreateFcn, 'superSudoku(''levelSelector_CreateFcn'',gcbo,[],guidata(gcbo))', appdata} ,...
'Tag','popupmenu2');

appdata = [];
appdata.lastValidTag = 'pushbutton14';

h17 = uicontrol(...
'Parent',h7,...
'Units','characters',...
'Callback','superSudoku(''exit_Callback'',gcbo,[],guidata(gcbo))',...
'Position',[35.8 11.9230769230769 11.4 1.84615384615385],...
'String','Exit',...
'TooltipString','exit the game',...
'Tag','pushbutton14',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'pushbutton15';

h18 = uicontrol(...
'Parent',h7,...
'Units','characters',...
'Callback','superSudoku(''verifyGame_Callback'',gcbo,[],guidata(gcbo))',...
'Position',[26.6 4.30769230769231 20.2 1.76923076923077],...
'String','Verify Game',...
'TooltipString','verify a game',...
'Tag','pushbutton15',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'uipanel4';

h19 = uipanel(...
'Parent',h1,...
'Units','characters',...
'Title','Help',...
'Tag','uipanel4',...
'Clipping','on',...
'Position',[120 5.53846153846153 48.2 11.6153846153846],...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'pushbutton7';

h20 = uicontrol(...
'Parent',h19,...
'Units','characters',...
'Callback','superSudoku(''fixMark_Callback'',gcbo,[],guidata(gcbo))',...
'Position',[22.8 4.53846153846154 20.2 1.84615384615385],...
'String','Fix Marks',...
'TooltipString','fix all hint marks',...
'Tag','pushbutton7',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'pushbutton8';

h21 = uicontrol(...
'Parent',h19,...
'Units','characters',...
'Callback','superSudoku(''solvePuzzle_Callback'',gcbo,[],guidata(gcbo))',...
'Position',[22.8 1.07692307692308 20.2 1.84615384615385],...
'String','Solve Puzzle',...
'TooltipString','solve the puzzle',...
'Tag','pushbutton8',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'pushbutton13';

h22 = uicontrol(...
'Parent',h19,...
'Units','characters',...
'Callback','superSudoku(''about_Callback'',gcbo,[],guidata(gcbo))',...
'Position',[2.4 1.15384615384615 14.2 1.76923076923077],...
'String','About',...
'TooltipString','about the game',...
'Tag','pushbutton13',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'pushbutton4';

h23 = uicontrol(...
'Parent',h19,...
'Units','characters',...
'Callback','superSudoku(''hintMark_Callback'',gcbo,[],guidata(gcbo))',...
'Position',[2.4 8.07692307692308 13.8 1.76923076923077],...
'String','Hint Marks',...
'TooltipString','generate a hint for next move',...
'Tag','pushbutton4',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'pushbutton5';

h24 = uicontrol(...
'Parent',h19,...
'Units','characters',...
'Callback','superSudoku(''eraseMark_Callback'',gcbo,[],guidata(gcbo))',...
'Position',[2.4 4.61538461538462 13.8 1.76923076923077],...
'String','Erase Marks',...
'TooltipString','erase all hint marks',...
'Tag','pushbutton5',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'popupmenu1';

h25 = uicontrol(...
'Parent',h19,...
'Units','characters',...
'BackgroundColor',[1 1 1],...
'Callback','superSudoku(''hintLevel_Callback'',gcbo,[],guidata(gcbo))',...
'Position',[23.2 8.30769230769231 19.8 1.53846153846154],...
'String',{  'direct single'; 'indirect single'; 'paires'; 'recursive' },...
'Style','popupmenu',...
'TooltipString','hint level',...
'Value',1,...
'CreateFcn', {@local_CreateFcn, 'superSudoku(''hintLevel_CreateFcn'',gcbo,[],guidata(gcbo))', appdata} ,...
'Tag','popupmenu1');

appdata = [];
appdata.lastValidTag = 'playbuttons';

h26 = uibuttongroup(...
'Parent',h1,...
'Units','characters',...
'Title','Play',...
'Tag','playbuttons',...
'Clipping','on',...
'Position',[97.4 5.07692307692308 20.4 33.4615384615385],...
'SelectedObject',[],...
'SelectionChangeFcn','superSudoku(''playbuttons_SelectionChangeFcn'',gcbo,[],guidata(gcbo))',...
'OldSelectedObject',[],...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'radiobutton10';

h27 = uicontrol(...
'Parent',h26,...
'Units','characters',...
'Position',[7.8 23.6923076923077 6.2 1.23076923076923],...
'String','1',...
'Style','radiobutton',...
'TooltipString','number button 1',...
'Value',1,...
'Tag','radiobutton10',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'radiobutton11';

h28 = uicontrol(...
'Parent',h26,...
'Units','characters',...
'Position',[7.8 21 6.2 1.23076923076923],...
'String','2',...
'Style','radiobutton',...
'TooltipString','number button 2',...
'Tag','radiobutton11',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'radiobutton12';

h29 = uicontrol(...
'Parent',h26,...
'Units','characters',...
'Position',[7.8 18.3076923076923 6.2 1.23076923076923],...
'String','3',...
'Style','radiobutton',...
'TooltipString','number button 3',...
'Tag','radiobutton12',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'radiobutton13';

h30 = uicontrol(...
'Parent',h26,...
'Units','characters',...
'Position',[7.8 15.6153846153846 6.2 1.23076923076923],...
'String','4',...
'Style','radiobutton',...
'TooltipString','number button 4',...
'Tag','radiobutton13',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'radiobutton14';

h31 = uicontrol(...
'Parent',h26,...
'Units','characters',...
'Position',[7.8 12.9230769230769 6.2 1.23076923076923],...
'String','5',...
'Style','radiobutton',...
'TooltipString','number button 5',...
'Tag','radiobutton14',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'radiobutton15';

h32 = uicontrol(...
'Parent',h26,...
'Units','characters',...
'Position',[7.8 10.2307692307692 6.2 1.23076923076923],...
'String','6',...
'Style','radiobutton',...
'TooltipString','number button 6',...
'Tag','radiobutton15',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'radiobutton16';

h33 = uicontrol(...
'Parent',h26,...
'Units','characters',...
'Position',[7.8 7.53846153846154 6.2 1.23076923076923],...
'String','7',...
'Style','radiobutton',...
'TooltipString','number button 7',...
'Tag','radiobutton16',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'radiobutton17';

h34 = uicontrol(...
'Parent',h26,...
'Units','characters',...
'Position',[7.8 4.84615384615385 6.2 1.23076923076923],...
'String','8',...
'Style','radiobutton',...
'TooltipString','number button 8',...
'Tag','radiobutton17',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'radiobutton18';

h35 = uicontrol(...
'Parent',h26,...
'Units','characters',...
'Position',[7.8 2.15384615384615 6.2 1.23076923076923],...
'String','9',...
'Style','radiobutton',...
'TooltipString','number button 9',...
'Tag','radiobutton18',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'checkbox4';

h36 = uicontrol(...
'Parent',h26,...
'Units','characters',...
'Callback','superSudoku(''numberOn_Callback'',gcbo,[],guidata(gcbo))',...
'Position',[4 26.3846153846154 11.8 1.61538461538462],...
'String','On / Off',...
'Style','checkbox',...
'TooltipString','number button on/off',...
'CreateFcn', {@local_CreateFcn, 'superSudoku(''numberOn_CreateFcn'',gcbo,[],guidata(gcbo))', appdata} ,...
'Tag','checkbox4');

appdata = [];
appdata.lastValidTag = 'checkbox5';

h37 = uicontrol(...
'Parent',h26,...
'Units','characters',...
'Callback','superSudoku(''construct_Callback'',gcbo,[],guidata(gcbo))',...
'Position',[4 29.4615384615385 14.6 1.15384615384615],...
'String','Construct',...
'Style','checkbox',...
'TooltipString','select to constructu a game',...
'CreateFcn', {@local_CreateFcn, 'superSudoku(''construct_CreateFcn'',gcbo,[],guidata(gcbo))', appdata} ,...
'Tag','checkbox5');


hsingleton = h1;


% --- Set application data first then calling the CreateFcn. 
function local_CreateFcn(hObject, eventdata, createfcn, appdata)

if ~isempty(appdata)
   names = fieldnames(appdata);
   for i=1:length(names)
       name = char(names(i));
       setappdata(hObject, name, getfield(appdata,name));
   end
end

if ~isempty(createfcn)
   eval(createfcn);
end


% --- Handles default GUIDE GUI creation and callback dispatch
function varargout = gui_mainfcn(gui_State, varargin)

gui_StateFields =  {'gui_Name'
    'gui_Singleton'
    'gui_OpeningFcn'
    'gui_OutputFcn'
    'gui_LayoutFcn'
    'gui_Callback'};
gui_Mfile = '';
for i=1:length(gui_StateFields)
    if ~isfield(gui_State, gui_StateFields{i})
        error('MATLAB:gui_mainfcn:FieldNotFound', 'Could not find field %s in the gui_State struct in GUI M-file %s', gui_StateFields{i}, gui_Mfile);
    elseif isequal(gui_StateFields{i}, 'gui_Name')
        gui_Mfile = [gui_State.(gui_StateFields{i}), '.m'];
    end
end

numargin = length(varargin);

if numargin == 0
    % SUPERSUDOKU
    % create the GUI only if we are not in the process of loading it
    % already
    gui_Create = true;
elseif local_isInvokeActiveXCallback(gui_State, varargin{:})
    % SUPERSUDOKU(ACTIVEX,...)
    vin{1} = gui_State.gui_Name;
    vin{2} = [get(varargin{1}.Peer, 'Tag'), '_', varargin{end}];
    vin{3} = varargin{1};
    vin{4} = varargin{end-1};
    vin{5} = guidata(varargin{1}.Peer);
    feval(vin{:});
    return;
elseif local_isInvokeHGCallbak(gui_State, varargin{:})
    % SUPERSUDOKU('CALLBACK',hObject,eventData,handles,...)
    gui_Create = false;
else
    % SUPERSUDOKU(...)
    % create the GUI and hand varargin to the openingfcn
    gui_Create = true;
end

if ~gui_Create
    % In design time, we need to mark all components possibly created in
    % the coming callback evaluation as non-serializable. This way, they
    % will not be brought into GUIDE and not be saved in the figure file
    % when running/saving the GUI from GUIDE.
    designEval = false;
    if (numargin>1 && ishghandle(varargin{2}))
        fig = varargin{2};
        while ~isempty(fig) && ~isa(handle(fig),'figure')
            fig = get(fig,'parent');
        end
        
        designEval = isappdata(0,'CreatingGUIDEFigure') || isprop(fig,'__GUIDEFigure');
    end
        
    if designEval
        beforeChildren = findall(fig);
    end
    
    % evaluate the callback now
    varargin{1} = gui_State.gui_Callback;
    if nargout
        [varargout{1:nargout}] = feval(varargin{:});
    else       
        feval(varargin{:});
    end
    
    % Set serializable of objects created in the above callback to off in
    % design time. Need to check whether figure handle is still valid in
    % case the figure is deleted during the callback dispatching.
    if designEval && ishandle(fig)
        set(setdiff(findall(fig),beforeChildren), 'Serializable','off');
    end
else
    if gui_State.gui_Singleton
        gui_SingletonOpt = 'reuse';
    else
        gui_SingletonOpt = 'new';
    end

    % Check user passing 'visible' P/V pair first so that its value can be
    % used by oepnfig to prevent flickering
    gui_Visible = 'auto';
    gui_VisibleInput = '';
    for index=1:2:length(varargin)
        if length(varargin) == index || ~ischar(varargin{index})
            break;
        end

        % Recognize 'visible' P/V pair
        len1 = min(length('visible'),length(varargin{index}));
        len2 = min(length('off'),length(varargin{index+1}));
        if ischar(varargin{index+1}) && strncmpi(varargin{index},'visible',len1) && len2 > 1
            if strncmpi(varargin{index+1},'off',len2)
                gui_Visible = 'invisible';
                gui_VisibleInput = 'off';
            elseif strncmpi(varargin{index+1},'on',len2)
                gui_Visible = 'visible';
                gui_VisibleInput = 'on';
            end
        end
    end
    
    % Open fig file with stored settings.  Note: This executes all component
    % specific CreateFunctions with an empty HANDLES structure.

    
    % Do feval on layout code in m-file if it exists
    gui_Exported = ~isempty(gui_State.gui_LayoutFcn);
    % this application data is used to indicate the running mode of a GUIDE
    % GUI to distinguish it from the design mode of the GUI in GUIDE. it is
    % only used by actxproxy at this time.   
    setappdata(0,genvarname(['OpenGuiWhenRunning_', gui_State.gui_Name]),1);
    if gui_Exported
        gui_hFigure = feval(gui_State.gui_LayoutFcn, gui_SingletonOpt);

        % make figure invisible here so that the visibility of figure is
        % consistent in OpeningFcn in the exported GUI case
        if isempty(gui_VisibleInput)
            gui_VisibleInput = get(gui_hFigure,'Visible');
        end
        set(gui_hFigure,'Visible','off')

        % openfig (called by local_openfig below) does this for guis without
        % the LayoutFcn. Be sure to do it here so guis show up on screen.
        movegui(gui_hFigure,'onscreen');
    else
        gui_hFigure = local_openfig(gui_State.gui_Name, gui_SingletonOpt, gui_Visible);
        % If the figure has InGUIInitialization it was not completely created
        % on the last pass.  Delete this handle and try again.
        if isappdata(gui_hFigure, 'InGUIInitialization')
            delete(gui_hFigure);
            gui_hFigure = local_openfig(gui_State.gui_Name, gui_SingletonOpt, gui_Visible);
        end
    end
    if isappdata(0, genvarname(['OpenGuiWhenRunning_', gui_State.gui_Name]))
        rmappdata(0,genvarname(['OpenGuiWhenRunning_', gui_State.gui_Name]));
    end

    % Set flag to indicate starting GUI initialization
    setappdata(gui_hFigure,'InGUIInitialization',1);

    % Fetch GUIDE Application options
    gui_Options = getappdata(gui_hFigure,'GUIDEOptions');
    % Singleton setting in the GUI M-file takes priority if different
    gui_Options.singleton = gui_State.gui_Singleton;

    if ~isappdata(gui_hFigure,'GUIOnScreen')
        % Adjust background color
        if gui_Options.syscolorfig
            set(gui_hFigure,'Color', get(0,'DefaultUicontrolBackgroundColor'));
        end

        % Generate HANDLES structure and store with GUIDATA. If there is
        % user set GUI data already, keep that also.
        data = guidata(gui_hFigure);
        handles = guihandles(gui_hFigure);
        if ~isempty(handles)
            if isempty(data)
                data = handles;
            else
                names = fieldnames(handles);
                for k=1:length(names)
                    data.(char(names(k)))=handles.(char(names(k)));
                end
            end
        end
        guidata(gui_hFigure, data);
    end

    % Apply input P/V pairs other than 'visible'
    for index=1:2:length(varargin)
        if length(varargin) == index || ~ischar(varargin{index})
            break;
        end

        len1 = min(length('visible'),length(varargin{index}));
        if ~strncmpi(varargin{index},'visible',len1)
            try set(gui_hFigure, varargin{index}, varargin{index+1}), catch break, end
        end
    end

    % If handle visibility is set to 'callback', turn it on until finished
    % with OpeningFcn
    gui_HandleVisibility = get(gui_hFigure,'HandleVisibility');
    if strcmp(gui_HandleVisibility, 'callback')
        set(gui_hFigure,'HandleVisibility', 'on');
    end

    feval(gui_State.gui_OpeningFcn, gui_hFigure, [], guidata(gui_hFigure), varargin{:});

    if isscalar(gui_hFigure) && ishandle(gui_hFigure)
        % Handle the default callbacks of predefined toolbar tools in this
        % GUI, if any
%         guidemfile('restoreToolbarToolPredefinedCallback',gui_hFigure); 
        
        % Update handle visibility
        set(gui_hFigure,'HandleVisibility', gui_HandleVisibility);

        % Call openfig again to pick up the saved visibility or apply the
        % one passed in from the P/V pairs
        if ~gui_Exported
            gui_hFigure = local_openfig(gui_State.gui_Name, 'reuse',gui_Visible);
        elseif ~isempty(gui_VisibleInput)
            set(gui_hFigure,'Visible',gui_VisibleInput);
        end
        if strcmpi(get(gui_hFigure, 'Visible'), 'on')
            figure(gui_hFigure);
            
            if gui_Options.singleton
                setappdata(gui_hFigure,'GUIOnScreen', 1);
            end
        end

        % Done with GUI initialization
        if isappdata(gui_hFigure,'InGUIInitialization')
            rmappdata(gui_hFigure,'InGUIInitialization');
        end

        % If handle visibility is set to 'callback', turn it on until
        % finished with OutputFcn
        gui_HandleVisibility = get(gui_hFigure,'HandleVisibility');
        if strcmp(gui_HandleVisibility, 'callback')
            set(gui_hFigure,'HandleVisibility', 'on');
        end
        gui_Handles = guidata(gui_hFigure);
    else
        gui_Handles = [];
    end

    if nargout
        [varargout{1:nargout}] = feval(gui_State.gui_OutputFcn, gui_hFigure, [], gui_Handles);
    else
        feval(gui_State.gui_OutputFcn, gui_hFigure, [], gui_Handles);
    end

    if isscalar(gui_hFigure) && ishandle(gui_hFigure)
        set(gui_hFigure,'HandleVisibility', gui_HandleVisibility);
    end
end

function gui_hFigure = local_openfig(name, singleton, visible)

% openfig with three arguments was new from R13. Try to call that first, if
% failed, try the old openfig.
if nargin('openfig') == 2
    % OPENFIG did not accept 3rd input argument until R13,
    % toggle default figure visible to prevent the figure
    % from showing up too soon.
    gui_OldDefaultVisible = get(0,'defaultFigureVisible');
    set(0,'defaultFigureVisible','off');
    gui_hFigure = openfig(name, singleton);
    set(0,'defaultFigureVisible',gui_OldDefaultVisible);
else
    gui_hFigure = openfig(name, singleton, visible);
end

function result = local_isInvokeActiveXCallback(gui_State, varargin)

try
    result = ispc && iscom(varargin{1}) ...
             && isequal(varargin{1},gcbo);
catch
    result = false;
end

function result = local_isInvokeHGCallbak(gui_State, varargin)

try
    fhandle = functions(gui_State.gui_Callback);
    result = ~isempty(findstr(gui_State.gui_Name,fhandle.file)) || ...
             (ischar(varargin{1}) ...
             && isequal(ishandle(varargin{2}), 1) ...
             && ~isempty(strfind(varargin{1},[get(varargin{2}, 'Tag'), '_'])));
catch
    result = false;
end

function wav = tts(txt,voice,pace,fs)
%TTS text to speech.
% See original written by Siyi Deng; 12-21-2007;
% updated by Gus 2008

if ~ispc, 
  warning('tts:notpc','Microsoft Win32 SAPI is required.'); 
  wav = [];
  return; 
end

SV = actxserver('SAPI.SpVoice');
TK = invoke(SV,'GetVoices');

% Select voice;
for k = 0:TK.Count-1
    if strcmpi(voice,TK.Item(k).GetDescription)
        SV.Voice = TK.Item(k);
        break;
    end
end
% Set pace;
if isempty(pace), pace = 0; end
if abs(pace) > 10, pace = sign(pace)*10; end        
SV.Rate = pace;

% Output variable;
MS = actxserver('SAPI.SpMemoryStream');
MS.Format.Type = sprintf('SAFT%dkHz16BitMono',fix(fs/1000));
SV.AudioOutputStream = MS;  

invoke(SV,'Speak',txt);

% Convert uint8 to double precision;
wav = reshape(double(invoke(MS,'GetData')),2,[])';
wav = (wav(:,2)*256+wav(:,1))/32768;
wav(wav >= 1) = wav(wav >= 1)-2;
delete(MS);
clear MS;

delete(SV); 
clear SV TK;


Contact us at files@mathworks.com