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;