📄 sudokon.m
字号:
% yet selected.
if hc(85,4)>1 % if this is the second request for hints, finish all
% selections.
kk = find(~hc(1:81,4)); dd = kk; hc(kk,4) = 1; lkk = numel(kk);
for j=1:lkk
dd(j) = find(p(kk(j),:));
set(hc(kk(j),1),'Visible','on','Fontsize',30,'Fontweight','bold',...
'String',dd(j))
end
hst = [hst; ones(lkk,1),kk,dd];
set(hc(85,1),'Visible','on', 'String','Congratulations!')
else
hc(85,4) = 0; update(hc,p), hc(85,4) = 2;
set(hc(85,1),'Visible','on', 'String',get(hc(84,2),'Userdata'))
end
else
if hc(85,4)<0
hc(85,4) = 0; update(hc,p)
set(hc(85,1),'Visible','on','String',get(hc(84,2),'Userdata'))
if isequal(get(p(82,1),'Visible'),'on')
set([p(82,:), hc(82,4)],'Visible','off');
end
else
strings = get(hc(85,1),'String');
if iscell(strings), strings = strings{1}; end
if (strings(1)=='E'||strings(1)=='N')
update(hc,p)
set(hc(~hc(1:81,4),1),'String',''), hc(85,4) = -1;
set(hc(85,1),'Visible','on','String',get(hc(83,3),'Userdata'))
else
hc(85,2) = 0;
if isequal(get(gcf,'SelectionType'),'alt')
hc(85,2) = 1;
end
switch checkit(dg,p,gr,hc,action)
case 0
messge = get(hc(85,1),'Userdata');
case 2
messge = {'Every circle indicates';'a removable choice'};
case 1
messge = 'Every star indicates a correct choice';
case -1
messge = 'No obvious correct choices';
end
set(hc(85,1),'String',messge,'Visible','on')
end
end
end
case 'prints'
button = questdlg('Where should the board be sent to?','Send to ...',...
'Printer','File','Command Window','Printer');
if isempty(button), button = 'N'; end
switch button(1)
case {'P','F'}
set(hc(83,4),'Visible','on')
set([reshape(hc(83:84,1:3),1,6),hc(85,1)],'Visible','off')
if button(1)=='F'
curbd = get(hc(84,1),'Userdata');
[pn,mfname,coru] = getfilename('.eps',curbd);
if ~isempty(mfname)
eval(['print -deps ',pn,mfname,'.eps'])
set(hc(84,1),'Userdata',curbd+1);
fprintf(['sudokon ',coru,'ated the eps-file ',mfname,...
' in the directory ',strrep(pn(1:end-1),'\','\\'),'\n']);
end
else
print
end
set(hc(83,4),'Visible','off')
set([reshape(hc(83:84,1:3),1,6),hc(85,1)],'Visible','on')
case 'C'
border = ' +-------+-------+-------+';
tline = repmat(' | . . . | . . . | . . . |',3,1);
printg = [border;repmat([tline;border],3,1)]; dotsp = find(printg=='.');
numbers = find(dg); strdg = num2str(dg); dotsd = find(strdg~=' ');
printg(dotsp(numbers)) = strdg(dotsd(numbers));
disp(printg)
end
case 'save' % saves the current history in the current directory
% for later recall via the command load
curbd = get(hc(84,1),'Userdata');
[pn,mfname,coru] = getfilename('.mat',curbd);
if isempty(mfname), return, end
save([pn mfname],'hst')
set(hc(84,1),'Userdata',curbd+1);
fprintf(['sudokon ',coru,'ated the MAT-file ',mfname,...
' in the directory ',strrep(pn(1:end-1),'\','\\'),'\n']);
case 'load' % restores the board to the end of the history brought
% back from
% get a file name
curbd = get(hc(84,1),'Userdata'); % used in serializing exported data
mfname = ['board',num2str(curbd),'.mat']; curdir = pwd;
if ~(curdir(end)==filesep), curdir = [curdir filesep]; end
getfiletitle = 'Which saved board would you like to load?';
[mfname,pn] = uigetfile([curdir mfname], getfiletitle);
if isequal(mfname,0)||isequal(pn,0)
% the user hit Cancel, so give up on this
return
end
load([pn mfname])
% check out that this is actually a workable history
accepted = 0;
q = unique(hst(:,3));
q(q==0|q==1|q==2|q==3|q==4|q==5|q==6|q==7|q==8|q==9)=[];
if isempty(q)
q = unique(hst(:,1));
q(q==0|q==1|q==2)=[];
if isempty(q)
q = unique(hst(:,2));
if ~any(q-fix(q))&&q(1)>0&&q(end)<82
accepted = 1;
[dg,p,hc] = bringback(hst,p,gr,hc);
mfname(end-3:end) = [];
set(hc(85,1),'Visible','on','String',['back to ',mfname])
end
end
end
if ~accepted
set(hc(85,1),'Visible','on','String',['the file ''',...
mfname,''' does not appear to be generated by sudokon.'])
end
case 'prefer' % makes choices for what exactly check? does
% Userdata action
% 1 check correctness
% 2 check correctness and print detail
% 3 check number of solutions
% 4 print all solutions (if any)
temp = get(hc(84,3),'Userdata') + 1; if temp>4, temp = 1; end
hc(85,3) = 0;
switch temp
case 1
set(hc(83,3),'Tooltipstring','checks consistency of choices made so far')
set(hc(84,3),'String','...choices made')
case 2
set(hc(84,3),'String','...choices; print')
set(hc(83,3),'Tooltipstring', ...
'checks consistency of choices made so far and prints details')
hc(85,3) = 1;
case 3
set(hc(84,3),'String','...# solutions')
set(hc(83,3),'Tooltipstring','checks number of solutions')
case 4
set(hc(84,3),'String','...all solutions')
set(hc(83,3),'Tooltipstring','prints out all solutions (if any)')
end
set(hc(84,3),'Userdata',temp)
case 'works' % act on the selected cell
answer = get(gcf,{'CurrentPoint','SelectionType'});
k = get(gco,'Userdata');
if hc(k,4) % the cell has been settled, so, show the undo button
setdonot(hc(82,4),hc(k,2:3))
set(hc(82,3),'Position',[hc(k,2:3)-w/2,w(1),w(2)/3],...
'Visible','on','Userdata',k)
set(hc(85,1),'visible','off')
else
switch hc(85,4)
% hc(85,4) gives the 5 modes: clueless (-1), some help (0),
% no help but only singletons (1), help with singletons (2), done (3).
case {0,2} % some help, hence this is a click on digit or else undo wish
set(hc(85,1),'String',get(hc(84,2),'Userdata'))
d = find(p(k,:));
if length(d)==1
% we are in the help mode and are looking at a singleton cell
% that has not yet been settled.
if isequal(answer{2},'normal')
hst(end+1,:) = [1,k,d];
set(hc(82,3:4),'Visible','off')
[dg,p,hc] = rm(k,d,dg,p,gr,hc);
else % anything other than a left click brings up the undo button
setdonot(hc(82,4),hc(k,2:3))
set(hc(82,3),'Visible','on',...
'Position',[hc(k,2:3)-w/2,w(1),w(2)/3],'Userdata',k)
set(hc(85,1),'Visible','off')
end
else
% check which digit was clicked
dc = ...
find(histc(answer{1}(1), [-inf, hc(k,2)+[-w(1)/6,w(2)/6], inf]))+...
3*(3-...
find(histc(answer{1}(2), [-inf, hc(k,3)+[-w(1)/6,w(2)/6], inf])));
% ... and act accordingly
if p(k,dc) % the digit is one of the possible choices
switch answer{2} % which should be 'normal' or 'alt'
case 'normal' % a left click, hence select this digit
hst(end+1,:) = [1,k,dc];
[dg,p,hc] = rm(k,dc,dg,p,gr,hc);
case 'alt' % a right click, hence delete this digit
p(k,dc) = 0; hst(end+1,:) = [2,k,dc];
text = get(hc(k,1),'string');
temp = [1 7 13 2 8 14 3 9 15]; text(temp(dc))=' ';
set(hc(k,1),'string',text,...
'Fontweight','normal','Foregroundcolor','k')
otherwise % put up the undo button
setdonot(hc(82,4),hc(k,2:3))
set(hc(82,3),'Visible','on',...
'Position',[hc(k,2:3)-w/2,w(1),w(2)/3],'Userdata',k)
set(hc(85,1),'Visible','off')
end
else % an empty space was clicked, hence put up undo button
setdonot(hc(82,4),hc(k,2:3))
set(hc(82,3),'Visible','on','Position',...
[hc(k,2:3)-w/2,w(1),w(2)/3],'Userdata',k)
set(hc(85,1),'Visible','off')
end
end
case {-1,1} % no help, hence show the keyboard
setdonot(hc(82,4),hc(k,2:3))
keyboard(k,hc,p,w);
set(hc(85,1),'String','click digit to select','Visible','on')
set(p(82,:),'Tooltipstring','click to select',...
'Callback','sudokon ''finis''');
otherwise
error('something wrong in sudokon')
end
end
case 'finis' % make the selected digit the choice for this cell
stored = get(gco,'Userdata');
k = stored(1); d = stored(2);
if ~p(k,d) % we are in the clueless state
% but will refuse any inconsistent choice
set(hc(85,1),'Visible','on', ...
'String',['your choice of ',num2str(d),' is inconsistent'])
else
set([p(82,:),hc(82,3:4)],'Visible','off')
hst(end+1,:) = [1,k,d];
[dg,p,hc] = rm(k,d,dg,p,gr,hc);
set(hc(85,1),'String',get(hc(83,3),'Userdata'))
end
case 'undo' % return to the stage before the last change made to this cell
set(hc(82,3:4),'Visible','off')
k = get(gco,'Userdata');
last = find(hst(:,2)==k,1,'last');
if ~hst(last,1) % this is one of the original givens, hence merely start
% from scratch
last = find(hst(:,1),1);
end
hst(last:end,:) = [];
[dg,p,hc] = bringback(hst,p,gr,hc);
case 'donot' % do nothing
set([p(82,:),hc(82,3:4)],'Visible','off')
set(hc(85,1),'Visible','on')
case 'closefigure'
delete(findobj('Tag','sudokon Message Box'))
return
end
if hc(85,4)<3&&all(hc(1:81,4)) % we just finished
hc(85,4) = 3;
set(hc(85,1),'Visible','on', 'String','Congratulations!')
for j=1:6
set(hc(85,1),'Visible','off'), pause(.1)
set(hc(85,1),'Visible','on'), pause(.1)
end
end
set(hf,'Userdata',{hf,p,dg,gr,hc,hst})
function [ok,dg,p] = checkit(dg,p,gr,hc,action)
%CHECKIT check for inconsistencies and/or new singletons
switch action(1)
case 'h'
ok = -1; ntries = 3; nrep = 4; pstart = p;
case {'c','a'}
ntries = numel(find(dg==0)); nrep = 1; hc(85,2) = 0;
% made sure that an earlier right click on hints doesn't generate
% detailed printout now
end
if hc(85,3)
if action(1)=='h', fprintf('\n detailed hints\n')
else counts = zeros(1,6);
fprintf(['\n',action,'\n rcb, bc, br, two, three ',...
'count occurrences of the following:\n rare digit ',...
'removed from box(rcb), column(bc), row(br);\n all other choices removed',...
' from only pair(two)/triple(three)\n',...
' that can contain a certain pair/triple of digits.\n']);
end
end
for tries=1:ntries
for rep=1:nrep
for r=1:27
tt = sum(p(gr(:,r),:));
if ~all(tt), ok = 0; return, end %inconcistency: some digit is excluded
sd = find(tt==1); %These are the digits that occur exactly once in this
% group, hence the corresponding k should be a singleton.
for d = sd
k = gr(p(gr(:,r),d)==1,r);
if ~dg(k) % this should be a singleton
if hc(85,3)&&action(1)=='h'
dd = 1:9; dd(d) = [];
if any(p(k,dd))||r<10
fprintf(' ** select cell %g|%g for digit %g\n',cellid(k),d)
end
end
p(k,:) = 0;
% also remove this digit from all the other cells in the two
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -